From 9251b86c0c7854e85ddb964a9f6edf89e983d477 Mon Sep 17 00:00:00 2001 From: Yonggang Yu Date: Thu, 11 Jan 2024 14:18:03 -0700 Subject: [PATCH 1/6] Revised swath and trajecotry sampler to handle multiple missing files along with model runs --- CHANGELOG.md | 7 + Tests/ExtDataDriverGridComp.F90 | 16 +- base/MAPL_ObsUtil.F90 | 240 ++++++--- base/MAPL_SwathGridFactory.F90 | 436 ++++++++++------ base/Plain_netCDF_Time.F90 | 32 +- gridcomps/History/MAPL_EpochSwathMod.F90 | 266 +++++----- gridcomps/History/MAPL_HistoryGridComp.F90 | 199 ++++--- .../History/MAPL_HistoryTrajectoryMod.F90 | 17 +- .../MAPL_HistoryTrajectoryMod_smod.F90 | 494 +++++++++++------- 9 files changed, 1092 insertions(+), 615 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c50ea8f9ef5f..7f512a9e0edf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added +- Modify trajectory sampler for a collection with multiple platforms: P3B (air craft) + FIREX +- Modify swath sampler to handle two Epoch swath grids +- Handle regrid accumulate for time step (1 sec) during which no obs exists +- Use IntState%stampoffset(n) to adjust filenames for an epoch time +- parse "GOCART::CO2" from 'geovals_fields' entry in PLATFORM +- Add Shmem to ExtDataDriverGridComp.F90 +- Read swath data on root, pass to NodeRoot for Shmem, so to avoid race in reading nc files - Added memory utility, MAPL_MemReport that can be used in any code linking MAPL diff --git a/Tests/ExtDataDriverGridComp.F90 b/Tests/ExtDataDriverGridComp.F90 index 0873a68c4c11..c303f61be6e1 100644 --- a/Tests/ExtDataDriverGridComp.F90 +++ b/Tests/ExtDataDriverGridComp.F90 @@ -11,7 +11,7 @@ module ExtData_DriverGridCompMod use MAPL_HistoryGridCompMod, only : Hist_SetServices => SetServices use MAPL_Profiler, only : get_global_time_profiler, BaseProfiler use mpi - +! use MAPL_ShmemMod implicit none private @@ -145,6 +145,9 @@ subroutine initialize_gc(gc, import_state, export_state, clock, rc) class(BaseProfiler), pointer :: t_p logical :: use_extdata2g + integer :: useShmem + + _UNUSED_DUMMY(import_state) _UNUSED_DUMMY(export_state) _UNUSED_DUMMY(clock) @@ -168,6 +171,7 @@ subroutine initialize_gc(gc, import_state, export_state, clock, rc) cap%AmIRoot = AmIRoot_ + ! Open the CAP's configuration from CAP.rc !------------------------------------------ @@ -176,6 +180,7 @@ subroutine initialize_gc(gc, import_state, export_state, clock, rc) call ESMF_ConfigLoadFile(cap%config, cap%configFile, rc = status) _VERIFY(status) + ! CAP's MAPL MetaComp !--------------------- @@ -185,6 +190,13 @@ subroutine initialize_gc(gc, import_state, export_state, clock, rc) call MAPL_Set(MAPLOBJ, name = cap%name, cf = cap%config, rc = status) _VERIFY(status) + call MAPL_GetResource(MAPLOBJ, useShmem, label = 'USE_SHMEM:', default = 0, rc = status) + if (useShmem /= 0) then + call MAPL_InitializeShmem (rc = status) + _VERIFY(status) + end if + + call ESMF_ConfigGetAttribute(cap%config,cap%run_fbf,label="RUN_FBF:",default=.false.) call ESMF_ConfigGetAttribute(cap%config,cap%run_hist,label="RUN_HISTORY:",default=.true.) call ESMF_ConfigGetAttribute(cap%config,cap%run_extdata,label="RUN_EXTDATA:",default=.true.) @@ -484,6 +496,8 @@ subroutine finalize_gc(gc, import_state, export_state, clock, rc) call ESMF_ConfigDestroy(cap%config, rc = status) _VERIFY(status) + call MAPL_FinalizeSHMEM (rc = status) + _VERIFY(status) _RETURN(ESMF_SUCCESS) end subroutine finalize_gc diff --git a/base/MAPL_ObsUtil.F90 b/base/MAPL_ObsUtil.F90 index d4ed2f8de5ab..8901c159f6c7 100644 --- a/base/MAPL_ObsUtil.F90 +++ b/base/MAPL_ObsUtil.F90 @@ -33,10 +33,10 @@ module MAPL_ObsUtilMod type obs_platform character (len=ESMF_MAXSTR) :: name='' - character (len=ESMF_MAXSTR) :: nc_index='' - character (len=ESMF_MAXSTR) :: nc_lon='' - character (len=ESMF_MAXSTR) :: nc_lat='' - character (len=ESMF_MAXSTR) :: nc_time='' + character (len=ESMF_MAXSTR) :: index_name_x='' + character (len=ESMF_MAXSTR) :: var_name_lon='' + character (len=ESMF_MAXSTR) :: var_name_lat='' + character (len=ESMF_MAXSTR) :: var_name_time='' character (len=ESMF_MAXSTR) :: file_name_template='' integer :: ngeoval=0 integer :: nentry_name=0 @@ -62,7 +62,7 @@ subroutine get_obsfile_Tbracket_from_epoch(currTime, & integer, intent(out) :: obsfile_Te_index integer, optional, intent(out) :: rc - type(ESMF_Time) :: T1, Tn + type(ESMF_Time) :: T1 type(ESMF_Time) :: cT1 type(ESMF_Time) :: Ts, Te type(ESMF_TimeInterval) :: dT1, dT2, dTs, dTe @@ -71,8 +71,14 @@ subroutine get_obsfile_Tbracket_from_epoch(currTime, & integer :: n1, n2 integer :: status + ! + ! o---------o ------------- o -------------o + ! obsfile_interval + ! x---------------------x-- + ! Epoch + ! + T1 = obsfile_start_time - Tn = obsfile_end_time cT1 = currTime dT1 = currTime - T1 @@ -91,11 +97,13 @@ subroutine get_obsfile_Tbracket_from_epoch(currTime, & Te = T1 + dTe obsfile_Ts_index = n1 - if ( dT2_s - n2*dT0_s < 1 ) then - obsfile_Te_index = n2 - 1 - else - obsfile_Te_index = n2 - end if + obsfile_Te_index = n2 + +! if ( dT2_s - n2*dT0_s < 1 ) then +! obsfile_Te_index = n2 - 1 +! else +! obsfile_Te_index = n2 +! end if _RETURN(ESMF_SUCCESS) @@ -177,7 +185,7 @@ end subroutine reset_times_to_current_day ! --//-------------------------------------//-> ! files ! o o o o o o o o o o T: filename - ! <--- off set + ! <--- off set ! o o o o o o o o o o T: file content start ! | | ! curr curr+Epoch @@ -210,6 +218,7 @@ subroutine Find_M_files_for_currTime (currTime, & integer :: n1, n2 integer :: i, j integer :: status + logical :: EX !__ s1. Arithmetic index list based on s,e,interval ! @@ -254,13 +263,13 @@ subroutine Find_M_files_for_currTime (currTime, & ! print*, '2nd n1, n2', n1, n2 !__ s2. further test file existence - ! + ! j=0 do i= n1, n2 test_file = get_filename_from_template_use_index & (obsfile_start_time, obsfile_interval, & - i, file_template, rc=rc) - if (test_file /= '') then + i, file_template, EX, rc=rc) + if (EX) then j=j+1 filenames(j) = test_file end if @@ -269,7 +278,6 @@ subroutine Find_M_files_for_currTime (currTime, & _ASSERT ( M < size(filenames) , 'code crash, number of files exceeds upper bound') _ASSERT (M/=0, 'M is zero, no files found for currTime') - _RETURN(_SUCCESS) @@ -278,8 +286,8 @@ end subroutine Find_M_files_for_currTime subroutine read_M_files_4_swath ( filenames, Xdim, Ydim, & index_name_lon, index_name_lat,& - var_name_lon, var_name_lat, var_name_time, & - lon, lat, time, rc ) + var_name_lon, var_name_lat, var_name_time, & + lon, lat, time, Tfilter, rc ) use pFlogger, only: logging, Logger character(len=ESMF_MAXSTR), intent(in) :: filenames(:) integer, intent(out) :: Xdim @@ -288,17 +296,18 @@ subroutine read_M_files_4_swath ( filenames, Xdim, Ydim, & character(len=ESMF_MAXSTR), intent(in) :: index_name_lat character(len=ESMF_MAXSTR), optional, intent(in) :: var_name_lon character(len=ESMF_MAXSTR), optional, intent(in) :: var_name_lat - character(len=ESMF_MAXSTR), optional, intent(in) :: var_name_time + character(len=ESMF_MAXSTR), optional, intent(in) :: var_name_time - real, optional, intent(inout) :: lon(:,:) - real, optional, intent(inout) :: lat(:,:) + real, allocatable, optional, intent(inout) :: lon(:,:) + real, allocatable, optional, intent(inout) :: lat(:,:) !! real(ESMF_KIND_R8), optional, intent(inout) :: time_R8(:,:) - real, optional, intent(inout) :: time(:,:) + real, allocatable, optional, intent(inout) :: time(:,:) + logical, optional, intent(in) :: Tfilter integer, optional, intent(out) :: rc integer :: M - integer :: i, j, jx, status + integer :: i, j, jx, j2, status integer :: nlon, nlat integer :: ncid, ncid2 character(len=ESMF_MAXSTR) :: grp1, grp2 @@ -316,7 +325,7 @@ subroutine read_M_files_4_swath ( filenames, Xdim, Ydim, & M = size(filenames) _ASSERT(M/=0, 'M is zero, no files found') lgr => logging%get_logger('MAPL.Sampler') - + allocate(nlons(M), nlats(M)) jx=0 do i = 1, M @@ -326,45 +335,139 @@ subroutine read_M_files_4_swath ( filenames, Xdim, Ydim, & nlons(i)=nlon nlats(i)=nlat jx=jx+nlat - + call lgr%debug('Input filename: %a', trim(filename)) call lgr%debug('Input file : nlon, nlat= %i6 %i6', nlon, nlat) end do + ! + ! __ output results wo filter + ! Xdim=nlon Ydim=jx - + j2=jx !__ s2. get fields - jx=0 - do i = 1, M - filename = filenames(i) - nlon = nlons(i) - nlat = nlats(i) - if (present(var_name_time).AND.present(time)) then + if ( present(Tfilter) .AND. Tfilter ) then + if ( .not. (present(time) .AND. present(lon) .AND. present(lat)) ) then + _FAIL('when Tfilter present, time/lon/lat must also present') + end if + + ! + ! -- determine jx + ! + jx=0 + do i = 1, M + filename = filenames(i) + nlon = nlons(i) + nlat = nlats(i) allocate (time_loc_R8(nlon, nlat)) call get_var_from_name_w_group (var_name_time, time_loc_R8, filename, _RC) - time(1:nlon,jx+1:jx+nlat) = time_loc_R8(1:nlon,1:nlat) +!! write(6,*) 'af ith, filename', i, trim(filename) + + do j=1, nlat + ! + ! -- filter, e.g., eliminate -9999 + ! + if ( time_loc_R8(1, j) > 0.0 ) then + jx = jx + 1 + end if + end do deallocate(time_loc_R8) + end do + Xdim=nlon + Ydim=jx + if (allocated (time)) then + deallocate(time) + allocate (time(Xdim, Ydim)) end if - - if (present(var_name_lon).AND.present(lon)) then + if (allocated (lon)) then + deallocate(lon) + allocate (lon(Xdim, Ydim)) + end if + if (allocated (lat)) then + deallocate(lat) + allocate (lat(Xdim, Ydim)) + end if + ! + !!write(6,'(2x,a,10i10)') 'true Xdim, Ydim:', Xdim, Ydim + !!write(6,'(2x,a,10i10)') 'false Xdim, Ydim:', nlon, j2 + ! + + + + ! + ! -- determine true time/lon/lat by filtering T < 0 + ! + jx=0 + do i = 1, M + filename = filenames(i) + nlon = nlons(i) + nlat = nlats(i) + !!write(6,'(2x,a,10i6)') 'M, i, nlon, nlat:', M, i, nlon, nlat + !!write(6,'(2x,a)') 'time_loc_r8' + ! + allocate (time_loc_R8(nlon, nlat)) + call get_var_from_name_w_group (var_name_time, time_loc_R8, filename, _RC) allocate (lon_loc(nlon, nlat)) call get_var_from_name_w_group (var_name_lon, lon_loc, filename, _RC) - lon(1:nlon,jx+1:jx+nlat) = lon_loc(1:nlon,1:nlat) - deallocate(lon_loc) - end if - - if (present(var_name_lat).AND.present(lat)) then allocate (lat_loc(nlon, nlat)) call get_var_from_name_w_group (var_name_lat, lat_loc, filename, _RC) - lat(1:nlon,jx+1:jx+nlat) = lat_loc(1:nlon,1:nlat) + ! + do j=1, nlat + ! + ! -- filter, e.g., eliminate -9999 + ! + if ( time_loc_R8(1, j) > 0.0 ) then + jx = jx + 1 + time(1:nlon,jx) = time_loc_R8(1:nlon,j) + lon (1:nlon,jx) = lon_loc (1:nlon,j) + lat (1:nlon,jx) = lat_loc (1:nlon,j) + end if + !!write(6,'(5f20.2)') time_loc_R8(1,j) + end do + + !!write(6,'(2x,a,10i10)') 'end of file id', i + !!write(6,*) + + deallocate(time_loc_R8) + deallocate(lon_loc) deallocate(lat_loc) - end if + end do - jx = jx + nlat + else - end do + jx=0 + do i = 1, M + filename = filenames(i) + nlon = nlons(i) + nlat = nlats(i) + + if (present(var_name_time).AND.present(time)) then + allocate (time_loc_R8(nlon, nlat)) + call get_var_from_name_w_group (var_name_time, time_loc_R8, filename, _RC) + time(1:nlon,jx+1:jx+nlat) = time_loc_R8(1:nlon,1:nlat) + deallocate(time_loc_R8) + end if + + if (present(var_name_lon).AND.present(lon)) then + allocate (lon_loc(nlon, nlat)) + call get_var_from_name_w_group (var_name_lon, lon_loc, filename, _RC) + lon(1:nlon,jx+1:jx+nlat) = lon_loc(1:nlon,1:nlat) + deallocate(lon_loc) + end if + + if (present(var_name_lat).AND.present(lat)) then + allocate (lat_loc(nlon, nlat)) + call get_var_from_name_w_group (var_name_lat, lat_loc, filename, _RC) + lat(1:nlon,jx+1:jx+nlat) = lat_loc(1:nlon,1:nlat) + deallocate(lat_loc) + end if + + jx = jx + nlat + end do + + end if _RETURN(_SUCCESS) end subroutine read_M_files_4_swath @@ -375,14 +478,15 @@ end subroutine read_M_files_4_swath ! because of (bash ls) command therein ! function get_filename_from_template_use_index (obsfile_start_time, obsfile_interval, & - f_index, file_template, rc) result(filename) + f_index, file_template, EX, rc) result(filename) use Plain_netCDF_Time, only : ESMF_time_to_two_integer - use MAPL_StringTemplate, only : fill_grads_template + use MAPL_StringTemplate, only : fill_grads_template character(len=ESMF_MAXSTR) :: filename type(ESMF_Time), intent(in) :: obsfile_start_time type(ESMF_TimeInterval), intent(in) :: obsfile_interval character(len=*), intent(in) :: file_template integer, intent(in) :: f_index + logical, intent(out) :: EX integer, optional, intent(out) :: rc integer :: itime(2) @@ -393,7 +497,6 @@ function get_filename_from_template_use_index (obsfile_start_time, obsfile_inter type(ESMF_TimeInterval) :: dT type(ESMF_Time) :: time integer :: i, j, u - logical :: EX character(len=ESMF_MAXSTR) :: file_template_left character(len=ESMF_MAXSTR) :: file_template_right @@ -416,7 +519,6 @@ function get_filename_from_template_use_index (obsfile_start_time, obsfile_inter call fill_grads_template ( filename, file_template, & experiment_id='', nymd=nymd, nhms=nhms, _RC ) inquire(file= trim(filename), EXIST = EX) - if(.not.EX) filename='' _RETURN(_SUCCESS) @@ -431,8 +533,8 @@ subroutine get_var_from_name_w_group (var_name, var2d, filename, rc) integer :: i, j character(len=ESMF_MAXSTR) :: grp1, grp2 - character(len=ESMF_MAXSTR) :: short_name - integer :: ncid, ncid2, varid + character(len=ESMF_MAXSTR) :: short_name + integer :: ncid, ncid1, ncid2, ncid_final, varid logical :: found_group integer :: status @@ -447,7 +549,7 @@ subroutine get_var_from_name_w_group (var_name, var2d, filename, rc) short_name=var_name(i+j+1:) else grp2='' - short_name=var_name(i+1:) + short_name=var_name(i+1:) endif i=i+j else @@ -457,20 +559,29 @@ subroutine get_var_from_name_w_group (var_name, var2d, filename, rc) short_name=var_name endif - call check_nc_status(nf90_open(filename, NF90_NOWRITE, ncid2), _RC) + + ! ncid + ! ncid1: grp1 + ! ncid2: grp2 + ! + call check_nc_status(nf90_open(filename, NF90_NOWRITE, ncid), _RC) + ncid_final = ncid if ( found_group ) then - call check_nc_status(nf90_inq_ncid(ncid2, grp1, ncid), _RC) + call check_nc_status(nf90_inq_ncid(ncid, grp1, ncid1), _RC) + ncid_final = ncid1 if (j>0) then - call check_nc_status(nf90_inq_ncid(ncid, grp2, ncid2), _RC) - ncid=ncid2 + call check_nc_status(nf90_inq_ncid(ncid1, grp2, ncid2), _RC) + ncid_final = ncid2 endif else - print*, 'no grp name' - ncid=ncid2 +!! print*, 'no grp name' endif - call check_nc_status(nf90_inq_varid(ncid, short_name, varid), _RC) - call check_nc_status(nf90_get_var(ncid, varid, var2d), _RC) -!! call check_nc_status(nf90_close(ncid), _RC) + + call check_nc_status(nf90_inq_varid(ncid_final, short_name, varid), _RC) +!! write(6,*) 'ncid, short_name, varid', ncid, trim(short_name), varid + call check_nc_status(nf90_get_var(ncid_final, varid, var2d), _RC) + + call check_nc_status(nf90_close(ncid), _RC) _RETURN(_SUCCESS) @@ -557,16 +668,15 @@ subroutine sort_four_arrays_by_time(U,V,T,ID,rc) end subroutine sort_four_arrays_by_time - function copy_platform_nckeys(a, rc) type(obs_platform) :: copy_platform_nckeys type(obs_platform), intent(in) :: a integer, optional, intent(out) :: rc - copy_platform_nckeys%nc_index = a%nc_index - copy_platform_nckeys%nc_lon = a%nc_lon - copy_platform_nckeys%nc_lat = a%nc_lat - copy_platform_nckeys%nc_time = a%nc_time + copy_platform_nckeys%index_name_x = a%index_name_x + copy_platform_nckeys%var_name_lon = a%var_name_lon + copy_platform_nckeys%var_name_lat = a%var_name_lat + copy_platform_nckeys%var_name_time = a%var_name_time copy_platform_nckeys%nentry_name = a%nentry_name _RETURN(_SUCCESS) diff --git a/base/MAPL_SwathGridFactory.F90 b/base/MAPL_SwathGridFactory.F90 index 591c9eb562cc..d92cd27fafb4 100644 --- a/base/MAPL_SwathGridFactory.F90 +++ b/base/MAPL_SwathGridFactory.F90 @@ -26,14 +26,14 @@ module MAPL_SwathGridFactoryMod private public :: SwathGridFactory - + type, extends(AbstractGridFactory) :: SwathGridFactory private character(len=:), allocatable :: grid_name - character(len=:), allocatable :: grid_file_name + character(len=:), allocatable :: grid_file_name character(len=ESMF_MAXSTR) :: filenames(mx_file) integer :: M_file - + integer :: cell_across_swath integer :: cell_along_swath integer :: im_world = MAPL_UNDEFINED_INTEGER @@ -47,7 +47,7 @@ module MAPL_SwathGridFactoryMod ! note: this var is not deallocated in swathfactory, use caution character(len=ESMF_MAXSTR) :: tunit character(len=ESMF_MAXSTR) :: index_name_lon - character(len=ESMF_MAXSTR) :: index_name_lat + character(len=ESMF_MAXSTR) :: index_name_lat character(len=ESMF_MAXSTR) :: var_name_lon character(len=ESMF_MAXSTR) :: var_name_lat character(len=ESMF_MAXSTR) :: var_name_time @@ -57,10 +57,10 @@ module MAPL_SwathGridFactoryMod type(ESMF_Time) :: obsfile_start_time ! user specify type(ESMF_Time) :: obsfile_end_time type(ESMF_TimeInterval) :: obsfile_interval - type(ESMF_TimeInterval) :: EPOCH_FREQUENCY + type(ESMF_TimeInterval) :: EPOCH_FREQUENCY integer :: obsfile_Ts_index ! for epoch integer :: obsfile_Te_index - logical :: is_valid + logical :: is_valid ! Domain decomposition: integer :: nx = MAPL_UNDEFINED_INTEGER @@ -130,7 +130,7 @@ function SwathGridFactory_from_parameters(unusable, grid_name, & integer, optional, intent(in) :: im_world integer, optional, intent(in) :: jm_world integer, optional, intent(in) :: lm - + ! decomposition: integer, optional, intent(in) :: nx integer, optional, intent(in) :: ny @@ -142,7 +142,7 @@ function SwathGridFactory_from_parameters(unusable, grid_name, & integer :: status _UNUSED_DUMMY(unusable) - + call set_with_default(factory%grid_name, grid_name, MAPL_GRID_NAME_DEFAULT) call set_with_default(factory%nx, nx, MAPL_UNDEFINED_INTEGER) call set_with_default(factory%ny, ny, MAPL_UNDEFINED_INTEGER) @@ -155,7 +155,7 @@ function SwathGridFactory_from_parameters(unusable, grid_name, & if (present(jms)) factory%jms = jms call factory%check_and_fill_consistency(_RC) - + _RETURN(_SUCCESS) end function SwathGridFactory_from_parameters @@ -168,8 +168,14 @@ function make_new_grid(this, unusable, rc) result(grid) integer :: status _UNUSED_DUMMY(unusable) + + if (mapl_am_I_root()) write(6,*) 'MAPL_SwathGridFactory.F90: bf this%create_basic_grid' grid = this%create_basic_grid(_RC) + if (mapl_am_I_root()) write(6,*) 'MAPL_SwathGridFactory.F90: af this%create_basic_grid' + call this%add_horz_coordinates_from_file(grid,_RC) + if (mapl_am_I_root()) write(6,*) 'MAPL_SwathGridFactory.F90: af this%add_horz_coordinates_from_file' + _RETURN(_SUCCESS) end function make_new_grid @@ -202,7 +208,7 @@ function create_basic_grid(this, unusable, rc) result(grid) call ESMF_AttributeSet(grid, 'GridType', 'LatLon', _RC) call ESMF_AttributeSet(grid, 'Global', .false., _RC) - _RETURN(_SUCCESS) + _RETURN(_SUCCESS) end function create_basic_grid @@ -217,32 +223,52 @@ subroutine add_horz_coordinates_from_file(this, grid, unusable, rc) real(kind=ESMF_KIND_R8), pointer :: fptr(:,:) real, pointer :: centers(:,:) - real, allocatable :: centers_full(:,:) - + real, allocatable :: lon_true(:,:) + real, allocatable :: lat_true(:,:) + real, allocatable :: time_true(:,:) + real(kind=ESMF_KIND_R8), allocatable :: X1d(:) + integer :: i, j, k integer :: Xdim, Ydim integer :: Xdim_full, Ydim_full integer :: nx, ny - + integer :: IM, JM integer :: IM_WORLD, JM_WORLD integer :: COUNTS(3), DIMS(3) integer :: i_1, i_n, j_1, j_n ! regional array bounds type(Logger), pointer :: lgr + ! debug + type(ESMF_VM) :: vm + integer :: mypet, petcount + + integer :: rank0 + integer :: src, dst + integer :: nsize, count + integer :: nshared_pet + real, allocatable :: arr(:,:), arr_lon(:,:), arr_lat(:,:) + + integer, allocatable:: array1(:), array2(:), array3(:) + _UNUSED_DUMMY(unusable) + call ESMF_VMGetGlobal(vm,_RC) + call ESMF_VMGet(vm, localPet=mypet, petCount=petCount, _RC) Xdim=this%im_world Ydim=this%jm_world Xdim_full=this%cell_across_swath Ydim_full=this%cell_along_swath - - call MAPL_grid_interior(grid, i_1, i_n, j_1, j_n) - call MAPL_AllocateShared(centers,[Xdim,Ydim],transroot=.true.,_RC) + + call MAPL_grid_interior(grid, i_1, i_n, j_1, j_n) + call MAPL_AllocateShared(centers,[Xdim,Ydim],transroot=.true.,_RC) call MAPL_SyncSharedMemory(_RC) + call MAPL_AllocateShared(arr_lon,[Xdim,Ydim],transroot=.true.,_RC) + call MAPL_AllocateShared(arr_lat,[Xdim,Ydim],transroot=.true.,_RC) +!! mmapl_am_I_root() is element in set (rootscomm) ! if (mapl_am_I_root()) then ! write(6,'(2x,a,10i8)') & ! 'ck: Xdim, Ydim, Xdim_full, Ydim_full', Xdim, Ydim, Xdim_full, Ydim_full @@ -250,40 +276,124 @@ subroutine add_horz_coordinates_from_file(this, grid, unusable, rc) ! 'ck: i_1, i_n, j_1, j_n', i_1, i_n, j_1, j_n ! end if + ! + ! array3(1:nshared_pet) is the pet for shared headnode excluding mapl_am_i_root() + ! s1. read NC from root/rank0 + ! s2. MPI send and recv true_lon / true_lat via X1d + ! s3. pass X1d to Shmem [centers] + ! + + nsize = petCount + allocate (array1(nsize)) + allocate (array2(nsize)) + + array1(:) = 0 + src = 0 + dst = 0 + + if (mapl_am_i_root()) then + rank0 = mypet + src = 1 + end if + + if (MAPL_AmNodeRoot .or. (.not. MAPL_ShmInitialized)) then + if (mypet/=rank0) then + array1(mypet+1) = mypet+1 ! raise index to [1, N] + dst = 1 + end if + end if - ! read longitudes - if (MAPL_AmNodeRoot .or. (.not. MAPL_ShmInitialized)) then - allocate( centers_full(Xdim_full, Ydim_full)) + call ESMF_VMAllReduce(vm, sendData=array1, recvData=array2, count=nsize, & + reduceflag=ESMF_REDUCE_SUM, rc=rc) + write(6, '(2x,a,2x,i5,2x,a,2x,10i10)') 'mypet, array2', mypet, ':', array2 + + j=0 + do i=1, nsize + if ( array2(i) > 0 ) then + j=j+1 + end if + end do + allocate (array3(j)) + nshared_pet = j + + j=0 + do i=1, nsize + if ( array2(i) > 0 ) then + j=j+1 + array3(j) = array2(i) - 1 ! downshift value to mypet + end if + end do + + if (src==1 .OR. dst==1) then + allocate( arr_lon(Xdim, Ydim) ) + allocate( arr_lat(Xdim, Ydim) ) + allocate( X1d( Xdim * Ydim ) ) + allocate( Y1d( Xdim * Ydim ) ) + end if + + if (mypet==rank0) then + allocate( lon_true(0,0), lat_true(0,0), time_true(0,0) ) call read_M_files_4_swath (this%filenames(1:this%M_file), nx, ny, & this%index_name_lon, this%index_name_lat, & - var_name_lon=this%var_name_lon, lon=centers_full, _RC) + var_name_lon=this%var_name_lon, & + var_name_lat=this%var_name_lat, & + var_name_time=this%var_name_time, & + lon=lon_true, lat=lat_true, time=time_true, & + Tfilter=.true., _RC) k=0 do j=this%epoch_index(3), this%epoch_index(4) k=k+1 - centers(1:Xdim, k) = centers_full(1:Xdim, j) + arr_lon(1:Xdim, k) = lon_true(1:Xdim, j) + arr_lat(1:Xdim, k) = lat_true(1:Xdim, j) enddo - centers=centers*MAPL_DEGREES_TO_RADIANS_R8 - deallocate (centers_full) + arr_lon=arr_lon*MAPL_DEGREES_TO_RADIANS_R8 + arr_lat=arr_lat*MAPL_DEGREES_TO_RADIANS_R8 + k=0 + do j=1, Ydim + do i=1, Xdim + X1d(k) = arr_lon(i,j) + Y1d(k) = arr_lat(i,j) + end do + end do + deallocate( lon_true, time_true ) + ! + end if + + + + if (nshared_pet > 0) then + count = Xdim * Ydim + if (src==1) then + do j=1, nshared_pet + call ESMF_VMSend(vm, sendData=X1d, count=count, dstPet=array3(j), rc=rc) + call ESMF_VMSend(vm, sendData=Y1d, count=count, dstPet=array3(j), rc=rc) + end do + end if + if (dst==1) then + call ESMF_VMRecv(vm, recvData=arr_lon, count=count, srcPet=rank0, rc=rc) + call ESMF_VMRecv(vm, recvData=arr_lat, count=count, srcPet=rank0, rc=rc) + end if + end if + + + ! read longitudes + if (MAPL_AmNodeRoot .or. (.not. MAPL_ShmInitialized)) then + write(6,'(2x,a,2x,i10)') 'add_horz_coord: MAPL_AmNodeRoot: mypet=', mypet + centers = arr_lon end if - call MAPL_SyncSharedMemory(_RC) + + +!! mpi_barrier for each core within node + call MAPL_SyncSharedMemory(_RC) + call ESMF_GridGetCoord(grid, coordDim=1, localDE=0, & staggerloc=ESMF_STAGGERLOC_CENTER, farrayPtr=fptr, _RC) fptr=real(centers(i_1:i_n,j_1:j_n), kind=ESMF_KIND_R8) - - ! read latitudes +!! _FAIL ('nail -1') + ! read latitudes if (MAPL_AmNodeRoot .or. (.not. MAPL_ShmInitialized)) then - allocate( centers_full(Xdim_full, Ydim_full)) - call read_M_files_4_swath (this%filenames(1:this%M_file), nx, ny, & - this%index_name_lon, this%index_name_lat, & - var_name_lat=this%var_name_lat, lat=centers_full, _RC) - k=0 - do j=this%epoch_index(3), this%epoch_index(4) - k=k+1 - centers(1:Xdim, k) = centers_full(1:Xdim, j) - enddo - centers=centers*MAPL_DEGREES_TO_RADIANS_R8 - deallocate (centers_full) + centers = arr_lat end if call MAPL_SyncSharedMemory(_RC) call ESMF_GridGetCoord(grid, coordDim=2, localDE=0, & @@ -296,7 +406,7 @@ subroutine add_horz_coordinates_from_file(this, grid, unusable, rc) else deallocate(centers) end if - + _RETURN(_SUCCESS) end subroutine add_horz_coordinates_from_file @@ -413,12 +523,13 @@ subroutine initialize_from_config_with_prefix(this, config, prefix, unusable, rc integer :: nx, ny character(len=ESMF_MAXSTR) :: key_lon, key_lat, key_time character(len=ESMF_MAXSTR) :: tunit, grp1, grp2 - character(len=ESMF_MAXSTR) :: filename, STR1, tmp + character(len=ESMF_MAXSTR) :: filename, STR1, tmp character(len=ESMF_MAXSTR) :: symd, shms - ! real(ESMF_KIND_R8), allocatable :: scanTime(:,:) real, allocatable :: scanTime(:,:) + real, allocatable :: lon_true(:,:) + real, allocatable :: lat_true(:,:) integer :: yy, mm, dd, h, m, s, sec, second integer :: i, j, L integer :: ncid, ncid2, varid @@ -429,24 +540,23 @@ subroutine initialize_from_config_with_prefix(this, config, prefix, unusable, rc integer (ESMF_KIND_I8) :: j0, j1, jt, jt1, jt2 real(ESMF_KIND_R8) :: jx0, jx1 real(ESMF_KIND_R8) :: x0, x1 - integer :: khi, klo, k, nstart, max_iter + integer :: khi, klo, k, nstart, nend, max_iter type(Logger), pointer :: lgr logical :: ispresent - type(ESMF_TimeInterval) :: Toff - + type(ESMF_TimeInterval) :: Toff, obs_time_span + _UNUSED_DUMMY(unusable) lgr => logging%get_logger('HISTORY.sampler') - + call ESMF_VmGetCurrent(VM, _RC) ! input : config ! output: this%epoch_index, nx, ny ! ! Read in specs, crop epoch_index based on scanTime - ! - + !__ s1. read in file spec. ! call ESMF_ConfigGetAttribute(config, tmp, label=prefix//'GRIDNAME:', default=MAPL_GRID_NAME_DEFAULT) @@ -458,41 +568,63 @@ subroutine initialize_from_config_with_prefix(this, config, prefix, unusable, rc call ESMF_ConfigGetAttribute(config, this%epoch, label=prefix//'Epoch:', default=300, _RC) call ESMF_ConfigGetAttribute(config, tmp, label=prefix//'Epoch_init:', default='2006', _RC) + call lgr%debug(' %a %a', 'CurrTime =', trim(tmp)) + + if ( index(tmp, 'T') /= 0 .OR. index(tmp, '-') /= 0 ) then + call ESMF_TimeSet(currTime, timeString=tmp, _RC) + else + read(tmp,'(i4,5i2)') yy,mm,dd,h,m,s + call ESMF_Timeset(currTime, yy=yy, mm=mm, dd=dd, h=h, m=m, s=s, _RC) + endif + second = hms_2_s(this%Epoch) + call ESMF_TimeIntervalSet(this%epoch_frequency, s=second, _RC) + call ESMF_ConfigGetAttribute(config, value=STR1, default="", & label= prefix// 'obs_file_begin:', _RC) - - if (trim(STR1)=='') then - _FAIL('obs_file_begin missing, code crash') - else - call ESMF_TimeSet(this%obsfile_start_time, timestring=STR1, _RC) + _ASSERT (trim(STR1)/='', 'obs_file_begin missing, critical for data with 5 min interval!') + call ESMF_TimeSet(this%obsfile_start_time, timestring=STR1, _RC) + !!disable using currTime as obsfile_start_time + !!if (trim(STR1)=='') then + !! this%obsfile_start_time = currTime + !! call ESMF_TimeGet(currTime, timestring=STR1, _RC) + !! if (mapl_am_I_root()) then + !! write(6,105) 'obs_file_begin missing, default = currTime :', trim(STR1) + !! endif + !!else + !! call ESMF_TimeSet(this%obsfile_start_time, timestring=STR1, _RC) + !! if (mapl_am_I_root()) then + !! write(6,105) 'obs_file_begin provided: ', trim(STR1) + !! end if + !!end if + + + if (mapl_am_I_root()) then + write(6,105) 'obs_file_begin provided: ', trim(STR1) end if call ESMF_ConfigGetAttribute(config, value=STR1, default="", & label=prefix // 'obs_file_end:', _RC) - if (trim(STR1)=='') then - _FAIL('obs_file_end missing, code crash') + call ESMF_TimeIntervalSet(obs_time_span, d=100, _RC) + this%obsfile_end_time = this%obsfile_start_time + obs_time_span + call ESMF_TimeGet(this%obsfile_end_time, timestring=STR1, _RC) + if (mapl_am_I_root()) then + write(6,105) 'obs_file_end missing, default = begin+100D:', trim(STR1) + endif else call ESMF_TimeSet(this%obsfile_end_time, timestring=STR1, _RC) + if (mapl_am_I_root()) then + write(6,105) 'obs_file_end provided:', trim(STR1) + end if end if call ESMF_ConfigGetAttribute(config, value=STR1, default="", & label= prefix// 'obs_file_interval:', _RC) _ASSERT(STR1/='', 'fatal error: obs_file_interval not provided in RC file') + if (mapl_am_I_root()) write(6,105) 'obs_file_interval:', trim(STR1) + if (mapl_am_I_root()) write(6,106) 'Epoch (second) :', second - -! if (mapl_am_I_root()) then -! write(6,'(//2x, a)') 'SWATH initialize_from_config_with_prefix' -! print*, 'obs_file_begin: str1=', trim(STR1) -! write(6,105) 'obs_file_begin provided: ', trim(STR1) -! print*, 'obs_file_end: str1=', trim(STR1) -! write(6,105) 'obs_file_end provided:', trim(STR1) -! write(6,105) 'obs_file_interval:', trim(STR1) -! write(6,106) 'Epoch (hhmmss) :', this%epoch -! end if - - i= index( trim(STR1), ' ' ) if (i>0) then symd=STR1(1:i-1) @@ -501,29 +633,12 @@ subroutine initialize_from_config_with_prefix(this, config, prefix, unusable, rc symd='' shms=trim(STR1) endif - call convert_twostring_2_esmfinterval (symd, shms, this%obsfile_interval, _RC) - - second = hms_2_s(this%Epoch) - call ESMF_TimeIntervalSet(this%epoch_frequency, s=second, _RC) - - if ( index(tmp, 'T') /= 0 .OR. index(tmp, '-') /= 0 ) then - call ESMF_TimeSet(currTime, timeString=tmp, _RC) - else - read(tmp,'(i4,5i2)') yy,mm,dd,h,m,s - call ESMF_Timeset(currTime, yy=yy, mm=mm, dd=dd, h=h, m=m, s=s, _RC) - endif - - call lgr%debug(' %a %a', 'input_template =', trim(this%input_template)) - !!write(6,'(2x,a,/,4i8,/,5(2x,a))') 'nx,ny,lm,epoch -- filename,tmp', & - !! this%nx,this%ny,this%lm,this%epoch,& - !! trim(filename),trim(tmp) - !!print*, 'ck: Epoch_init:', trim(tmp) - + call convert_twostring_2_esmfinterval (symd, shms, this%obsfile_interval, _RC) call ESMF_ConfigGetAttribute(config, value=this%index_name_lon, default="", & label=prefix // 'index_name_lon:', _RC) call ESMF_ConfigGetAttribute(config, value=this%index_name_lat, default="", & - label=prefix // 'index_name_lat:', _RC) + label=prefix // 'index_name_lat:', _RC) call ESMF_ConfigGetAttribute(config, this%var_name_lon, & label=prefix // 'var_name_lon:', default="", _RC) call ESMF_ConfigGetAttribute(config, this%var_name_lat, & @@ -531,15 +646,16 @@ subroutine initialize_from_config_with_prefix(this, config, prefix, unusable, rc call ESMF_ConfigGetAttribute(config, this%var_name_time, default="", & label=prefix//'var_name_time:', _RC) call ESMF_ConfigGetAttribute(config, this%tunit, default="", & - label=prefix//'tunit:', _RC) + label=prefix//'tunit:', _RC) + + call lgr%debug(' %a %a', 'input_template =', trim(this%input_template)) - !__ s2. find obsFile even if missing on disk and get array: this%t_alongtrack(:) ! call ESMF_VMGet(vm, mpiCommunicator=mpic, _RC) call MPI_COMM_RANK(mpic, irank, ierror) - + if (irank==0) & write(6,'(10(2x,a20,2x,a40,/))') & 'index_name_lon:', trim(this%index_name_lon), & @@ -547,42 +663,54 @@ subroutine initialize_from_config_with_prefix(this, config, prefix, unusable, rc 'var_name_lon:', trim(this%var_name_lon), & 'var_name_lat:', trim(this%var_name_lat), & 'var_name_time:', trim(this%var_name_time), & - 'tunit:', trim(this%tunit) - - if (irank==0) then + 'tunit:', trim(this%tunit) + + if (irank==0) then call ESMF_TimeIntervalSet(Toff, h=0, m=0, s=0, _RC) call Find_M_files_for_currTime (currTime, & this%obsfile_start_time, this%obsfile_end_time, this%obsfile_interval, & this%epoch_frequency, this%input_template, M_file, this%filenames, & T_offset_in_file_content = Toff, _RC) this%M_file = M_file - write(6,'(10(2x,a20,2x,i40))') & + write(6,'(10(2x,a20,2x,i40))') & 'M_file:', M_file do i=1, M_file - write(6,'(10(2x,a20,2x,a))') & - 'filenames(i):', trim(this%filenames(i)) + write(6,'(10(2x,a14,i4,a2,2x,a))') & + 'filenames(', i, '):', trim(this%filenames(i)) end do + !------------------------------------------------------------ + ! QC for obs files: + ! + ! 1. redefine nstart to skip un-defined time value + ! 2. Scan_Start_Time = -9999, -9999, -9999, + ! :: eliminate this row of data + !------------------------------------------------------------ + + allocate(lon_true(0,0), lat_true(0,0), scanTime(0,0)) call read_M_files_4_swath (this%filenames(1:M_file), nx, ny, & - this%index_name_lon, this%index_name_lat, _RC) + this%index_name_lon, this%index_name_lat, & + var_name_lon=this%var_name_lon, & + var_name_lat=this%var_name_lat, & + var_name_time=this%var_name_time, & + lon=lon_true, lat=lat_true, time=scanTime, & + Tfilter=.true., _RC) + nlon=nx nlat=ny - allocate(scanTime(nlon, nlat)) allocate(this%t_alongtrack(nlat)) + do j=1, nlat + this%t_alongtrack(j) = scanTime(1,j) + end do - call read_M_files_4_swath (this%filenames(1:M_file), nx, ny, & - this%index_name_lon, this%index_name_lat, & - var_name_time=this%var_name_time, time=scanTime, _RC) + !!write(6,'(a)') 'this%t_alongtrack(::50)=' + !!write(6,'(5f20.2)') this%t_alongtrack(::50) - do j=1, nlat - this%t_alongtrack(j)= scanTime(1,j) - enddo nstart = 1 ! - ! redefine nstart to skip un-defined time value ! If the t_alongtrack contains undefined values, use this code - ! + ! x0 = this%t_alongtrack(1) x1 = 1.d16 if (x0 > x1) then @@ -590,7 +718,7 @@ subroutine initialize_from_config_with_prefix(this, config, prefix, unusable, rc ! bisect backward finding the first index arr[n] < x1 klo=1 khi=nlat - max_iter = int( log( real(nlat) ) / log(2.d0) ) + 2 + max_iter = int( log( real(nlat) ) / log(2.d0) ) + 2 do i=1, max_iter k = (klo+khi)/2 if ( this%t_alongtrack(k) < x1 ) then @@ -607,7 +735,7 @@ subroutine initialize_from_config_with_prefix(this, config, prefix, unusable, rc this%cell_across_swath = nlon this%cell_along_swath = nlat deallocate(scanTime) -!! write(6,*) 'this%t_alongtrack(j)=', this%t_alongtrack(::100) + ! P2. @@ -623,26 +751,32 @@ subroutine initialize_from_config_with_prefix(this, config, prefix, unusable, rc j1= j0 + sec jx0= j0 jx1= j1 - call lgr%debug ('%a %i16 %i16', 'j0, j1 ', j0, j1) - this%epoch_index(1)= 1 this%epoch_index(2)= this%cell_across_swath - call bisect( this%t_alongtrack, jx0, jt1, n_LB=int(nstart, ESMF_KIND_I8), n_UB=int(this%cell_along_swath, ESMF_KIND_I8), rc=rc) - call bisect( this%t_alongtrack, jx1, jt2, n_LB=int(nstart, ESMF_KIND_I8), n_UB=int(this%cell_along_swath, ESMF_KIND_I8), rc=rc) + nend = this%cell_along_swath + call bisect( this%t_alongtrack, jx0, jt1, n_LB=int(nstart, ESMF_KIND_I8), n_UB=int(nend, ESMF_KIND_I8), rc=rc) + call bisect( this%t_alongtrack, jx1, jt2, n_LB=int(nstart, ESMF_KIND_I8), n_UB=int(nend, ESMF_KIND_I8), rc=rc) + call lgr%debug ('%a %i20 %i20', 'nstart, nend', nstart, nend) + call lgr%debug ('%a %f20.1 %f20.1', 'j0[currT] j1[T+Epoch] w.r.t. timeunit ', jx0, jx1) + call lgr%debug ('%a %f20.1 %f20.1', 'x0[times(1)] xn[times(N)] w.r.t. timeunit ', & + this%t_alongtrack(1), this%t_alongtrack(nend)) + call lgr%debug ('%a %i20 %i20', 'jt1, jt2 [final intercepted position]', jt1, jt2) if (jt1==jt2) then _FAIL('Epoch Time is too small, empty swath grid is generated, increase Epoch') endif + jt1 = jt1 + 1 ! (x1,x2] design this%epoch_index(3)= jt1 this%epoch_index(4)= jt2 + _ASSERT( jt1 < jt2, 'Swath grid fail : epoch_index(3) > epoch_index(4)') Xdim = this%cell_across_swath Ydim = this%epoch_index(4) - this%epoch_index(3) + 1 call lgr%debug ('%a %i4 %i4', 'bisect for j0: rc, jt', rc, jt1) - call lgr%debug ('%a %i4 %i4', 'bisect for j1: rc, jt', rc, jt2) + call lgr%debug ('%a %i4 %i4', 'bisect for j1: rc, jt', rc, jt2) call lgr%debug ('%a %i4 %i4', 'Xdim, Ydim', Xdim, Ydim) call lgr%debug ('%a %i4 %i4 %i4 %i4', 'this%epoch_index(4)', & this%epoch_index(1), this%epoch_index(2), & @@ -651,7 +785,8 @@ subroutine initialize_from_config_with_prefix(this, config, prefix, unusable, rc this%im_world = Xdim this%jm_world = Ydim end if - + + call MPI_bcast(this%M_file, 1, MPI_INTEGER, 0, mpic, ierror) do i=1, this%M_file call MPI_bcast(this%filenames(i), ESMF_MAXSTR, MPI_CHARACTER, 0, mpic, ierror) @@ -660,9 +795,10 @@ subroutine initialize_from_config_with_prefix(this, config, prefix, unusable, rc call MPI_bcast(this%im_world, 1, MPI_INTEGER, 0, mpic, ierror) call MPI_bcast(this%jm_world, 1, MPI_INTEGER, 0, mpic, ierror) call MPI_bcast(this%cell_across_swath, 1, MPI_INTEGER, 0, mpic, ierror) - call MPI_bcast(this%cell_along_swath, 1, MPI_INTEGER, 0, mpic, ierror) + call MPI_bcast(this%cell_along_swath, 1, MPI_INTEGER, 0, mpic, ierror) ! donot need to bcast this%along_track (root only) - + + call ESMF_ConfigGetAttribute(config, tmp, label=prefix//'IMS_FILE:', rc=status) if ( status == _SUCCESS ) then call get_ims_from_file(this%ims, trim(tmp),this%nx, _RC) @@ -678,9 +814,8 @@ subroutine initialize_from_config_with_prefix(this, config, prefix, unusable, rc ! ims is set at here call this%check_and_fill_consistency(_RC) - _RETURN(_SUCCESS) - + 105 format (1x,a,2x,a) 106 format (1x,a,2x,10i8) @@ -698,11 +833,11 @@ subroutine get_multi_integer(values, label, rc) logical :: isPresent call ESMF_ConfigFindLabel(config, label=prefix//label, isPresent=isPresent, _RC) - + if (.not. isPresent) then _RETURN(_SUCCESS) end if - + ! First pass: count values n = 0 do @@ -721,9 +856,9 @@ subroutine get_multi_integer(values, label, rc) call ESMF_ConfigFindLabel(config, label=prefix//label,_RC) do i = 1, n call ESMF_ConfigGetAttribute(config, values(i), _RC) - write(6,*) 'values(i)=', values(i) + write(6,*) 'values(i)=', values(i) end do - + _RETURN(_SUCCESS) end subroutine get_multi_integer @@ -796,7 +931,7 @@ function to_string(this) result(string) end function to_string - + subroutine check_and_fill_consistency(this, unusable, rc) use MAPL_BaseMod, only: MAPL_DecomposeDim class (SwathGridFactory), intent(inout) :: this @@ -869,7 +1004,7 @@ end subroutine verify end subroutine check_and_fill_consistency - + elemental subroutine set_with_default_integer(to, from, default) integer, intent(out) :: to integer, optional, intent(in) :: from @@ -936,7 +1071,7 @@ elemental subroutine set_with_default_bounds(to, from, default) end subroutine set_with_default_bounds - + ! MAPL uses values in lon_array and lat_array only to determine the ! general positioning. Actual coordinates are then recomputed. ! This helps to avoid roundoff differences from slightly different @@ -967,7 +1102,7 @@ subroutine initialize_from_esmf_distGrid(this, dist_grid, lon_array, lat_array, real, parameter :: tiny = 1.e-4 _FAIL ('stop: not implemented: subroutine initialize_from_esmf_distGrid') - + _UNUSED_DUMMY(unusable) call ESMF_DistGridGet(dist_grid, dimCount=dim_count, tileCount=tile_count) @@ -1078,7 +1213,7 @@ function generate_grid_name(this) result(name) name = im_string // 'x' // jm_string end function generate_grid_name - + function check_decomposition(this,unusable,rc) result(can_decomp) class (SwathGridFactory), target, intent(inout) :: this class (KeywordEnforcer), optional, intent(in) :: unusable @@ -1098,7 +1233,7 @@ function check_decomposition(this,unusable,rc) result(can_decomp) _RETURN(_SUCCESS) end function check_decomposition - + subroutine generate_newnxy(this,unusable,rc) use MAPL_BaseMod, only: MAPL_DecomposeDim class (SwathGridFactory), target, intent(inout) :: this @@ -1171,7 +1306,7 @@ subroutine append_metadata(this, metadata) character(len=ESMF_MAXSTR) :: key_lon character(len=ESMF_MAXSTR) :: key_lat - + ! Horizontal grid dimensions call metadata%add_dimension('lon', this%im_world) call metadata%add_dimension('lat', this%jm_world) @@ -1186,10 +1321,10 @@ subroutine append_metadata(this, metadata) call v%add_attribute('long_name', 'latitude') call v%add_attribute('units', 'degrees_north') call metadata%add_variable('lats', v) - + end subroutine append_metadata - + function get_grid_vars(this) result(vars) class (SwathGridFactory), intent(inout) :: this @@ -1197,7 +1332,7 @@ function get_grid_vars(this) result(vars) character(len=ESMF_MAXSTR) :: key_lon character(len=ESMF_MAXSTR) :: key_lat _UNUSED_DUMMY(this) - + !!key_lon=trim(this%var_name_lon) !!key_lat=trim(this%var_name_lat) vars = 'lon,lat' @@ -1300,7 +1435,7 @@ subroutine get_xy_subset(this, interval, xy_subset, rc) integer:: irank, ierror integer :: status - type(ESMF_Time) :: T1, T2 + type(ESMF_Time) :: T1, T2 integer(ESMF_KIND_I8) :: i1, i2 real(ESMF_KIND_R8) :: iT1, iT2 integer(ESMF_KIND_I8) :: index1, index2 @@ -1315,7 +1450,7 @@ subroutine get_xy_subset(this, interval, xy_subset, rc) ! xtrack xy_subset(1:2,1)=this%epoch_index(1:2) - ! atrack + ! atrack T1= interval(1) T2= interval(2) @@ -1337,24 +1472,24 @@ subroutine get_xy_subset(this, interval, xy_subset, rc) call bisect( this%t_alongtrack, iT1, index1, n_LB=int(jlo, ESMF_KIND_I8), n_UB=int(jhi, ESMF_KIND_I8), rc=rc) call bisect( this%t_alongtrack, iT2, index2, n_LB=int(jlo, ESMF_KIND_I8), n_UB=int(jhi, ESMF_KIND_I8), rc=rc) - !! complex version + !! complex version !! ! (x1, x2] design in bisect !! if (index1==jlo-1) then !! je = index1 + 1 !! else !! je = index1 !! end if - !! xy_subset(1, 2) = je + !! xy_subset(1, 2) = je !! if (index2==jlo-1) then !! je = index2 + 1 !! else !! je = index2 - !! end if + !! end if !! xy_subset(2, 2) = je - ! simple version + ! simple version xy_subset(1, 2)=index1+1 ! atrack - xy_subset(2, 2)=index2 + xy_subset(2, 2)=index2 ! !- relative @@ -1364,18 +1499,18 @@ subroutine get_xy_subset(this, interval, xy_subset, rc) end if call MPI_bcast(xy_subset, 4, MPI_INTEGER, 0, mpic, ierror) - + _RETURN(_SUCCESS) end subroutine get_xy_subset - + subroutine destroy(this, rc) class(SwathGridFactory), intent(inout) :: this integer, optional, intent(out) :: rc - integer :: i + integer :: i return end subroutine destroy - + ! here grid == external_grid ! because this%grid is protected in AbstractGridFactory @@ -1392,8 +1527,10 @@ subroutine get_obs_time(this, grid, obs_time, rc) !! shared mem real(kind=ESMF_KIND_R8), pointer :: fptr(:,:) real, pointer :: centers(:,:) - real, allocatable :: centers_full(:,:) - + real, allocatable :: lon_true(:,:) + real, allocatable :: lat_true(:,:) + real, allocatable :: time_true(:,:) + integer :: i, j, k integer :: Xdim, Ydim integer :: Xdim_full, Ydim_full @@ -1413,19 +1550,22 @@ subroutine get_obs_time(this, grid, obs_time, rc) call MAPL_SyncSharedMemory(_RC) - ! read Time and set + ! read and set Time if (MAPL_AmNodeRoot .or. (.not. MAPL_ShmInitialized)) then - allocate( centers_full(Xdim_full, Ydim_full)) + allocate( lon_true(0,0), lat_true(0,0), time_true(0,0) ) call read_M_files_4_swath (this%filenames(1:this%M_file), nx, ny, & this%index_name_lon, this%index_name_lat, & - var_name_time=this%var_name_time, time=centers_full, _RC) - !!call get_v2d_netcdf(this%grid_file_name, time_name, centers_full, Xdim_full, Ydim_full) + var_name_lon=this%var_name_lon, & + var_name_lat=this%var_name_lat, & + var_name_time=this%var_name_time, & + lon=lon_true, lat=lat_true, time=time_true, & + Tfilter=.true., _RC) k=0 do j=this%epoch_index(3), this%epoch_index(4) k=k+1 - centers(1:Xdim, k) = centers_full(1:Xdim, j) + centers(1:Xdim, k) = time_true(1:Xdim, j) enddo - deallocate (centers_full) + deallocate (lon_true, lat_true, time_true) end if call MAPL_SyncSharedMemory(_RC) diff --git a/base/Plain_netCDF_Time.F90 b/base/Plain_netCDF_Time.F90 index be20b3d76bb1..33035962936e 100644 --- a/base/Plain_netCDF_Time.F90 +++ b/base/Plain_netCDF_Time.F90 @@ -117,7 +117,11 @@ subroutine get_attribute_from_group(filename, group_name, var_name, attr_name, a character(len=100) :: str2 call check_nc_status(nf90_open(fileName, NF90_NOWRITE, ncid2), _RC) - call check_nc_status(nf90_inq_ncid(ncid2, group_name, ncid), _RC) + if (group_name/='') then + call check_nc_status(nf90_inq_ncid(ncid2, group_name, ncid), _RC) + else + ncid = ncid2 + end if call check_nc_status(nf90_inq_varid(ncid, var_name, varid), _RC) call check_nc_status(nf90_inquire_attribute(ncid, varid, attr_name, xtype, len=len), _RC) c_ncid= ncid @@ -241,7 +245,6 @@ subroutine check_nc_status(status, rc) integer, intent(out), optional :: rc _ASSERT(status == nf90_noerr, 'netCDF error: '//trim(nf90_strerror(status))) - _RETURN(_SUCCESS) end subroutine check_nc_status @@ -287,10 +290,20 @@ subroutine time_esmf_2_nc_int(time, tunit, n, rc) type(ESMF_Time) :: time0 type(ESMF_TimeInterval) :: dt + character(len=ESMF_MAXSTR) :: STR1 + + n=0 call parse_timeunit(tunit, n, time0, dt, _RC) dt = time - time0 +! ! test +! write(6, '(2x,a,2x,a)') 'tunit=', trim(tunit) +! call ESMF_TimeGet(time, timestring=STR1, _RC) +! write(6, '(2x,a,2x,a)') 'time=', trim(STR1) +! call ESMF_TimeGet(time0, timestring=STR1, _RC) +! write(6, '(2x,a,2x,a)') 'time0=', trim(STR1) + ! assume unit is second ! call ESMF_TimeIntervalGet(dt, s_i8=n, _RC) @@ -300,6 +313,10 @@ subroutine time_esmf_2_nc_int(time, tunit, n, rc) end subroutine time_esmf_2_nc_int + ! + ! n sec after tunit + ! t0 = since [ xxxx-xx-xx ] + ! dt = n sec subroutine parse_timeunit_i4(tunit, n, t0, dt, rc) use ESMF implicit none @@ -329,7 +346,7 @@ subroutine parse_timeunit_i4(tunit, n, t0, dt, rc) isec=n gregorianCalendar = ESMF_CalendarCreate(ESMF_CALKIND_GREGORIAN, name='Gregorian_obs', _RC) - call ESMF_timeSet(t0, yy=y,mm=m,dd=m,h=hour,m=min,s=sec,& + call ESMF_timeSet(t0, yy=y,mm=m,dd=d,h=hour,m=min,s=sec,& calendar=gregorianCalendar, _RC) call ESMF_timeintervalSet(dt, d=0, h=0, m=0, s=isec, _RC) @@ -363,11 +380,14 @@ subroutine parse_timeunit_i8(tunit, n, t0, dt, rc) read(s1, '(i4,a1,i2,a1,i2)') y, c1, m, c1, d read(s2, '(i2,a1,i2,a1,i2)') hour, c1, min, c1, sec +! write(6,*) 'y, c1, m, c1, d', y, c1, m, c1, d +! write(6,*) 'hour, c1, min, c1, sec', hour, c1, min, c1, sec + _ASSERT(trim(s_unit) == 'seconds', "s_unit /= 'seconds' is not handled") isec=n gregorianCalendar = ESMF_CalendarCreate(ESMF_CALKIND_GREGORIAN, name='Gregorian_obs', _RC) - call ESMF_timeSet(t0, yy=y,mm=m,dd=m,h=hour,m=min,s=sec,& + call ESMF_timeSet(t0, yy=y,mm=m,dd=d,h=hour,m=min,s=sec,& calendar=gregorianCalendar, _RC) call ESMF_timeintervalSet(dt, d=0, h=0, m=0, s_i8=isec, _RC) @@ -451,7 +471,7 @@ subroutine bisect_find_LB_R8_I8(xa, x, n, n_LB, n_UB, rc) if(present(n_LB)) LB=max(LB, n_LB) if(present(n_UB)) UB=min(UB, n_UB) klo=LB; khi=UB; dk=1 - + if ( xa(LB ) > xa(UB) ) then klo= UB khi= LB @@ -673,7 +693,7 @@ function matches( string, substring ) RETURN end function matches - + subroutine split_string_by_space (string_in, length_mx, & mxseg, nseg, str_piece, jstatus) integer, intent (in) :: length_mx diff --git a/gridcomps/History/MAPL_EpochSwathMod.F90 b/gridcomps/History/MAPL_EpochSwathMod.F90 index 62b94145df5f..82fdebcbd9b6 100644 --- a/gridcomps/History/MAPL_EpochSwathMod.F90 +++ b/gridcomps/History/MAPL_EpochSwathMod.F90 @@ -29,27 +29,35 @@ module MAPL_EpochSwathMod use MAPL_DownbitMod use Plain_netCDF_Time use, intrinsic :: ISO_C_BINDING - use, intrinsic :: iso_fortran_env, only: REAL64 - use ieee_arithmetic, only: isnan => ieee_is_nan + use MAPL_CommsMod, only : MAPL_Am_I_Root implicit none - private - type, public :: samplerHQ + integer, parameter :: ngrid_max = 10 + + type, private :: K_V_CF + character(len=ESMF_MAXSTR) :: key + type(ESMF_config) :: cf + end type K_V_CF + + type, public :: samplerHQ type(ESMF_Clock) :: clock type(ESMF_Alarm) :: alarm type(ESMF_Time) :: RingTime type(ESMF_TimeInterval) :: Frequency_epoch - type(ESMF_config) :: config_grid_save - type(ESMF_grid) :: ogrid + integer :: ngrid = 0 character(len=ESMF_MAXSTR) :: grid_type + character(len=ESMF_MAXSTR) :: tunit + type (K_V_CF) :: CF_loc(ngrid_max) real*8 :: arr(2) contains procedure :: create_grid procedure :: regrid_accumulate => regrid_accumulate_on_xysubset procedure :: destroy_rh_regen_ogrid - procedure :: fill_time_in_bundle + procedure :: fill_time_in_bundle + procedure :: find_config + procedure :: config_accumulate end type samplerHQ interface samplerHQ @@ -67,7 +75,7 @@ module MAPL_EpochSwathMod logical :: doVertRegrid = .false. type(ESMF_FieldBundle) :: output_bundle type(ESMF_FieldBundle) :: input_bundle - type(ESMF_FieldBundle) :: acc_bundle + type(ESMF_FieldBundle) :: acc_bundle type(ESMF_Time) :: startTime integer :: regrid_method = REGRID_METHOD_BILINEAR integer :: nbits_to_keep = MAPL_NBITS_NOT_SET @@ -86,7 +94,7 @@ module MAPL_EpochSwathMod logical :: have_initalized contains !! procedure :: CreateFileMetaData - procedure :: Create_bundle_RH + procedure :: Create_bundle_RH procedure :: CreateVariable procedure :: regridScalar procedure :: regridVector @@ -95,7 +103,7 @@ module MAPL_EpochSwathMod procedure :: check_chunking procedure :: alphabatize_variables procedure :: addVariable_to_acc_bundle - procedure :: addVariable_to_output_bundle + procedure :: addVariable_to_output_bundle procedure :: interp_accumulate_fields end type sampler @@ -105,36 +113,36 @@ module MAPL_EpochSwathMod contains - function new_samplerHQ(clock, config, key, rc) result(hq) + ! + ! in MAPL_HistoryGridComp.F90, Hsampler get its config and key + ! from the first SwathGrid entry in HISTORY.rc + ! thus + ! there is only one frequency_epoch for all the SwathGrid usage + ! + function new_samplerHQ(clock, key, config, rc) result(hq) implicit none type(samplerHQ) :: hq - type(ESMF_Clock), intent(in) :: clock + type(ESMF_Clock), intent(in) :: clock + character(len=*), intent(in) :: key type(ESMF_Config), intent(inout) :: config - character(len=*), intent(in) :: key - integer, optional, intent(out) :: rc + integer, optional, intent(out) :: rc - character(len=ESMF_MAXSTR) :: time_string integer :: status + integer :: second integer :: time_integer - type(ESMF_Time) :: RingTime_epoch - type(ESMF_Time) :: startTime - type(ESMF_Time) :: currTime - type(ESMF_TimeInterval) :: timeStep + type(ESMF_Time) :: startTime + type(ESMF_Time) :: currTime + type(ESMF_TimeInterval) :: timeStep type(ESMF_TimeInterval) :: Frequency_epoch - integer :: sec, second - integer :: n1 - type(ESMF_Config) :: cf - hq%clock= clock - hq%config_grid_save= config - hq%arr(1:2) = -2.d0 call ESMF_ClockGet ( clock, CurrTime=currTime, _RC ) call ESMF_ClockGet ( clock, timestep=timestep, _RC ) call ESMF_ClockGet ( clock, startTime=startTime, _RC ) call ESMF_ConfigGetAttribute(config, value=time_integer, label=trim(key)//'.Epoch:', default=0, _RC) + call ESMF_ConfigGetAttribute(config, value=hq%tunit, label=trim(key)//'.tunit:', default="", _RC) _ASSERT(time_integer /= 0, 'Epoch value in config wrong') second = hms_2_s (time_integer) call ESMF_TimeIntervalSet(frequency_epoch, s=second, _RC) @@ -146,7 +154,44 @@ function new_samplerHQ(clock, config, key, rc) result(hq) _RETURN(_SUCCESS) end function new_samplerHQ - + + + function find_config (this, key, rc) result(cf) + class(samplerHQ) :: this + character(len=*) , intent(in) :: key + type(ESMF_Config) :: cf + integer, intent(out), optional :: rc + integer :: status + integer :: i, j + + j=0 + do i=1, this%ngrid + if ( trim(key) == trim(this%CF_loc(i)%key) ) then + cf = this%CF_loc(i)%cf + j=j+1 + exit + end if + end do + + _ASSERT( j>0 , trim(key)//' is not found in Hsampler CF_loc(:)') + + _RETURN(_SUCCESS) + end function find_config + + + subroutine config_accumulate (this, key, cf, rc) + class(samplerHQ) :: this + type(ESMF_Config), intent(in) :: cf + character(len=*) , intent(in) :: key + integer, intent(out), optional :: rc + integer :: status + + this%ngrid = this%ngrid + 1 + this%CF_loc(this%ngrid)%key = trim(key) + this%CF_loc(this%ngrid)%cf = cf + _RETURN(_SUCCESS) + end subroutine config_accumulate + !--------------------------------------------------! ! __ set @@ -161,24 +206,26 @@ function create_grid(this, key, currTime, grid_type, rc) result(ogrid) character(len=*), optional, intent(in) :: grid_type integer, intent(out), optional :: rc integer :: status - + type(ESMF_Config) :: config_grid character(len=ESMF_MAXSTR) :: time_string - logical :: ispresent if (present(grid_type)) this%grid_type = trim(grid_type) - config_grid = this%config_grid_save + config_grid = this%find_config(key) call ESMF_TimeGet(currTime, timeString=time_string, _RC) - ! + + ! ! -- the `ESMF_ConfigSetAttribute` shows a risk ! to overwrite the nextline in config ! call ESMF_ConfigSetAttribute( config_grid, trim(time_string), label=trim(key)//'.Epoch_init:', _RC) + ogrid = grid_manager%make_grid(config_grid, prefix=trim(key)//'.', _RC ) - this%ogrid = ogrid + !! call grid_validate (ogrid,) + _RETURN(_SUCCESS) - + end function create_grid @@ -187,76 +234,62 @@ subroutine regrid_accumulate_on_xysubset (this, sp, rc) class(sampler), intent(inout) :: sp integer, intent(out), optional :: rc integer :: status - - class(AbstractGridFactory), pointer :: factory - integer :: xy_subset(2,2) - type(ESMF_Time) :: timeset(2) - type(ESMF_Time) :: current_time - type(ESMF_TimeInterval) :: dur - character(len=ESMF_MAXSTR) :: time_string - integer, allocatable :: global_xy_mask(:,:) - integer, allocatable :: local_xy_mask(:,:) + class(AbstractGridFactory), pointer :: factory + type(ESMF_Time) :: timeset(2) + type(ESMF_Time) :: current_time + type(ESMF_TimeInterval) :: dur + integer :: xy_subset(2,2) - integer :: counts(5) - integer :: dims(3) - integer :: m1, m2 - ! __ s1. get xy_subset - factory => grid_manager%get_factory(this%ogrid,_RC) call ESMF_ClockGet(this%clock,currTime=current_time,_RC) call ESMF_ClockGet(this%clock,timeStep=dur, _RC ) timeset(1) = current_time - dur timeset(2) = current_time + + factory => grid_manager%get_factory(sp%output_grid,_RC) call factory%get_xy_subset( timeset, xy_subset, _RC) - + ! __ s2. interpolate then save data using xy_mask call sp%interp_accumulate_fields (xy_subset, _RC) _RETURN(ESMF_SUCCESS) - - end subroutine regrid_accumulate_on_xysubset - + + end subroutine regrid_accumulate_on_xysubset + subroutine destroy_rh_regen_ogrid (this, key_grid_label, output_grids, sp, rc) implicit none - class(samplerHQ) :: this + class(samplerHQ), target :: this class(sampler) :: sp type (StringGridMap), target, intent(inout) :: output_grids character(len=*), intent(in) :: key_grid_label - integer, intent(out), optional :: rc + integer, intent(out), optional :: rc integer :: status - - class(AbstractGridFactory), pointer :: factory + type(ESMF_Time) :: currTime - type(ESMF_TimeInterval) :: dur - character(len=ESMF_MAXSTR) :: time_string - type(ESMF_Grid), pointer :: pgrid type(ESMF_Grid) :: ogrid - type(ESMF_Grid) :: input_grid character(len=ESMF_MAXSTR) :: key_str type (StringGridMapIterator) :: iter character(len=:), pointer :: key - type (ESMF_Config) :: config_grid - + integer :: i, numVars character(len=ESMF_MAXSTR), allocatable :: names(:) type(ESMF_Field) :: field - + if ( .NOT. ESMF_AlarmIsRinging(this%alarm) ) then - write(6,*) 'ck: regen, not in alarming' - rc=0 - return + _RETURN(ESMF_SUCCESS) endif - !__ s1. destroy ogrid + regen ogrid + !__ s1. destroy ogrid + RH, regen ogrid + + key_str = trim(key_grid_label) + pgrid => output_grids%at(key_str) - key_str=trim(key_grid_label) - pgrid => output_grids%at(trim(key_grid_label)) call grid_manager%destroy(pgrid,_RC) call ESMF_ClockGet (this%clock, CurrTime=currTime, _RC ) @@ -266,19 +299,18 @@ subroutine destroy_rh_regen_ogrid (this, key_grid_label, output_grids, sp, rc) if (trim(key)==trim(key_str)) then ogrid = this%create_grid (key_str, currTime, _RC) call output_grids%set(key, ogrid) - this%ogrid = ogrid endif call iter%next() enddo !__ s2. destroy RH - call sp%regrid_handle%destroy(_RC) - + + !__ s3. destroy acc_bundle / output_bundle - + call ESMF_FieldBundleGet(sp%acc_bundle,fieldCount=numVars,_RC) allocate(names(numVars),stat=status) call ESMF_FieldBundleGet(sp%acc_bundle,fieldNameList=names,_RC) @@ -298,18 +330,19 @@ subroutine destroy_rh_regen_ogrid (this, key_grid_label, output_grids, sp, rc) call ESMF_FieldBundleDestroy(sp%output_bundle,noGarbage=.true.,_RC) _RETURN(ESMF_SUCCESS) - + end subroutine destroy_rh_regen_ogrid - subroutine fill_time_in_bundle (this, xname, bundle, rc) + subroutine fill_time_in_bundle (this, xname, bundle, ogrid, rc) implicit none class(samplerHQ) :: this character(len=*), intent(in) :: xname type(ESMF_FieldBundle), intent(inout) :: bundle integer, optional, intent(out) :: rc - integer :: status + integer :: status + type(ESMF_Grid), intent(in) :: ogrid class(AbstractGridFactory), pointer :: factory type(ESMF_Field) :: field real(kind=ESMF_KIND_R4), pointer :: ptr2d(:,:) @@ -317,16 +350,16 @@ subroutine fill_time_in_bundle (this, xname, bundle, rc) ! __ get field xname='time' call ESMF_FieldBundleGet (bundle, xname, field=field, _RC) call ESMF_FieldGet (field, farrayptr=ptr2d, _RC) - + ! __ obs_time from swath factory - factory => grid_manager%get_factory(this%ogrid,_RC) - call factory%get_obs_time (this%ogrid, ptr2d, _RC) - + factory => grid_manager%get_factory(ogrid,_RC) + call factory%get_obs_time (ogrid, ptr2d, _RC) + _RETURN(ESMF_SUCCESS) end subroutine fill_time_in_bundle - + function new_sampler(metadata,input_bundle,output_bundle,write_collection_id,read_collection_id, & metadata_collection_id,regrid_method,fraction,items,rc) result(GriddedIO) type(sampler) :: GriddedIO @@ -354,14 +387,14 @@ function new_sampler(metadata,input_bundle,output_bundle,write_collection_id,rea end function new_sampler - subroutine Create_bundle_RH(this,items,bundle,timeInfo,vdata,ogrid,global_attributes,rc) + subroutine Create_bundle_RH(this,items,bundle,tunit,timeInfo,vdata,ogrid,rc) class (sampler), intent(inout) :: this type(GriddedIOitemVector), target, intent(inout) :: items type(ESMF_FieldBundle), intent(inout) :: bundle + character(len=*), intent(in) :: tunit type(TimeData), optional, intent(inout) :: timeInfo type(VerticalData), intent(inout), optional :: vdata type (ESMF_Grid), intent(inout), pointer, optional :: ogrid - type(StringStringMap), target, intent(in), optional :: global_attributes integer, intent(out), optional :: rc type(ESMF_Grid) :: input_grid @@ -370,10 +403,6 @@ subroutine Create_bundle_RH(this,items,bundle,timeInfo,vdata,ogrid,global_attrib type(ESMF_Field) :: new_field type(GriddedIOitemVectorIterator) :: iter type(GriddedIOitem), pointer :: item - type(stringVector) :: order - integer :: metadataVarsSize - type(StringStringMapIterator) :: s_iter - character(len=:), pointer :: attr_name, attr_val integer :: status this%items = items @@ -418,7 +447,7 @@ subroutine Create_bundle_RH(this,items,bundle,timeInfo,vdata,ogrid,global_attrib this%vdata=VerticalData(rc=status) _VERIFY(status) end if - + call this%vdata%append_vertical_metadata(this%metadata,this%input_bundle,rc=status) _VERIFY(status) this%doVertRegrid = (this%vdata%regrid_type /= VERTICAL_METHOD_NONE) @@ -450,7 +479,7 @@ subroutine Create_bundle_RH(this,items,bundle,timeInfo,vdata,ogrid,global_attrib item => iter%get() call this%addVariable_to_acc_bundle(item%xname,_RC) if (item%itemType == ItemTypeVector) then - call this%addVariable_to_acc_bundle(item%yname,_RC) + call this%addVariable_to_acc_bundle(item%yname,_RC) end if call iter%next() enddo @@ -460,13 +489,16 @@ subroutine Create_bundle_RH(this,items,bundle,timeInfo,vdata,ogrid,global_attrib ! new_field = ESMF_FieldCreate(this%output_grid ,name='time', & typekind=ESMF_TYPEKIND_R4,_RC) + ! + ! add attribute + ! + call ESMF_AttributeSet(new_field,'UNITS',trim(tunit),_RC) call MAPL_FieldBundleAdd( this%acc_bundle, new_field, _RC ) - _RETURN(_SUCCESS) end subroutine Create_Bundle_RH - + subroutine set_param(this,deflation,quantize_algorithm,quantize_level,chunking,nbits_to_keep,regrid_method,itemOrder,write_collection_id,rc) class (sampler), intent(inout) :: this integer, optional, intent(in) :: deflation @@ -577,9 +609,7 @@ subroutine CreateVariable(this,itemName,rc) integer :: fieldRank logical :: isPresent character(len=ESMF_MAXSTR) :: varName,longName,units - character(len=:), allocatable :: grid_dims - character(len=:), allocatable :: vdims - type(Variable) :: v + call ESMF_FieldBundleGet(this%input_bundle,itemName,field=field,rc=status) _VERIFY(status) @@ -641,7 +671,7 @@ subroutine RegridScalar(this,itemName,rc) type(ESMF_Grid) :: gridIn,gridOut logical :: hasDE_in, hasDE_out logical :: first_entry - + call ESMF_FieldBundleGet(this%output_bundle,itemName,field=outField,rc=status) _VERIFY(status) call ESMF_FieldBundleGet(this%input_bundle,grid=gridIn,rc=status) @@ -714,8 +744,8 @@ subroutine RegridScalar(this,itemName,rc) !! print *, maxval(ptr2d) !! print *, minval(ptr2d) !! print *, maxval(outptr2d) -!! print *, minval(outptr2d) - +!! print *, minval(outptr2d) + else if (fieldRank==3) then if (.not.associated(ptr3d)) then if (hasDE_in) then @@ -914,7 +944,7 @@ subroutine RegridVector(this,xName,yName,rc) end subroutine RegridVector - + subroutine alphabatize_variables(this,nfixedVars,rc) class (sampler), intent(inout) :: this integer, intent(in) :: nFixedVars @@ -967,18 +997,14 @@ subroutine alphabatize_variables(this,nfixedVars,rc) end subroutine alphabatize_variables - + subroutine addVariable_to_acc_bundle(this,itemName,rc) class (sampler), intent(inout) :: this character(len=*), intent(in) :: itemName integer, optional, intent(out) :: rc type(ESMF_Field) :: field,newField - type(ESMF_Array) :: array1 - real(KIND=ESMF_KIND_R4), pointer :: pt2d(:,:) - class (AbstractGridFactory), pointer :: factory integer :: fieldRank - logical :: isPresent integer :: status call ESMF_FieldBundleGet(this%input_bundle,itemName,field=field,_RC) @@ -1001,9 +1027,7 @@ subroutine addVariable_to_output_bundle(this,itemName,rc) integer, optional, intent(out) :: rc type(ESMF_Field) :: field,newField - class (AbstractGridFactory), pointer :: factory integer :: fieldRank - logical :: isPresent integer :: status call ESMF_FieldBundleGet(this%input_bundle,itemName,field=field,_RC) @@ -1017,8 +1041,8 @@ subroutine addVariable_to_output_bundle(this,itemName,rc) _RETURN(_SUCCESS) end subroutine addVariable_to_output_bundle - - + + !! -- based on subroutine bundlepost(this,filename,oClients,rc) !! @@ -1033,23 +1057,20 @@ subroutine interp_accumulate_fields (this,xy_subset,rc) type(ESMF_Field) :: outField type(ESMF_Field) :: new_outField type(ESMF_Grid) :: grid - integer :: tindex - type(ArrayReference) :: ref type(GriddedIOitemVectorIterator) :: iter type(GriddedIOitem), pointer :: item - logical :: have_time type(ESMF_Array) :: array1, array2 integer :: is,ie,js,je - integer :: rank, rank1, rank2 + integer :: rank real(KIND=ESMF_KIND_R4), pointer :: pt2d(:,:), pt2d_(:,:) real(KIND=ESMF_KIND_R4), pointer :: pt3d(:,:,:), pt3d_(:,:,:) integer :: localDe, localDECount integer, dimension(:), allocatable :: LB, UB, exclusiveCount - integer, dimension(:), allocatable :: compLB, compUB, compCount + integer, dimension(:), allocatable :: compLB, compUB, compCount integer :: dimCount integer :: y1, y2 integer :: j, jj @@ -1059,16 +1080,21 @@ subroutine interp_accumulate_fields (this,xy_subset,rc) is=xy_subset(1,1); ie=xy_subset(2,1) js=xy_subset(1,2); je=xy_subset(2,2) + if (js > je) then + ! no valid points are found on swath grid for this time step + _RETURN(ESMF_SUCCESS) + end if + if (this%vdata%regrid_type==VERTICAL_METHOD_ETA2LEV) then call this%vdata%setup_eta_to_pressure(regrid_handle=this%regrid_handle,output_grid=this%output_grid,rc=status) _VERIFY(status) end if - + call ESMF_FieldBundleGet(this%output_bundle, grid=grid, _RC) call ESMF_GridGet(grid, localDECount=localDECount, dimCount=dimCount, _RC) allocate ( LB(dimCount), UB(dimCount), exclusiveCount(dimCount) ) - allocate ( compLB(dimCount), compUB(dimCount), compCount(dimCount) ) - + allocate ( compLB(dimCount), compUB(dimCount), compCount(dimCount) ) + allocate ( j1(0:localDEcount-1) ) ! start allocate ( j2(0:localDEcount-1) ) ! end @@ -1079,7 +1105,7 @@ subroutine interp_accumulate_fields (this,xy_subset,rc) LB(1)=ii1; LB(2)=jj1 UB(1)=iin; UB(2)=jjn - + do localDe=0, localDEcount-1 ! ! is/ie, js/je, [LB, UB] @@ -1114,7 +1140,7 @@ subroutine interp_accumulate_fields (this,xy_subset,rc) !! write(6,*) 'j1(localDe)', j1(0:localDeCount-1) !! write(6,*) 'j2(localDe)', j2(0:localDeCount-1) - + iter = this%items%begin() do while (iter /= this%items%end()) item => iter%get() @@ -1170,7 +1196,7 @@ subroutine interp_accumulate_fields (this,xy_subset,rc) end subroutine interp_accumulate_fields - + subroutine get_xy_mask(grid, xy_subset, xy_mask, rc) implicit none type(ESMF_Grid), intent(in) :: grid @@ -1180,12 +1206,10 @@ subroutine get_xy_mask(grid, xy_subset, xy_mask, rc) integer :: status integer :: ii1, iin, jj1, jjn ! local box for localDE - integer :: is, ie, js, je ! global box for each time-interval - integer :: j1p, jnp ! local y-index for each time-interval + integer :: is,ie, js, je ! global box for each time-interval - integer :: dimCount integer :: y1, y2 - integer :: j, jj + integer :: jj integer :: j1, j2 is=xy_subset(1,1); ie=xy_subset(2,1) @@ -1230,5 +1254,5 @@ subroutine get_xy_mask(grid, xy_subset, xy_mask, rc) end subroutine get_xy_mask - + end module MAPL_EpochSwathMod diff --git a/gridcomps/History/MAPL_HistoryGridComp.F90 b/gridcomps/History/MAPL_HistoryGridComp.F90 index a29439905bbd..a742d8654335 100644 --- a/gridcomps/History/MAPL_HistoryGridComp.F90 +++ b/gridcomps/History/MAPL_HistoryGridComp.F90 @@ -405,6 +405,7 @@ subroutine Initialize ( gc, import, dumexport, clock, rc ) ! variables for counting table integer :: nline, ncol + integer :: swath_count type(HistoryCollection) :: collection character(len=ESMF_MAXSTR) :: cFileOrder @@ -601,6 +602,7 @@ subroutine Initialize ( gc, import, dumexport, clock, rc ) call ESMF_ConfigNextLine ( config,tableEnd=tend,_RC ) enddo + swath_count = 0 iter = IntState%output_grids%begin() do while (iter /= IntState%output_grids%end()) key => iter%key() @@ -620,14 +622,25 @@ subroutine Initialize ( gc, import, dumexport, clock, rc ) if (trim(grid_type)/='Swath') then output_grid = grid_manager%make_grid(config, prefix=key//'.', _RC) else - Hsampler = samplerHQ(clock, config, key, _RC) + swath_count = swath_count + 1 + ! + ! Hsampler use the first config to setup epoch + ! + if (swath_count == 1) then + Hsampler = samplerHQ(clock, key, config, _RC) + end if + call Hsampler%config_accumulate(key, config, _RC) output_grid = Hsampler%create_grid(key, currTime, grid_type=grid_type, _RC) + if (mapl_am_i_root()) write(6,*) 'nail af Hsampler%create_grid' + + end if call IntState%output_grids%set(key, output_grid) call iter%next() end do end block OUTPUT_GRIDS end if + if (intstate%version >= 2) then call ESMF_ConfigFindLabel(config, 'FIELD_SETS:', _RC) table_end = .false. @@ -641,7 +654,7 @@ subroutine Initialize ( gc, import, dumexport, clock, rc ) end if call ESMF_ConfigNextLine ( config,tableEnd=table_end,_RC ) enddo - + field_set_iter = intState%field_sets%begin() do while (field_set_iter /= intState%field_sets%end()) key => field_set_iter%key() @@ -706,7 +719,7 @@ subroutine Initialize ( gc, import, dumexport, clock, rc ) if( MAPL_AM_I_ROOT(vm) ) then call regen_rcx_for_obs_platform (config, nlist, list, _RC) end if - + call ESMF_VMbarrier(vm, _RC) ! Initialize History Lists @@ -897,6 +910,7 @@ subroutine Initialize ( gc, import, dumexport, clock, rc ) endif endif + ! Handle "backwards" mode: this is hidden (i.e. not documented) feature ! Defaults to .false. call ESMF_ConfigGetAttribute ( cfg, reverse, default=0, & @@ -1635,6 +1649,9 @@ subroutine Initialize ( gc, import, dumexport, clock, rc ) else sec = MAPL_nsecf(list(n)%frequency) / 2 endif + if (index(trim(list(n)%output_grid_label), 'SwathGrid') > 0) then + call ESMF_TimeIntervalGet(Hsampler%Frequency_epoch, s=sec, _RC) + end if call ESMF_TimeIntervalSet( INTSTATE%STAMPOFFSET(n), S=sec, _RC ) end do @@ -2371,7 +2388,7 @@ subroutine Initialize ( gc, import, dumexport, clock, rc ) else list(n)%vdata = VerticalData(positive=list(n)%positive,_RC) end if - if (trim(list(n)%output_grid_label)=='SwathGrid') then + if (index(trim(list(n)%output_grid_label), 'SwathGrid') > 0) then call list(n)%xsampler%set_param(deflation=list(n)%deflate,_RC) call list(n)%xsampler%set_param(quantize_algorithm=list(n)%quantize_algorithm,_RC) call list(n)%xsampler%set_param(quantize_level=list(n)%quantize_level,_RC) @@ -2400,14 +2417,15 @@ subroutine Initialize ( gc, import, dumexport, clock, rc ) if (list(n)%timeseries_output) then list(n)%trajectory = HistoryTrajectory(cfg,string,clock,_RC) call list(n)%trajectory%initialize(items=list(n)%items,bundle=list(n)%bundle,timeinfo=list(n)%timeInfo,vdata=list(n)%vdata,_RC) + IntState%stampoffset(n) = list(n)%trajectory%epoch_frequency elseif (list(n)%sampler_spec == 'station') then list(n)%station_sampler = StationSampler (trim(list(n)%stationIdFile), nskip_line=list(n)%stationSkipLine, _RC) call list(n)%station_sampler%add_metadata_route_handle(list(n)%bundle,list(n)%timeInfo,vdata=list(n)%vdata,_RC) else global_attributes = list(n)%global_atts%define_collection_attributes(_RC) - if (trim(list(n)%output_grid_label)=='SwathGrid') then + if (index(trim(list(n)%output_grid_label), 'SwathGrid') > 0) then pgrid => IntState%output_grids%at(trim(list(n)%output_grid_label)) - call list(n)%xsampler%Create_bundle_RH(list(n)%items,list(n)%bundle,ogrid=pgrid,vdata=list(n)%vdata,global_attributes=global_attributes,_RC) + call list(n)%xsampler%Create_bundle_RH(list(n)%items,list(n)%bundle,Hsampler%tunit,ogrid=pgrid,vdata=list(n)%vdata,_RC) else if (trim(list(n)%output_grid_label)/='') then pgrid => IntState%output_grids%at(trim(list(n)%output_grid_label)) @@ -3371,7 +3389,7 @@ subroutine Run ( gc, import, export, clock, rc ) Writing(n) = .false. else if (list(n)%timeseries_output) then Writing(n) = ESMF_AlarmIsRinging ( list(n)%trajectory%alarm ) - else if (trim(list(n)%output_grid_label)=='SwathGrid') then + else if (index(trim(list(n)%output_grid_label), 'SwathGrid') > 0) then Writing(n) = ESMF_AlarmIsRinging ( Hsampler%alarm ) else Writing(n) = ESMF_AlarmIsRinging ( list(n)%his_alarm ) @@ -3419,13 +3437,12 @@ subroutine Run ( gc, import, export, clock, rc ) ! swath only epoch_swath_grid_case: do n=1,nlist - if (trim(list(n)%output_grid_label)=='SwathGrid') then + if (index(trim(list(n)%output_grid_label), 'SwathGrid') > 0) then call Hsampler%regrid_accumulate(list(n)%xsampler,_RC) if( ESMF_AlarmIsRinging ( Hsampler%alarm ) ) then create_mode = PFIO_NOCLOBBER ! defaut no overwrite if (intState%allow_overwrite) create_mode = PFIO_CLOBBER - ! add time to items ! true metadata comes here from mGriddedIO%metadata ! the mGriddedIO below only touches metadata, collection_id etc., it is safe. @@ -3437,7 +3454,7 @@ subroutine Run ( gc, import, export, clock, rc ) item%itemType = ItemTypeScalar item%xname = 'time' call list(n)%items%push_back(item) - call Hsampler%fill_time_in_bundle ('time', list(n)%xsampler%acc_bundle, _RC) + call Hsampler%fill_time_in_bundle ('time', list(n)%xsampler%acc_bundle, list(n)%xsampler%output_grid, _RC) call list(n)%mGriddedIO%destroy(_RC) call list(n)%mGriddedIO%CreateFileMetaData(list(n)%items,list(n)%xsampler%acc_bundle,timeinfo_uninit,vdata=list(n)%vdata,global_attributes=global_attributes,_RC) call list(n)%items%pop_back() @@ -3526,7 +3543,7 @@ subroutine Run ( gc, import, export, clock, rc ) inquire (file=trim(filename(n)),exist=file_exists) _ASSERT(.not.file_exists,trim(filename(n))//" being created for History output already exists") end if - if (trim(list(n)%output_grid_label)/='SwathGrid') then + if (index(trim(list(n)%output_grid_label), 'SwathGrid') == 0) then call list(n)%mGriddedIO%modifyTime(oClients=o_Clients,_RC) endif list(n)%currentFile = filename(n) @@ -3655,13 +3672,15 @@ subroutine Run ( gc, import, export, clock, rc ) ! destroy ogrid/RH/acc_bundle, regenerate them ! swath only epoch_swath_regen_grid: do n=1,nlist - if (trim(list(n)%output_grid_label)=='SwathGrid') then + if (index(trim(list(n)%output_grid_label), 'SwathGrid') > 0) then if( ESMF_AlarmIsRinging ( Hsampler%alarm ) ) then + key_grid_label = list(n)%output_grid_label call Hsampler%destroy_rh_regen_ogrid ( key_grid_label, IntState%output_grids, list(n)%xsampler, _RC ) + pgrid => IntState%output_grids%at(trim(list(n)%output_grid_label)) - call list(n)%xsampler%Create_bundle_RH(list(n)%items,list(n)%bundle,ogrid=pgrid,& - vdata=list(n)%vdata,global_attributes=global_attributes,_RC) + call list(n)%xsampler%Create_bundle_RH(list(n)%items,list(n)%bundle,Hsampler%tunit, & + ogrid=pgrid,vdata=list(n)%vdata,_RC) if( MAPL_AM_I_ROOT() ) write(6,'(//)') endif end if @@ -5240,10 +5259,11 @@ function get_acc_offset(current_time,ref_time,rc) result(acc_offset) end if _RETURN(_SUCCESS) end function - - + + ! __ read data to object: obs_platform ! __ for each collection: find union fields, write to collection.rcx + ! __ note: this subroutine is called by MPI root only ! subroutine regen_rcx_for_obs_platform (config, nlist, list, rc) use MAPL_scan_pattern_in_file @@ -5251,7 +5271,8 @@ subroutine regen_rcx_for_obs_platform (config, nlist, list, rc) ! ! Plan: !- read and write schema - !- extract union of field lines, print out to rc + !- extract union of field lines, print out to rc + integer, parameter :: ESMF_MAXSTR2 = 2*ESMF_MAXSTR type(ESMF_Config), intent(inout) :: config integer, intent(in) :: nlist type(HistoryCollection), pointer :: list(:) @@ -5259,21 +5280,21 @@ subroutine regen_rcx_for_obs_platform (config, nlist, list, rc) character(len=ESMF_MAXSTR) :: HIST_CF integer :: n, unitr, unitw - logical :: match, contLine, con3 + logical :: match, contLine, con integer :: status - character (len=ESMF_MAXSTR) :: fname character (len=ESMF_MAXSTR) :: marker - character (len=ESMF_MAXSTR) :: line, line2 character (len=ESMF_MAXSTR) :: string - character (len=ESMF_MAXSTR), allocatable :: str_piece(:) + character (len=ESMF_MAXSTR2) :: line, line2 + character (len=ESMF_MAXSTR2), allocatable :: str_piece(:) type(obs_platform), allocatable :: PLFS(:) type(obs_platform) :: p1 - integer :: k, i, j + integer :: k, i, j, m, i2 integer :: ios, ngeoval, count, nplf integer :: length_mx integer :: mxseg integer :: nseg + integer :: nseg_ub integer :: nfield, nplatform integer :: nentry_name logical :: obs_flag @@ -5283,12 +5304,11 @@ subroutine regen_rcx_for_obs_platform (config, nlist, list, rc) lgr => logging%get_logger('HISTORY.sampler') ! - ! -- note: work on HEAD node ! call ESMF_ConfigGetAttribute(config, value=HIST_CF, & label="HIST_CF:", default="HIST.rc", _RC ) unitr = GETFILE(HIST_CF, FORM='formatted', _RC) - + call scan_count_match_bgn (unitr, 'PLATFORM.', count, .false.) rewind(unitr) call lgr%debug('%a %i8','count PLATFORM.', count) @@ -5299,8 +5319,12 @@ subroutine regen_rcx_for_obs_platform (config, nlist, list, rc) nplf = count allocate (PLFS(nplf)) allocate (map(nplf)) - - ! __ s1. scan get platform name + nc_index/lat/lon/time + + ! __ global set for call split_string by space + length_mx = ESMF_MAXSTR2 + mxseg = 100 + + ! __ s1. scan get platform name + index_name_x var_name_lat/lon/time do k=1, count call scan_begin(unitr, 'PLATFORM.', .false.) backspace(unitr) @@ -5313,53 +5337,51 @@ subroutine regen_rcx_for_obs_platform (config, nlist, list, rc) call lgr%debug('%a %a', 'marker=', trim(marker)) call scan_contain(unitr, marker, .true.) - call scan_contain(unitr, 'index:', .false.) + call scan_contain(unitr, 'index_name_x:', .false.) backspace(unitr) read(unitr, '(a)') line i=index(line, ':') - PLFS(k)%nc_index = trim(line(i+1:)) + PLFS(k)%index_name_x = trim(line(i+1:)) call scan_contain(unitr, marker, .true.) - call scan_contain(unitr, 'longitude:', .false.) + call scan_contain(unitr, 'var_name_lon:', .false.) backspace(unitr) read(unitr, '(a)') line i=index(line, ':') - PLFS(k)%nc_lon = trim(line(i+1:)) - - call scan_contain(unitr, marker, .true.) - call scan_contain(unitr, 'latitude:', .false.) + PLFS(k)%var_name_lon = trim(line(i+1:)) + + call scan_contain(unitr, marker, .true.) + call scan_contain(unitr, 'var_name_lat:', .false.) backspace(unitr) read(unitr, '(a)') line i=index(line, ':') - PLFS(k)%nc_lat = trim(line(i+1:)) + PLFS(k)%var_name_lat = trim(line(i+1:)) - call scan_contain(unitr, marker, .true.) - call scan_contain(unitr, 'time:', .false.) + call scan_contain(unitr, marker, .true.) + call scan_contain(unitr, 'var_name_time:', .false.) backspace(unitr) read(unitr, '(a)') line i=index(line, ':') - PLFS(k)%nc_time = trim(line(i+1:)) + PLFS(k)%var_name_time = trim(line(i+1:)) - call scan_contain(unitr, marker, .true.) + call scan_contain(unitr, marker, .true.) call scan_contain(unitr, 'file_name_template:', .false.) backspace(unitr) read(unitr, '(a)') line i=index(line, ':') - PLFS(k)%file_name_template = trim(line(i+1:)) + PLFS(k)%file_name_template = trim(line(i+1:)) call lgr%debug('%a %a %a %a %a', & trim( PLFS(k)%name ), & - trim( PLFS(k)%nc_lon ), & - trim( PLFS(k)%nc_lat ), & - trim( PLFS(k)%nc_time ), & + trim( PLFS(k)%var_name_lon ), & + trim( PLFS(k)%var_name_lat ), & + trim( PLFS(k)%var_name_time ), & trim( PLFS(k)%file_name_template ) ) end do ! __ s2.1 scan fields: get ngeoval / nentry_name = nword - length_mx = ESMF_MAXSTR - mxseg = 10 allocate (str_piece(mxseg)) rewind(unitr) do k=1, count @@ -5369,27 +5391,29 @@ subroutine regen_rcx_for_obs_platform (config, nlist, list, rc) i=index(line, 'PLATFORM.') j=index(line, ':') marker=line(1:j) - call scan_begin(unitr, marker, .true.) + call scan_begin(unitr, marker, .true.) call scan_contain(unitr, 'geovals_fields:', .false.) ios=0 ngeoval=0 + nseg_ub=0 do while (ios == 0) read (unitr, '(A)' ) line - i=index(line, '::') - if (i==0) then + con = .not.(adjustl(trim(line))=='::') + if (con) then ngeoval = ngeoval + 1 call split_string_by_space (line, length_mx, mxseg, & nseg, str_piece, status) + nseg_ub = max(nseg_ub, nseg) else exit endif enddo PLFS(k)%ngeoval = ngeoval - PLFS(k)%nentry_name = nseg + PLFS(k)%nentry_name = nseg_ub !! call lgr%debug('%a %i','ngeoval=', ngeoval) - - allocate ( PLFS(k)%field_name (nseg, ngeoval) ) - nentry_name = nseg ! assume the same for each field_name + allocate ( PLFS(k)%field_name (nseg_ub, ngeoval) ) + PLFS(k)%field_name = '' +!! nentry_name = nseg_ub ! assume the same for each field_name end do @@ -5403,18 +5427,21 @@ subroutine regen_rcx_for_obs_platform (config, nlist, list, rc) j=index(line, ':') marker=line(1:j) ! - call scan_begin(unitr, marker, .true.) + call scan_begin(unitr, marker, .true.) call scan_contain(unitr, 'geovals_fields:', .false.) ios=0 ngeoval=0 do while (ios == 0) - read (unitr, '(A)' ) line - i=index(line, '::') - if (i==0) then + read (unitr, '(A)', iostat = ios) line + !! write(6,*) 'k in count, line', k, trim(line) + con = .not.(adjustl(trim(line))=='::') + if (con) then ngeoval = ngeoval + 1 call split_string_by_space (line, length_mx, mxseg, & nseg, str_piece, status) - PLFS(k)%field_name (1:nseg, ngeoval) = str_piece(1:nseg) + do m=1, nseg + PLFS(k)%field_name (m, ngeoval) = trim(str_piece(m)) + end do else exit endif @@ -5422,10 +5449,10 @@ subroutine regen_rcx_for_obs_platform (config, nlist, list, rc) end do deallocate(str_piece) rewind(unitr) - + !!do k=1, nplf !! do i=1, ngeoval - !! write(6,*) 'PLFS(k)%field_name (1:nseg, ngeoval)=', PLFS(k)%field_name (1:nseg,i) + !! write(6,*) 'PLFS(k)%field_name (1:nseg, ngeoval)=', PLFS(k)%field_name (1:nseg,1) !! enddo !!enddo !!write(6,*) 'nlist=', nlist @@ -5455,52 +5482,56 @@ subroutine regen_rcx_for_obs_platform (config, nlist, list, rc) if (contLine) then if (adjustl(line) == '::') contLine = .false. end if - if ( index(line, trim(string)//'ObsPlatforms:') > 0 ) then + if ( index(adjustl(line), trim(string)//'ObsPlatforms:') == 1 ) then obs_flag =.true. line2 = line + write(6,*) 'first line for ObsPlatforms:=', trim(line) + endif end do 1236 continue if (obs_flag) then - ! __ write common nc_index,time,lon,lat - k=1 ! plat form # 1 - write(unitw, '(2(2x,a))') trim(string)//'nc_Index: ', trim(adjustl(PLFS(k)%nc_index)) - write(unitw, '(2(2x,a))') trim(string)//'nc_Time: ', trim(adjustl(PLFS(k)%nc_time)) - write(unitw, '(2(2x,a))') trim(string)//'nc_Longitude:', trim(adjustl(PLFS(k)%nc_lon)) - write(unitw, '(2(2x,a))') trim(string)//'nc_Latitude: ', trim(adjustl(PLFS(k)%nc_lat)) - write(unitw, '(/)') - - length_mx = ESMF_MAXSTR - mxseg = 100 allocate (str_piece(mxseg)) i = index(line2, ':') line = adjustl ( line2(i+1:) ) + write(6,*) 'line for obsplatforms=', trim(line) call split_string_by_space (line, length_mx, mxseg, & - nplatform, str_piece, status) -! write(6,*) 'nplatform=', nplatform -! write(6,*) 'str_piece=', str_piece(1:nplatform) -! do j=1, nplf -! write(6,*) 'PLFS(j)%name=', trim( PLFS(j)%name ) -! enddo + nplatform, str_piece, status) + + + write(6,*) 'split string, nplatform=', nplatform + write(6,*) 'nplf=', nplf + !!write(6,*) 'str_piece=', str_piece(1:nplatform) + !!do j=1, nplf + !! write(6,*) 'PLFS(j)%name=', trim( PLFS(j)%name ) + !!enddo + ! ! a) union the platform ! - ! ! find the index for each str_piece map(:) = -1 - do i=1, nplatform ! loc collection + do i=1, nplatform ! for loc collection do j=1, nplf ! tot if ( trim(str_piece(i)) == trim( PLFS(j)%name ) ) then map(i)=j + exit end if end do end do deallocate(str_piece) + !! write(6,*) 'collection n=',n, 'map(:)=', map(:) + + ! __ write common nc_index,time,lon,lat + k=map(1) ! plat form # 1 + write(unitw, '(2(2x,a))') trim(string)//'index_name_x: ', trim(adjustl(PLFS(k)%index_name_x)) + write(unitw, '(2(2x,a))') trim(string)//'var_name_time: ', trim(adjustl(PLFS(k)%var_name_time)) + write(unitw, '(2(2x,a))') trim(string)//'var_name_lon: ', trim(adjustl(PLFS(k)%var_name_lon)) + write(unitw, '(2(2x,a))') trim(string)//'var_name_lat: ', trim(adjustl(PLFS(k)%var_name_lat)) - !!write(6,*) 'map(:)=', map(:) do i=1, nplatform k=map(i) if (i==1) then @@ -5520,13 +5551,16 @@ subroutine regen_rcx_for_obs_platform (config, nlist, list, rc) if (j==1) then write(unitw, '(10(2x,a))') trim(string)//'fields:', trim(line) else - write(unitw, '(12x,a)') trim(line) + write(unitw, '(12x,a)') trim(line) end if end do write(unitw,'(a,/)') '::' - write(unitw,'(a)') 'geovals.obs_files: # table start from next line' + write(unitw,'(a)') trim(string)//'obs_files: # table start from next line' + - do k=1, nplatform + write(6,*) 'nplatform', nplatform + do i2=1, nplatform + k=map(i2) write(unitw, '(a)') trim(adjustl(PLFS(k)%file_name_template)) do j=1, PLFS(k)%ngeoval line='' @@ -5543,7 +5577,8 @@ subroutine regen_rcx_for_obs_platform (config, nlist, list, rc) end do call free_file(unitr, _RC) + _RETURN(ESMF_SUCCESS) end subroutine regen_rcx_for_obs_platform - + end module MAPL_HistoryGridCompMod diff --git a/gridcomps/History/MAPL_HistoryTrajectoryMod.F90 b/gridcomps/History/MAPL_HistoryTrajectoryMod.F90 index 34aa412ef6c1..7e339282c866 100644 --- a/gridcomps/History/MAPL_HistoryTrajectoryMod.F90 +++ b/gridcomps/History/MAPL_HistoryTrajectoryMod.F90 @@ -40,16 +40,21 @@ module HistoryTrajectoryMod type(ESMF_Clock) :: clock type(ESMF_Alarm), public :: alarm type(ESMF_Time) :: RingTime - type(ESMF_TimeInterval) :: epoch_frequency + type(ESMF_TimeInterval), public :: epoch_frequency integer :: nobs_type - character(len=ESMF_MAXSTR) :: nc_index - character(len=ESMF_MAXSTR) :: nc_time - character(len=ESMF_MAXSTR) :: nc_latitude - character(len=ESMF_MAXSTR) :: nc_longitude +! character(len=ESMF_MAXSTR) :: nc_index +! character(len=ESMF_MAXSTR) :: nc_time +! character(len=ESMF_MAXSTR) :: nc_latitude +! character(len=ESMF_MAXSTR) :: nc_longitude + + character(len=ESMF_MAXSTR) :: index_name_x character(len=ESMF_MAXSTR) :: var_name_time character(len=ESMF_MAXSTR) :: var_name_lat character(len=ESMF_MAXSTR) :: var_name_lon + character(len=ESMF_MAXSTR) :: var_name_time_full + character(len=ESMF_MAXSTR) :: var_name_lat_full + character(len=ESMF_MAXSTR) :: var_name_lon_full character(len=ESMF_MAXSTR) :: datetime_units integer :: epoch ! unit: second integer(kind=ESMF_KIND_I8) :: epoch_index(2) @@ -61,7 +66,7 @@ module HistoryTrajectoryMod type(ESMF_TimeInterval) :: obsfile_interval integer :: obsfile_Ts_index ! for epoch integer :: obsfile_Te_index - logical :: is_valid + logical :: active contains procedure :: initialize procedure :: create_variable => create_metadata_variable diff --git a/gridcomps/History/MAPL_HistoryTrajectoryMod_smod.F90 b/gridcomps/History/MAPL_HistoryTrajectoryMod_smod.F90 index 1f13c1b6a3d0..c7126111330c 100644 --- a/gridcomps/History/MAPL_HistoryTrajectoryMod_smod.F90 +++ b/gridcomps/History/MAPL_HistoryTrajectoryMod_smod.F90 @@ -38,8 +38,8 @@ character(len=ESMF_MAXSTR) :: symd, shms integer :: nline, col integer, allocatable :: ncol(:) - character(len=ESMF_MAXSTR), allocatable :: word(:) - integer :: nobs, head, jvar + character(len=ESMF_MAXSTR), allocatable :: word(:) + integer :: nobs, head, jvar logical :: tend integer :: i, j, k, M integer :: count @@ -58,15 +58,14 @@ traj%alarm = ESMF_AlarmCreate( clock=clock, RingInterval=epoch_frequency, & RingTime=traj%RingTime, sticky=.false., _RC ) - call ESMF_ConfigGetAttribute(config, value=traj%nc_index, default="", & - label=trim(string) // 'nc_Index:', _RC) - call ESMF_ConfigGetAttribute(config, value=traj%nc_time, default="", & - label=trim(string) // 'nc_Time:', _RC) - call ESMF_ConfigGetAttribute(config, value=traj%nc_longitude, default="", & - label=trim(string) // 'nc_Longitude:', _RC) - call ESMF_ConfigGetAttribute(config, value=traj%nc_latitude, default="", & - label=trim(string) // 'nc_Latitude:', _RC) - + call ESMF_ConfigGetAttribute(config, value=traj%index_name_x, default="", & + label=trim(string) // 'index_name_x:', _RC) + call ESMF_ConfigGetAttribute(config, value=traj%var_name_lon_full, default="", & + label=trim(string) // 'var_name_lon:', _RC) + call ESMF_ConfigGetAttribute(config, value=traj%var_name_lat_full, default="", & + label=trim(string) // 'var_name_lat:', _RC) + call ESMF_ConfigGetAttribute(config, value=traj%var_name_time_full, default="", & + label=trim(string) // 'var_name_time:', _RC) call ESMF_ConfigGetAttribute(config, value=STR1, default="", & label=trim(string) // 'obs_file_begin:', _RC) @@ -114,7 +113,7 @@ shms=trim(STR1) endif call convert_twostring_2_esmfinterval (symd, shms, traj%obsfile_interval, _RC) - traj%is_valid = .true. + traj%active = .true. ! __ s1. overall print @@ -130,7 +129,7 @@ !!write(6,*) 'line', i, 'ncol(i)', ncol(i) enddo - + ! __ s2. find nobs && distinguish design with vs wo '------' nobs=0 call ESMF_ConfigFindLabel( config, trim(string)//'obs_files:', _RC) @@ -141,11 +140,12 @@ enddo ! __ s3. retrieve template and geoval, set metadata file_handle - lgr => logging%get_logger('HISTORY.sampler') + lgr => logging%get_logger('HISTORY.sampler') if ( nobs == 0 ) then ! ! treatment-1: ! + _FAIL('this setting in HISTORY.rc obs_files: is not supported, stop') traj%nobs_type = nline ! here .rc format cannot have empty spaces allocate (traj%obs(nline)) call ESMF_ConfigFindLabel( config, trim(string)//'obs_files:', _RC) @@ -160,13 +160,12 @@ ! treatment-2: ! traj%nobs_type = nobs - allocate (traj%obs(nobs)) + allocate (traj%obs(nobs)) ! nobs=0 ! reuse counter head=1 jvar=0 - ! ! count '------' in history.rc as special markers for ngeoval ! @@ -187,9 +186,9 @@ ! 1-item case: file template or one-var ! 2-item : var1 , 'root' case STR1=trim(word(1)) - else - ! 3-item : var1 , 'root', var1_alias case - STR1=trim(word(M)) + else + ! 3-item : var1 , 'root', var1_alias case + STR1=trim(word(M)) end if deallocate(word) if ( index(trim(STR1), '-----') == 0 ) then @@ -218,7 +217,7 @@ allocate (traj%obs(k)%file_handle) end if end do - + call lgr%debug('%a %i8', 'nobs_type=', traj%nobs_type) do i=1, traj%nobs_type call lgr%debug('%a %i4 %a %a', 'obs(', i, ') input_template =', & @@ -228,14 +227,14 @@ _ASSERT(j>0, '% is not found, template is wrong') traj%obs(i)%name = traj%obs(i)%input_template(k+1:j-1) end do - + _RETURN(_SUCCESS) 105 format (1x,a,2x,a) 106 format (1x,a,2x,i8) end procedure HistoryTrajectory_from_config - + ! !-- integrate both initialize and reinitialize ! @@ -251,7 +250,7 @@ if (.not. present(reinitialize)) then if(present(bundle)) this%bundle=bundle if(present(items)) this%items=items - if(present(timeInfo)) this%time_info=timeInfo + if(present(timeInfo)) this%time_info=timeInfo if (present(vdata)) then this%vdata=vdata else @@ -267,7 +266,7 @@ end do end if end if - + do k=1, this%nobs_type call this%vdata%append_vertical_metadata(this%obs(k)%metadata,this%bundle,_RC) end do @@ -278,7 +277,7 @@ call get_obsfile_Tbracket_from_epoch(currTime, & this%obsfile_start_time, this%obsfile_end_time, & this%obsfile_interval, this%epoch_frequency, & - this%obsfile_Ts_index, this%obsfile_Te_index, _RC) + this%obsfile_Ts_index, this%obsfile_Te_index, _RC) if (this%obsfile_Te_index < 0) then if (mapl_am_I_root()) then write(6,*) "model start time is earlier than obsfile_start_time" @@ -295,22 +294,22 @@ do k=1, this%nobs_type - call this%obs(k)%metadata%add_dimension(this%nc_index, this%obs(k)%nobs_epoch) + call this%obs(k)%metadata%add_dimension(this%index_name_x, this%obs(k)%nobs_epoch) if (this%time_info%integer_time) then - v = Variable(type=PFIO_INT32,dimensions=this%nc_index) + v = Variable(type=PFIO_INT32,dimensions=this%index_name_x) else - v = Variable(type=PFIO_REAL32,dimensions=this%nc_index) + v = Variable(type=PFIO_REAL32,dimensions=this%index_name_x) end if call v%add_attribute('units', this%datetime_units) call v%add_attribute('long_name', 'dateTime') call this%obs(k)%metadata%add_variable(this%var_name_time,v) - v = variable(type=PFIO_REAL64,dimensions=this%nc_index) + v = variable(type=PFIO_REAL64,dimensions=this%index_name_x) call v%add_attribute('units','degrees_east') call v%add_attribute('long_name','longitude') call this%obs(k)%metadata%add_variable(this%var_name_lon,v) - v = variable(type=PFIO_REAL64,dimensions=this%nc_index) + v = variable(type=PFIO_REAL64,dimensions=this%index_name_x) call v%add_attribute('units','degrees_north') call v%add_attribute('long_name','latitude') call this%obs(k)%metadata%add_variable(this%var_name_lat,v) @@ -358,9 +357,9 @@ units = 'unknown' endif if (field_rank==2) then - vdims = this%nc_index + vdims = this%index_name_x else if (field_rank==3) then - vdims = trim(this%nc_index)//",lev" + vdims = trim(this%index_name_x)//",lev" end if v = variable(type=PFIO_REAL32,dimensions=trim(vdims)) call v%add_attribute('units',trim(units)) @@ -409,7 +408,7 @@ end if call MAPL_FieldBundleAdd(new_bundle,dst_field,_RC) else if (item%itemType == ItemTypeVector) then - _FAIL("ItemTypeVector not yet supported") +!! _FAIL("ItemTypeVector not yet supported") end if call iter%next() enddo @@ -419,24 +418,33 @@ module procedure create_file_handle + use pflogger, only : Logger, logging integer :: status integer :: k character(len=ESMF_MAXSTR) :: filename + type(Logger), pointer :: lgr - if (.NOT. this%is_valid) then + if (.NOT. this%active) then _RETURN(ESMF_SUCCESS) endif + if (this%nobs_epoch_sum==0) then + rc=0 + return + endif + + lgr => logging%get_logger('HISTORY.sampler') do k=1, this%nobs_type - call this%obs(k)%metadata%modify_dimension(this%nc_index, this%obs(k)%nobs_epoch) + call this%obs(k)%metadata%modify_dimension(this%index_name_x, this%obs(k)%nobs_epoch) enddo if (mapl_am_I_root()) then do k=1, this%nobs_type if (this%obs(k)%nobs_epoch > 0) then filename=trim(this%obs(k)%name)//trim(filename_suffix) + call lgr%debug('%a %a', & + "Sampling to new file : ",trim(filename)) call this%obs(k)%file_handle%create(trim(filename),_RC) call this%obs(k)%file_handle%write(this%obs(k)%metadata,_RC) - write(6,*) "Sampling to new file : ",trim(filename) end if enddo end if @@ -449,10 +457,15 @@ integer :: status integer :: k - if (.NOT. this%is_valid) then + if (.NOT. this%active) then _RETURN(ESMF_SUCCESS) endif + if (this%nobs_epoch_sum==0) then + rc=0 + return + endif + if (mapl_am_I_root()) then do k=1, this%nobs_type if (this%obs(k)%nobs_epoch > 0) then @@ -475,6 +488,7 @@ character(len=ESMF_MAXSTR) :: grp_name character(len=ESMF_MAXSTR) :: timeunits_file + character :: new_char(ESMF_MAXSTR) real(kind=REAL64), allocatable :: lons_full(:), lats_full(:) real(kind=REAL64), allocatable :: times_R8_full(:) @@ -489,7 +503,7 @@ type(ESMF_VM) :: vm integer :: mypet, petcount - integer :: i, j, k, L + integer :: i, j, k, L, ii, jj integer :: fid_s, fid_e integer(kind=ESMF_KIND_I8) :: j0, j1 integer(kind=ESMF_KIND_I8) :: jt1, jt2 @@ -500,117 +514,182 @@ integer :: sec integer, allocatable :: ix(:) ! counter for each obs(k)%nobs_epoch integer :: nx2 + logical :: EX ! file + logical :: zero_obs - - this%datetime_units = "seconds since 1970-01-01 00:00:00" +!! this%datetime_units = "seconds since 1970-01-01 00:00:00" lgr => logging%get_logger('HISTORY.sampler') call ESMF_VMGetGlobal(vm,_RC) call ESMF_VMGet(vm, localPet=mypet, petCount=petCount, _RC) - if (this%nc_index == '') then + if (this%index_name_x == '') then ! - !-- non IODA case + !-- non IODA case / non netCDF ! _FAIL('non-IODA format is not implemented here') + end if + + ! + !-- IODA case + ! + i=index(this%var_name_lon_full, '/') + if (i==0) then + grp_name = '' + call lgr%debug('%a', 'grp_name not found') else - ! - !-- IODA case - ! - i=index(this%nc_longitude, '/') - _ASSERT (i>0, 'group name not found') - grp_name = this%nc_longitude(1:i-1) - this%var_name_lon = this%nc_longitude(i+1:) - i=index(this%nc_latitude, '/') - this%var_name_lat = this%nc_latitude(i+1:) - i=index(this%nc_time, '/') - this%var_name_time= this%nc_time(i+1:) - - call lgr%debug('%a', 'grp_name,this%var_name_lat,this%var_name_lon,this%var_name_time') - call lgr%debug('%a %a %a %a', & - trim(grp_name),trim(this%var_name_lat),trim(this%var_name_lon),trim(this%var_name_time)) - - L=0 - fid_s=this%obsfile_Ts_index - fid_e=this%obsfile_Te_index - if(fid_e < L) then - allocate(this%lons(0),this%lats(0),_STAT) - allocate(this%times_R8(0),_STAT) - allocate(this%obstype_id(0),_STAT) - this%epoch_index(1:2) = 0 - this%nobs_epoch = 0 - rc = 0 - return - end if + grp_name = this%var_name_lon_full(1:i-1) + end if + this%var_name_lon = this%var_name_lon_full(i+1:) + i=index(this%var_name_lat_full, '/') + this%var_name_lat = this%var_name_lat_full(i+1:) + i=index(this%var_name_time_full, '/') + this%var_name_time= this%var_name_time_full(i+1:) - if (mapl_am_I_root()) then - len = 0 - do k=1, this%nobs_type - j = max (fid_s, L) - do while (j<=fid_e) - filename = get_filename_from_template_use_index( & - this%obsfile_start_time, this%obsfile_interval, & - j, this%obs(k)%input_template, _RC) - if (filename /= '') then - call lgr%debug('%a %a', 'true filename: ', trim(filename)) - call get_ncfile_dimension(filename, tdim=num_times, key_time=this%nc_index, _RC) - len = len + num_times - end if - j=j+1 - enddo + call lgr%debug('%a', 'grp_name,this%index_name_x,this%var_name_lon,this%var_name_lat,this%var_name_time') + call lgr%debug('%a %a %a %a %a', & + trim(grp_name),trim(this%index_name_x),trim(this%var_name_lon),& + trim(this%var_name_lat),trim(this%var_name_time)) + + L=0 + fid_s=this%obsfile_Ts_index + fid_e=this%obsfile_Te_index + + call lgr%debug('%a %i10 %i10', & + 'fid_s, fid_e', fid_s, fid_e) + + arr(1)=0 ! len_full + if (mapl_am_I_root()) then + len = 0 + do k=1, this%nobs_type + j = max (fid_s, L) + do while (j<=fid_e) + filename = get_filename_from_template_use_index( & + this%obsfile_start_time, this%obsfile_interval, & + j, this%obs(k)%input_template, EX, _RC) + if (EX) then + call lgr%debug('%a %i10', 'exist: filename fid j :', j) + call lgr%debug('%a %a', 'exist: true filename :', trim(filename)) + call get_ncfile_dimension(filename, tdim=num_times, key_time=this%index_name_x, _RC) + len = len + num_times + else + call lgr%debug('%a %i10', 'non-exist: filename fid j :', j) + call lgr%debug('%a %a', 'non-exist: missing filename:', trim(filename)) + end if + j=j+1 enddo - len_full = len + enddo + arr(1)=len + + if (len>0) then allocate(lons_full(len),lats_full(len),_STAT) allocate(times_R8_full(len),_STAT) allocate(obstype_id_full(len),_STAT) - call lgr%debug('%a %i12', 'nobs from input file:', len_full) - + call lgr%debug('%a %i12', 'nobs from input file:', len) len = 0 + ii = 0 do k=1, this%nobs_type j = max (fid_s, L) do while (j<=fid_e) filename = get_filename_from_template_use_index( & this%obsfile_start_time, this%obsfile_interval, & - j, this%obs(k)%input_template, _RC) - if (filename /= '') then - call get_ncfile_dimension(trim(filename), tdim=num_times, key_time=this%nc_index, _RC) + j, this%obs(k)%input_template, EX, _RC) + if (EX) then + ii = ii + 1 + call get_ncfile_dimension(trim(filename), tdim=num_times, key_time=this%index_name_x, _RC) call get_v1d_netcdf_R8 (filename, this%var_name_lon, lons_full(len+1:), num_times, group_name=grp_name) call get_v1d_netcdf_R8 (filename, this%var_name_lat, lats_full(len+1:), num_times, group_name=grp_name) call get_v1d_netcdf_R8 (filename, this%var_name_time, times_R8_full(len+1:), num_times, group_name=grp_name) - call get_attribute_from_group (filename, grp_name, this%var_name_time, "units", timeunits_file) + if (ii == 1) then + this%datetime_units = trim(timeunits_file) + call lgr%debug('%a %a', 'datetime_units from 1st file:', trim(timeunits_file)) + end if obstype_id_full(len+1:len+num_times) = k - call lgr%debug('%a %f25.12, %f25.12', 'times_R8_full(1:200:100)', & - times_R8_full(1), times_R8_full(200)) - + !!write(6,'(f12.2)') times_R8_full(::50) len = len + num_times end if j=j+1 enddo enddo end if + end if + + call ESMF_VMAllFullReduce(vm, sendData=arr, recvData=nx_sum, & + count=1, reduceflag=ESMF_REDUCE_SUM, rc=rc) + if (nx_sum == 0) then + allocate(this%lons(0),this%lats(0),_STAT) + allocate(this%times_R8(0),_STAT) + allocate(this%obstype_id(0),_STAT) + this%epoch_index(1:2) = 0 + this%nobs_epoch = 0 + this%nobs_epoch_sum = 0 + ! + ! empty shell to keep regridding and destroy_RH_LS to work + ! + this%locstream_factory = LocStreamFactory(this%lons,this%lats,_RC) + this%LS_rt = this%locstream_factory%create_locstream(_RC) + call ESMF_FieldBundleGet(this%bundle,grid=grid,_RC) + this%LS_ds = this%locstream_factory%create_locstream(grid=grid,_RC) + this%fieldB = ESMF_FieldCreate (this%LS_ds, name='B_time', typekind=ESMF_TYPEKIND_R8, _RC) + call ESMF_FieldGet( this%fieldB, localDE=0, farrayPtr=this%obsTime) + this%obsTime= -1.d0 + call lgr%debug('%a %i5', 'nobservation points=', nx_sum) + rc = 0 + return + end if + call MAPL_CommsBcast(vm, this%datetime_units, N=ESMF_MAXSTR, ROOT=MAPL_Root, _RC) - if (mapl_am_I_root()) then - call sort_multi_arrays_by_time(lons_full, lats_full, times_R8_full, obstype_id_full, _RC) - call ESMF_ClockGet(this%clock,currTime=current_time,_RC) - timeset(1) = current_time - timeset(2) = current_time + this%epoch_frequency - call time_esmf_2_nc_int (timeset(1), this%datetime_units, j0, _RC) - sec = hms_2_s(this%Epoch) - j1 = j0 + int(sec, kind=ESMF_KIND_I8) - jx0 = real ( j0, kind=ESMF_KIND_R8) - jx1 = real ( j1, kind=ESMF_KIND_R8) - - nstart=1; nend=size(times_R8_full) - call bisect( times_R8_full, jx0, jt1, n_LB=int(nstart, ESMF_KIND_I8), n_UB=int(nend, ESMF_KIND_I8), rc=rc) - call bisect( times_R8_full, jx1, jt2, n_LB=int(nstart, ESMF_KIND_I8), n_UB=int(nend, ESMF_KIND_I8), rc=rc) - if (jt1==jt2) then - _FAIL('Epoch Time is too small, empty swath grid is generated, increase Epoch') - endif - call lgr%debug ('%a %f20.1 %f20.1', 'jx0, jx1', jx0, jx1) - call lgr%debug ('%a %i20 %i20', 'jt1, jt2', jt1, jt2) + if (mapl_am_I_root()) then + call sort_multi_arrays_by_time(lons_full, lats_full, times_R8_full, obstype_id_full, _RC) + call ESMF_ClockGet(this%clock,currTime=current_time,_RC) + timeset(1) = current_time + timeset(2) = current_time + this%epoch_frequency + call time_esmf_2_nc_int (timeset(1), this%datetime_units, j0, _RC) + sec = hms_2_s(this%Epoch) + j1 = j0 + int(sec, kind=ESMF_KIND_I8) + jx0 = real ( j0, kind=ESMF_KIND_R8) + jx1 = real ( j1, kind=ESMF_KIND_R8) + + nstart=1; nend=size(times_R8_full) + call bisect( times_R8_full, jx0, jt1, n_LB=int(nstart, ESMF_KIND_I8), n_UB=int(nend, ESMF_KIND_I8), rc=rc) + call bisect( times_R8_full, jx1, jt2, n_LB=int(nstart, ESMF_KIND_I8), n_UB=int(nend, ESMF_KIND_I8), rc=rc) + call lgr%debug ('%a %i20 %i20', 'nstart, nend', nstart, nend) + call lgr%debug ('%a %f20.1 %f20.1', 'j0[currT] j1[T+Epoch] w.r.t. timeunit ', jx0, jx1) + call lgr%debug ('%a %f20.1 %f20.1', 'x0[times(1)] xn[times(N)] w.r.t. timeunit ', & + times_R8_full(1), times_R8_full(nend)) + call lgr%debug ('%a %i20 %i20', 'jt1, jt2 [final intercepted position]', jt1, jt2) + + +! if (jt1==jt2) then +! _FAIL('Epoch Time is too small, empty grid is generated, increase Epoch') +! endif + + !-- shift the zero item to index 1 + zero_obs = .false. + if (jt1/=jt2) then + zero_obs = .false. + if (jt1==0) jt1=1 + else + ! at most one obs point exist, set it .true. + zero_obs = .true. + !! if (jt1==0) jt1=1 + end if + + ! + !-- exclude the out-of-range case + ! + if ( zero_obs ) then + allocate(this%lons(0),this%lats(0),_STAT) + allocate(this%times_R8(0),_STAT) + allocate(this%obstype_id(0),_STAT) + this%epoch_index(1:2)=0 + this%nobs_epoch = 0 + nx=0 + arr(1)=nx + else ! (x1, x2] design in bisect if (jt1==0) then this%epoch_index(1)= 1 @@ -626,6 +705,8 @@ nx= this%epoch_index(2) - this%epoch_index(1) + 1 this%nobs_epoch = nx + + allocate(this%lons(nx),this%lats(nx),_STAT) allocate(this%times_R8(nx),_STAT) allocate(this%obstype_id(nx),_STAT) @@ -679,47 +760,46 @@ call lgr%debug('%a %i4 %a %i12', & 'obs(', k, ')%nobs_epoch', this%obs(k)%nobs_epoch ) enddo + end if + else + allocate(this%lons(0),this%lats(0),_STAT) + allocate(this%times_R8(0),_STAT) + allocate(this%obstype_id(0),_STAT) + this%epoch_index(1:2)=0 + this%nobs_epoch = 0 + nx=0 + arr(1)=nx + endif - else - allocate(this%lons(0),this%lats(0),_STAT) - allocate(this%times_R8(0),_STAT) - allocate(this%obstype_id(0),_STAT) - this%epoch_index(1:2)=0 - this%nobs_epoch = 0 - nx=0 - arr(1)=nx - endif - - call ESMF_VMAllFullReduce(vm, sendData=arr, recvData=nx_sum, & - count=1, reduceflag=ESMF_REDUCE_SUM, rc=rc) - this%nobs_epoch_sum = nx_sum - if (mapl_am_I_root()) write(6,*) 'nobs in Epoch :', nx_sum + call ESMF_VMAllFullReduce(vm, sendData=arr, recvData=nx_sum, & + count=1, reduceflag=ESMF_REDUCE_SUM, rc=rc) + this%nobs_epoch_sum = nx_sum + if (mapl_am_I_root()) write(6,'(2x,a,2x,i15)') 'nobs in Epoch :', nx_sum - this%locstream_factory = LocStreamFactory(this%lons,this%lats,_RC) - this%LS_rt = this%locstream_factory%create_locstream(_RC) - call ESMF_FieldBundleGet(this%bundle,grid=grid,_RC) - this%LS_ds = this%locstream_factory%create_locstream(grid=grid,_RC) + this%locstream_factory = LocStreamFactory(this%lons,this%lats,_RC) + this%LS_rt = this%locstream_factory%create_locstream(_RC) + call ESMF_FieldBundleGet(this%bundle,grid=grid,_RC) + this%LS_ds = this%locstream_factory%create_locstream(grid=grid,_RC) - this%fieldA = ESMF_FieldCreate (this%LS_rt, name='A_time', typekind=ESMF_TYPEKIND_R8, _RC) - this%fieldB = ESMF_FieldCreate (this%LS_ds, name='B_time', typekind=ESMF_TYPEKIND_R8, _RC) + this%fieldA = ESMF_FieldCreate (this%LS_rt, name='A_time', typekind=ESMF_TYPEKIND_R8, _RC) + this%fieldB = ESMF_FieldCreate (this%LS_ds, name='B_time', typekind=ESMF_TYPEKIND_R8, _RC) - call ESMF_FieldGet( this%fieldA, localDE=0, farrayPtr=ptAT) - call ESMF_FieldGet( this%fieldB, localDE=0, farrayPtr=this%obsTime) - if (mypet == 0) then - ptAT(:) = this%times_R8(:) - end if - this%obsTime= -1.d0 + call ESMF_FieldGet( this%fieldA, localDE=0, farrayPtr=ptAT) + call ESMF_FieldGet( this%fieldB, localDE=0, farrayPtr=this%obsTime) + if (mypet == 0) then + ptAT(:) = this%times_R8(:) + end if + this%obsTime= -1.d0 - call ESMF_FieldRedistStore (this%fieldA, this%fieldB, RH, _RC) - call ESMF_FieldRedist (this%fieldA, this%fieldB, RH, _RC) + call ESMF_FieldRedistStore (this%fieldA, this%fieldB, RH, _RC) + call ESMF_FieldRedist (this%fieldA, this%fieldB, RH, _RC) - !!write(6,'(2x,a,i5,2x,10E20.11)') 'pet=', mypet, this%obsTime(1:10) + !!write(6,'(2x,a,i5,2x,10E20.11)') 'pet=', mypet, this%obsTime(1:10) - call ESMF_FieldRedistRelease(RH, noGarbage=.true., _RC) - call ESMF_FieldDestroy(this%fieldA,nogarbage=.true.,_RC) - ! defer destroy fieldB at regen_grid step - ! - end if + call ESMF_FieldRedistRelease(RH, noGarbage=.true., _RC) + call ESMF_FieldDestroy(this%fieldA,nogarbage=.true.,_RC) + ! defer destroy fieldB at regen_grid step + ! _RETURN(_SUCCESS) @@ -746,7 +826,7 @@ integer :: j, k, ig integer, allocatable :: ix(:) - if (.NOT. this%is_valid) then + if (.NOT. this%active) then _RETURN(ESMF_SUCCESS) endif @@ -835,6 +915,9 @@ enddo endif enddo + do k=1, this%nobs_type + deallocate (this%obs(k)%p2d) + enddo end if else if (rank==2) then call ESMF_FieldGet( acc_field, localDE=0, farrayPtr=p_acc_3d, _RC) @@ -878,7 +961,7 @@ nx = this%obs(k)%nobs_epoch if (nx>0) then do ig = 1, this%obs(k)%ngeoval - if (trim(item%xname) == trim(this%obs(k)%geoval_name(ig))) then + if (trim(item%xname) == trim(this%obs(k)%geoval_name(ig))) then call this%obs(k)%file_handle%put_var(trim(item%xname), this%obs(k)%p3d(:,:), & start=[is,1],count=[nx,size(p_acc_rt_3d,2)]) end if @@ -889,6 +972,10 @@ !!write(6,*) 'here in append_file: put_var 3d' !!call this%obs(k)%file_handle%put_var(trim(item%xname),p_acc_rt_3d(:,:),& !! start=[is,1],count=[nx,size(p_acc_rt_3d,2)]) + !! + do k=1, this%nobs_type + deallocate (this%obs(k)%p3d) + enddo end if endif else if (item%itemType == ItemTypeVector) then @@ -919,10 +1006,18 @@ real(kind=REAL32), pointer :: p_src_3d(:,:,:),p_src_2d(:,:) real(kind=REAL32), pointer :: p_dst_3d(:,:),p_dst_2d(:) real(kind=REAL32), pointer :: p_acc_3d(:,:),p_acc_2d(:) - integer :: is, ie + type(ESMF_VM) :: vm + integer :: mypet, petcount + integer :: is, ie, nx_sum integer :: status + integer :: arr(1) + + + if (.NOT. this%active) then + _RETURN(ESMF_SUCCESS) + endif - if (.NOT. this%is_valid) then + if (this%nobs_epoch_sum==0) then _RETURN(ESMF_SUCCESS) endif @@ -933,6 +1028,27 @@ call this%get_x_subset(timeset, x_subset, _RC) is=x_subset(1) ie=x_subset(2) + !! write(6,'(2x,a,4i10)') 'in regrid_accumulate is, ie=', is, ie + + + ! + ! __ I designed a method to return from regridding if no valid points exist + ! in reality for 29 jedi platforms and dt > 20 sec, we donot need this + ! + !!arr(1)=1 + !!if (.NOT. (is > 0 .AND. is <= ie )) arr(1)=0 + !!call ESMF_VMGetGlobal(vm,_RC) + !!call ESMF_VMGet(vm, localPet=mypet, petCount=petCount, _RC) + !!call ESMF_VMAllFullReduce(vm, sendData=arr, recvData=nx_sum, & + !! count=1, reduceflag=ESMF_REDUCE_SUM, rc=rc) + !!if ( nx_sum == 0 ) then + !! write(6, '(2x,a,2x,3i10)') 'invalid points, mypet, is, ie =', mypet, is, ie + !! ! no valid points to regrid + !! _RETURN(ESMF_SUCCESS) + !!else + !! write(6, '(2x,a,2x,3i10)') ' valid points, mypet, is, ie =', mypet, is, ie + !!end if + if (this%vdata%regrid_type==VERTICAL_METHOD_ETA2LEV) then call this%vdata%setup_eta_to_pressure(_RC) @@ -996,7 +1112,7 @@ type(ESMF_Field) :: field type(ESMF_Time) :: currTime - if (.NOT. this%is_valid) then + if (.NOT. this%active) then _RETURN(ESMF_SUCCESS) endif @@ -1016,9 +1132,15 @@ if (mapl_am_i_root()) then do k=1, this%nobs_type - deallocate (this%obs(k)%lons) - deallocate (this%obs(k)%lats) - deallocate (this%obs(k)%times_R8) + if (allocated (this%obs(k)%lons)) then + deallocate (this%obs(k)%lons) + end if + if (allocated (this%obs(k)%lats)) then + deallocate (this%obs(k)%lats) + end if + if (allocated (this%obs(k)%times_R8)) then + deallocate (this%obs(k)%times_R8) + end if if (allocated(this%obs(k)%p2d)) then deallocate (this%obs(k)%p2d) endif @@ -1049,7 +1171,7 @@ call ESMF_ClockGet ( this%clock, CurrTime=currTime, _RC ) if (currTime > this%obsfile_end_time) then - this%is_valid = .false. + this%active = .false. _RETURN(ESMF_SUCCESS) end if @@ -1067,7 +1189,7 @@ real (ESMF_KIND_R8) :: rT1, rT2 integer(ESMF_KIND_I8) :: i1, i2 - integer(ESMF_KIND_I8) :: jt1, jt2, lb, ub + integer(ESMF_KIND_I8) :: index1, index2, lb, ub integer :: jlo, jhi integer :: status @@ -1078,7 +1200,9 @@ rT1=real(i1, kind=ESMF_KIND_R8) rT2=real(i2, kind=ESMF_KIND_R8) jlo = 1 - jhi= size(this%obstime) + !! + !! I choose UB = N+1 not N, because my sub. bisect find n: Y(n)=ub) then - x_subset(1) = lb - x_subset(2) = ub - else - x_subset(1) = lb - x_subset(2) = jt2 - endif - elseif (jt1>=ub) then - x_subset(1) = 0 - x_subset(2) = 0 - else - x_subset(1) = jt1 - if (jt2>=ub) then - x_subset(2) = ub - else - x_subset(2) = jt2 - endif - endif - + call bisect( this%obstime, rT1, index1, n_LB=lb, n_UB=ub, rc=rc) + call bisect( this%obstime, rT2, index2, n_LB=lb, n_UB=ub, rc=rc) + + ! (x1, x2] design in bisect + ! simple version + + x_subset(1) = index1+1 + x_subset(2) = index2 + +! if (index1=ub) then +! x_subset(2) = ub +! else +! x_subset(2) = index2 +! endif +! elseif (index1>=ub) then +! x_subset(1) = 0 +! x_subset(2) = 0 +! else +! x_subset(2) = index2 +! endif +! +!! write(6,'(2x,a,2x,2i10)') 'mod vers. get_x_subset, LB,UB=', x_subset(1:2) _RETURN(_SUCCESS) end procedure get_x_subset From 91453cf617d7478dc6ea3105f84944d797585ddc Mon Sep 17 00:00:00 2001 From: Yonggang Yu Date: Thu, 11 Jan 2024 23:06:37 -0700 Subject: [PATCH 2/6] Add procedure MAPL_BcastShared_2DR8 to MAPL_Comms.F90 --- base/MAPL_Comms.F90 | 34 ++++ base/MAPL_ObsUtil.F90 | 10 +- base/MAPL_SwathGridFactory.F90 | 319 +++++++++++++++------------------ 3 files changed, 179 insertions(+), 184 deletions(-) diff --git a/base/MAPL_Comms.F90 b/base/MAPL_Comms.F90 index 078a0a8a2c1c..a0684d51f9bb 100644 --- a/base/MAPL_Comms.F90 +++ b/base/MAPL_Comms.F90 @@ -116,6 +116,7 @@ module MAPL_CommsMod interface MAPL_BcastShared module procedure MAPL_BcastShared_1DR4 module procedure MAPL_BcastShared_2DR4 + module procedure MAPL_BcastShared_2DR8 end interface interface MAPL_CommsScatterV @@ -1117,6 +1118,39 @@ subroutine MAPL_BcastShared_2DR4(VM, Data, N, Root, RootOnly, rc) end subroutine MAPL_BcastShared_2DR4 + + subroutine MAPL_BcastShared_2DR8(VM, Data, N, Root, RootOnly, rc) + type(ESMF_VM) :: VM + real(kind=REAL64), pointer, intent(INOUT) :: Data(:,:) + integer, intent(IN ) :: N + integer, optional, intent(IN ) :: Root + logical, intent(IN ) :: RootOnly + integer, optional, intent( OUT) :: rc + + + integer :: status + + + + if(.not.MAPL_ShmInitialized) then + if (RootOnly) then + _RETURN(ESMF_SUCCESS) + end if + call MAPL_CommsBcast(vm, DATA=Data, N=N, ROOT=Root, RC=status) + _RETURN(STATUS) + else + call MAPL_SyncSharedMemory(RC=STATUS) + _VERIFY(STATUS) + call MAPL_BroadcastToNodes(Data, N=N, ROOT=Root, rc=status) + _VERIFY(STATUS) + call MAPL_SyncSharedMemory(RC=STATUS) + _VERIFY(STATUS) + endif + + _RETURN(ESMF_SUCCESS) + + end subroutine MAPL_BcastShared_2DR8 + ! Rank 0 !--------------------------- #define RANK_ 0 diff --git a/base/MAPL_ObsUtil.F90 b/base/MAPL_ObsUtil.F90 index 8901c159f6c7..ba81b21584c1 100644 --- a/base/MAPL_ObsUtil.F90 +++ b/base/MAPL_ObsUtil.F90 @@ -297,13 +297,10 @@ subroutine read_M_files_4_swath ( filenames, Xdim, Ydim, & character(len=ESMF_MAXSTR), optional, intent(in) :: var_name_lon character(len=ESMF_MAXSTR), optional, intent(in) :: var_name_lat character(len=ESMF_MAXSTR), optional, intent(in) :: var_name_time - - real, allocatable, optional, intent(inout) :: lon(:,:) - real, allocatable, optional, intent(inout) :: lat(:,:) - !! real(ESMF_KIND_R8), optional, intent(inout) :: time_R8(:,:) - real, allocatable, optional, intent(inout) :: time(:,:) + real(ESMF_KIND_R8), allocatable, optional, intent(inout) :: lon(:,:) + real(ESMF_KIND_R8), allocatable, optional, intent(inout) :: lat(:,:) + real(ESMF_KIND_R8), allocatable, optional, intent(inout) :: time(:,:) logical, optional, intent(in) :: Tfilter - integer, optional, intent(out) :: rc integer :: M @@ -395,7 +392,6 @@ subroutine read_M_files_4_swath ( filenames, Xdim, Ydim, & ! - ! ! -- determine true time/lon/lat by filtering T < 0 ! diff --git a/base/MAPL_SwathGridFactory.F90 b/base/MAPL_SwathGridFactory.F90 index d92cd27fafb4..2c4ff94af8d6 100644 --- a/base/MAPL_SwathGridFactory.F90 +++ b/base/MAPL_SwathGridFactory.F90 @@ -222,11 +222,11 @@ subroutine add_horz_coordinates_from_file(this, grid, unusable, rc) integer :: status real(kind=ESMF_KIND_R8), pointer :: fptr(:,:) - real, pointer :: centers(:,:) - real, allocatable :: lon_true(:,:) - real, allocatable :: lat_true(:,:) - real, allocatable :: time_true(:,:) - real(kind=ESMF_KIND_R8), allocatable :: X1d(:) + real(kind=ESMF_KIND_R8), allocatable :: lon_true(:,:) + real(kind=ESMF_KIND_R8), allocatable :: lat_true(:,:) + real(kind=ESMF_KIND_R8), allocatable :: time_true(:,:) + real(kind=ESMF_KIND_R8), pointer :: arr_lon(:,:) + real(kind=ESMF_KIND_R8), pointer :: arr_lat(:,:) integer :: i, j, k integer :: Xdim, Ydim @@ -242,33 +242,78 @@ subroutine add_horz_coordinates_from_file(this, grid, unusable, rc) ! debug type(ESMF_VM) :: vm integer :: mypet, petcount - - integer :: rank0 - integer :: src, dst integer :: nsize, count - integer :: nshared_pet - real, allocatable :: arr(:,:), arr_lon(:,:), arr_lat(:,:) - - integer, allocatable:: array1(:), array2(:), array3(:) + integer :: mpic _UNUSED_DUMMY(unusable) - call ESMF_VMGetGlobal(vm,_RC) - call ESMF_VMGet(vm, localPet=mypet, petCount=petCount, _RC) - + call ESMF_VMGetCurrent(vm,_RC) + call ESMF_VMGet(vm, mpiCommunicator=mpic, localPet=mypet, petCount=petCount, _RC) + Xdim=this%im_world Ydim=this%jm_world - Xdim_full=this%cell_across_swath - Ydim_full=this%cell_along_swath - + count = Xdim * Ydim + call MAPL_grid_interior(grid, i_1, i_n, j_1, j_n) - call MAPL_AllocateShared(centers,[Xdim,Ydim],transroot=.true.,_RC) - call MAPL_SyncSharedMemory(_RC) - call MAPL_AllocateShared(arr_lon,[Xdim,Ydim],transroot=.true.,_RC) call MAPL_AllocateShared(arr_lat,[Xdim,Ydim],transroot=.true.,_RC) + call MAPL_SyncSharedMemory(_RC) + + if (mapl_am_i_root()) then + allocate( lon_true(0,0), lat_true(0,0), time_true(0,0) ) + call read_M_files_4_swath (this%filenames(1:this%M_file), nx, ny, & + this%index_name_lon, this%index_name_lat, & + var_name_lon=this%var_name_lon, & + var_name_lat=this%var_name_lat, & + var_name_time=this%var_name_time, & + lon=lon_true, lat=lat_true, time=time_true, & + Tfilter=.true., _RC) + k=0 + do j=this%epoch_index(3), this%epoch_index(4) + k=k+1 + arr_lon(1:Xdim, k) = lon_true(1:Xdim, j) + arr_lat(1:Xdim, k) = lat_true(1:Xdim, j) + enddo + arr_lon=arr_lon*MAPL_DEGREES_TO_RADIANS_R8 + arr_lat=arr_lat*MAPL_DEGREES_TO_RADIANS_R8 + deallocate( lon_true, lat_true, time_true ) + + write(6,*) 'in root' + write(6,'(11x,100f10.1)') arr_lon(::5,189) + end if + call MPI_Barrier(mpic, status) + call MAPL_SyncSharedMemory(_RC) + + call MAPL_BcastShared (VM, data=arr_lon, N=count, Root=MAPL_ROOT, RootOnly=.false., _RC) + call MAPL_BcastShared (VM, data=arr_lat, N=count, Root=MAPL_ROOT, RootOnly=.false., _RC) + +! call MAPL_BroadcastToNodes (arr_lon, count, MAPL_ROOT, _RC) +! call MAPL_SyncSharedMemory(_RC) +! call MAPL_BroadcastToNodes (arr_lat, count, MAPL_ROOT, _RC) +! call MAPL_SyncSharedMemory(_RC) + + write(6,'(2x,a,2x,i5,4x,100f10.1)') 'PET', mypet, arr_lon(::5,189) + call MPI_Barrier(mpic, status) + + + call ESMF_GridGetCoord(grid, coordDim=1, localDE=0, & + staggerloc=ESMF_STAGGERLOC_CENTER, farrayPtr=fptr, _RC) + fptr=real(arr_lon(i_1:i_n,j_1:j_n), kind=ESMF_KIND_R8) + call MAPL_SyncSharedMemory(_RC) + + call ESMF_GridGetCoord(grid, coordDim=2, localDE=0, & + staggerloc=ESMF_STAGGERLOC_CENTER, & + farrayPtr=fptr, rc=status) + fptr=real(arr_lat(i_1:i_n,j_1:j_n), kind=ESMF_KIND_R8) + + if(MAPL_ShmInitialized) then + call MAPL_DeAllocNodeArray(arr_lon,_RC) + call MAPL_DeAllocNodeArray(arr_lat,_RC) + else + deallocate(arr_lon) + deallocate(arr_lat) + end if -!! mmapl_am_I_root() is element in set (rootscomm) ! if (mapl_am_I_root()) then ! write(6,'(2x,a,10i8)') & ! 'ck: Xdim, Ydim, Xdim_full, Ydim_full', Xdim, Ydim, Xdim_full, Ydim_full @@ -276,138 +321,13 @@ subroutine add_horz_coordinates_from_file(this, grid, unusable, rc) ! 'ck: i_1, i_n, j_1, j_n', i_1, i_n, j_1, j_n ! end if - ! - ! array3(1:nshared_pet) is the pet for shared headnode excluding mapl_am_i_root() - ! s1. read NC from root/rank0 - ! s2. MPI send and recv true_lon / true_lat via X1d - ! s3. pass X1d to Shmem [centers] - ! - - nsize = petCount - allocate (array1(nsize)) - allocate (array2(nsize)) - - array1(:) = 0 - src = 0 - dst = 0 - - if (mapl_am_i_root()) then - rank0 = mypet - src = 1 - end if - + write(6,*) 'MAPL_AmNodeRoot, MAPL_ShmInitialized=', MAPL_AmNodeRoot, MAPL_ShmInitialized if (MAPL_AmNodeRoot .or. (.not. MAPL_ShmInitialized)) then - if (mypet/=rank0) then - array1(mypet+1) = mypet+1 ! raise index to [1, N] - dst = 1 - end if - end if - - call ESMF_VMAllReduce(vm, sendData=array1, recvData=array2, count=nsize, & - reduceflag=ESMF_REDUCE_SUM, rc=rc) - write(6, '(2x,a,2x,i5,2x,a,2x,10i10)') 'mypet, array2', mypet, ':', array2 - - j=0 - do i=1, nsize - if ( array2(i) > 0 ) then - j=j+1 - end if - end do - allocate (array3(j)) - nshared_pet = j - - j=0 - do i=1, nsize - if ( array2(i) > 0 ) then - j=j+1 - array3(j) = array2(i) - 1 ! downshift value to mypet - end if - end do - - if (src==1 .OR. dst==1) then - allocate( arr_lon(Xdim, Ydim) ) - allocate( arr_lat(Xdim, Ydim) ) - allocate( X1d( Xdim * Ydim ) ) - allocate( Y1d( Xdim * Ydim ) ) + write(6,'(2x,a,2x,i10)') 'add_horz_coord: MAPL_AmNodeRoot: mypet=', mypet end if - - if (mypet==rank0) then - allocate( lon_true(0,0), lat_true(0,0), time_true(0,0) ) - call read_M_files_4_swath (this%filenames(1:this%M_file), nx, ny, & - this%index_name_lon, this%index_name_lat, & - var_name_lon=this%var_name_lon, & - var_name_lat=this%var_name_lat, & - var_name_time=this%var_name_time, & - lon=lon_true, lat=lat_true, time=time_true, & - Tfilter=.true., _RC) - k=0 - do j=this%epoch_index(3), this%epoch_index(4) - k=k+1 - arr_lon(1:Xdim, k) = lon_true(1:Xdim, j) - arr_lat(1:Xdim, k) = lat_true(1:Xdim, j) - enddo - arr_lon=arr_lon*MAPL_DEGREES_TO_RADIANS_R8 - arr_lat=arr_lat*MAPL_DEGREES_TO_RADIANS_R8 - k=0 - do j=1, Ydim - do i=1, Xdim - X1d(k) = arr_lon(i,j) - Y1d(k) = arr_lat(i,j) - end do - end do - deallocate( lon_true, time_true ) - ! - end if - - - - if (nshared_pet > 0) then - count = Xdim * Ydim - if (src==1) then - do j=1, nshared_pet - call ESMF_VMSend(vm, sendData=X1d, count=count, dstPet=array3(j), rc=rc) - call ESMF_VMSend(vm, sendData=Y1d, count=count, dstPet=array3(j), rc=rc) - end do - end if - if (dst==1) then - call ESMF_VMRecv(vm, recvData=arr_lon, count=count, srcPet=rank0, rc=rc) - call ESMF_VMRecv(vm, recvData=arr_lat, count=count, srcPet=rank0, rc=rc) - end if - end if - - ! read longitudes - if (MAPL_AmNodeRoot .or. (.not. MAPL_ShmInitialized)) then - write(6,'(2x,a,2x,i10)') 'add_horz_coord: MAPL_AmNodeRoot: mypet=', mypet - centers = arr_lon - end if - - -!! mpi_barrier for each core within node - call MAPL_SyncSharedMemory(_RC) - - call ESMF_GridGetCoord(grid, coordDim=1, localDE=0, & - staggerloc=ESMF_STAGGERLOC_CENTER, farrayPtr=fptr, _RC) - fptr=real(centers(i_1:i_n,j_1:j_n), kind=ESMF_KIND_R8) - -!! _FAIL ('nail -1') - ! read latitudes - if (MAPL_AmNodeRoot .or. (.not. MAPL_ShmInitialized)) then - centers = arr_lat - end if - call MAPL_SyncSharedMemory(_RC) - call ESMF_GridGetCoord(grid, coordDim=2, localDE=0, & - staggerloc=ESMF_STAGGERLOC_CENTER, & - farrayPtr=fptr, rc=status) - fptr=real(centers(i_1:i_n,j_1:j_n), kind=ESMF_KIND_R8) - - if(MAPL_ShmInitialized) then - call MAPL_DeAllocNodeArray(centers,_RC) - else - deallocate(centers) - end if - _RETURN(_SUCCESS) + end subroutine add_horz_coordinates_from_file @@ -526,10 +446,9 @@ subroutine initialize_from_config_with_prefix(this, config, prefix, unusable, rc character(len=ESMF_MAXSTR) :: filename, STR1, tmp character(len=ESMF_MAXSTR) :: symd, shms - ! real(ESMF_KIND_R8), allocatable :: scanTime(:,:) - real, allocatable :: scanTime(:,:) - real, allocatable :: lon_true(:,:) - real, allocatable :: lat_true(:,:) + real(ESMF_KIND_R8), allocatable :: scanTime(:,:) + real(ESMF_KIND_R8), allocatable :: lon_true(:,:) + real(ESMF_KIND_R8), allocatable :: lat_true(:,:) integer :: yy, mm, dd, h, m, s, sec, second integer :: i, j, L integer :: ncid, ncid2, varid @@ -1522,36 +1441,35 @@ subroutine get_obs_time(this, grid, obs_time, rc) integer, optional, intent(out) :: rc integer :: status - integer :: i_1, i_n, j_1, j_n ! regional array bounds - - !! shared mem real(kind=ESMF_KIND_R8), pointer :: fptr(:,:) - real, pointer :: centers(:,:) - real, allocatable :: lon_true(:,:) - real, allocatable :: lat_true(:,:) - real, allocatable :: time_true(:,:) + real(kind=ESMF_KIND_R8), pointer :: centers(:,:) + real(kind=ESMF_KIND_R8), allocatable :: lon_true(:,:) + real(kind=ESMF_KIND_R8), allocatable :: lat_true(:,:) + real(kind=ESMF_KIND_R8), allocatable :: time_true(:,:) + real(kind=ESMF_KIND_R8), pointer :: arr_time(:,:) integer :: i, j, k - integer :: Xdim, Ydim - integer :: Xdim_full, Ydim_full + integer :: Xdim, Ydim, count integer :: nx, ny - integer :: IM_WORLD, JM_WORLD + integer :: i_1, i_n, j_1, j_n ! regional array bounds + ! debug + type(ESMF_VM) :: vm + integer :: mypet, petcount + integer :: mpic - !- shared mem case in MPI - ! + call ESMF_VMGetCurrent(vm,_RC) + call ESMF_VMGet(vm, mpiCommunicator=mpic, localPet=mypet, petCount=petCount, _RC) + Xdim=this%im_world Ydim=this%jm_world - Xdim_full=this%cell_across_swath - Ydim_full=this%cell_along_swath + count=Xdim*Ydim call MAPL_grid_interior(grid, i_1, i_n, j_1, j_n) - call MAPL_AllocateShared(centers,[Xdim,Ydim],transroot=.true.,_RC) + call MAPL_AllocateShared(arr_time,[Xdim,Ydim],transroot=.true.,_RC) call MAPL_SyncSharedMemory(_RC) - - ! read and set Time - if (MAPL_AmNodeRoot .or. (.not. MAPL_ShmInitialized)) then + if (mapl_am_i_root()) then allocate( lon_true(0,0), lat_true(0,0), time_true(0,0) ) call read_M_files_4_swath (this%filenames(1:this%M_file), nx, ny, & this%index_name_lon, this%index_name_lat, & @@ -1563,21 +1481,68 @@ subroutine get_obs_time(this, grid, obs_time, rc) k=0 do j=this%epoch_index(3), this%epoch_index(4) k=k+1 - centers(1:Xdim, k) = time_true(1:Xdim, j) + arr_time(1:Xdim, k) = time_true(1:Xdim, j) enddo - deallocate (lon_true, lat_true, time_true) + deallocate( lon_true, lat_true, time_true ) + + write(6,*) 'in root, time' + write(6,'(11x,100E12.5)') arr_time(::5,189) end if call MAPL_SyncSharedMemory(_RC) + call MAPL_BcastShared (VM, data=arr_time, N=count, Root=MAPL_ROOT, RootOnly=.false., _RC) + + write(6,'(2x,a,2x,i5,4x,100E12.5)') 'PET, time', mypet, arr_time(::5,189) + call MPI_Barrier(mpic, status) + !(Xdim, Ydim) - obs_time = centers(i_1:i_n,j_1:j_n) + obs_time = arr_time(i_1:i_n,j_1:j_n) if(MAPL_ShmInitialized) then - call MAPL_DeAllocNodeArray(centers,_RC) + call MAPL_DeAllocNodeArray(arr_time,_RC) else - deallocate(centers) + deallocate(arr_time) end if + +! !- shared mem case in MPI +! ! +! Xdim=this%im_world +! Ydim=this%jm_world +! +! call MAPL_grid_interior(grid, i_1, i_n, j_1, j_n) +! call MAPL_AllocateShared(centers,[Xdim,Ydim],transroot=.true.,_RC) +! call MAPL_SyncSharedMemory(_RC) +! +! ! read and set Time +! +! if (MAPL_AmNodeRoot .or. (.not. MAPL_ShmInitialized)) then +! allocate( lon_true(0,0), lat_true(0,0), time_true(0,0) ) +! call read_M_files_4_swath (this%filenames(1:this%M_file), nx, ny, & +! this%index_name_lon, this%index_name_lat, & +! var_name_lon=this%var_name_lon, & +! var_name_lat=this%var_name_lat, & +! var_name_time=this%var_name_time, & +! lon=lon_true, lat=lat_true, time=time_true, & +! Tfilter=.true., _RC) +! k=0 +! do j=this%epoch_index(3), this%epoch_index(4) +! k=k+1 +! centers(1:Xdim, k) = time_true(1:Xdim, j) +! enddo +! deallocate (lon_true, lat_true, time_true) +! end if +! call MAPL_SyncSharedMemory(_RC) +! +! !(Xdim, Ydim) +! obs_time = centers(i_1:i_n,j_1:j_n) +! +! if(MAPL_ShmInitialized) then +! call MAPL_DeAllocNodeArray(centers,_RC) +! else +! deallocate(centers) +! end if + _RETURN(_SUCCESS) end subroutine get_obs_time From 628c59b21ff449d4e6323bdacb9cbb79f2e1d139 Mon Sep 17 00:00:00 2001 From: Yonggang Yu Date: Thu, 11 Jan 2024 23:19:41 -0700 Subject: [PATCH 3/6] incremental cleanup --- base/MAPL_SwathGridFactory.F90 | 85 +++++----------------- gridcomps/History/MAPL_HistoryGridComp.F90 | 3 - 2 files changed, 20 insertions(+), 68 deletions(-) diff --git a/base/MAPL_SwathGridFactory.F90 b/base/MAPL_SwathGridFactory.F90 index 2c4ff94af8d6..8cec02c76410 100644 --- a/base/MAPL_SwathGridFactory.F90 +++ b/base/MAPL_SwathGridFactory.F90 @@ -169,12 +169,11 @@ function make_new_grid(this, unusable, rc) result(grid) _UNUSED_DUMMY(unusable) - if (mapl_am_I_root()) write(6,*) 'MAPL_SwathGridFactory.F90: bf this%create_basic_grid' + !!if (mapl_am_I_root()) write(6,*) 'MAPL_SwathGridFactory.F90: bf this%create_basic_grid' grid = this%create_basic_grid(_RC) - if (mapl_am_I_root()) write(6,*) 'MAPL_SwathGridFactory.F90: af this%create_basic_grid' - + !!if (mapl_am_I_root()) write(6,*) 'MAPL_SwathGridFactory.F90: af this%create_basic_grid' call this%add_horz_coordinates_from_file(grid,_RC) - if (mapl_am_I_root()) write(6,*) 'MAPL_SwathGridFactory.F90: af this%add_horz_coordinates_from_file' + !!if (mapl_am_I_root()) write(6,*) 'MAPL_SwathGridFactory.F90: af this%add_horz_coordinates_from_file' _RETURN(_SUCCESS) end function make_new_grid @@ -247,8 +246,8 @@ subroutine add_horz_coordinates_from_file(this, grid, unusable, rc) _UNUSED_DUMMY(unusable) - call ESMF_VMGetCurrent(vm,_RC) - call ESMF_VMGet(vm, mpiCommunicator=mpic, localPet=mypet, petCount=petCount, _RC) +!! call ESMF_VMGetCurrent(vm,_RC) +!! call ESMF_VMGet(vm, mpiCommunicator=mpic, localPet=mypet, petCount=petCount, _RC) Xdim=this%im_world Ydim=this%jm_world @@ -278,22 +277,17 @@ subroutine add_horz_coordinates_from_file(this, grid, unusable, rc) arr_lat=arr_lat*MAPL_DEGREES_TO_RADIANS_R8 deallocate( lon_true, lat_true, time_true ) - write(6,*) 'in root' - write(6,'(11x,100f10.1)') arr_lon(::5,189) +! write(6,*) 'in root' +! write(6,'(11x,100f10.1)') arr_lon(::5,189) end if - call MPI_Barrier(mpic, status) +! call MPI_Barrier(mpic, status) call MAPL_SyncSharedMemory(_RC) call MAPL_BcastShared (VM, data=arr_lon, N=count, Root=MAPL_ROOT, RootOnly=.false., _RC) call MAPL_BcastShared (VM, data=arr_lat, N=count, Root=MAPL_ROOT, RootOnly=.false., _RC) -! call MAPL_BroadcastToNodes (arr_lon, count, MAPL_ROOT, _RC) -! call MAPL_SyncSharedMemory(_RC) -! call MAPL_BroadcastToNodes (arr_lat, count, MAPL_ROOT, _RC) -! call MAPL_SyncSharedMemory(_RC) - - write(6,'(2x,a,2x,i5,4x,100f10.1)') 'PET', mypet, arr_lon(::5,189) - call MPI_Barrier(mpic, status) +! write(6,'(2x,a,2x,i5,4x,100f10.1)') 'PET', mypet, arr_lon(::5,189) +! call MPI_Barrier(mpic, status) call ESMF_GridGetCoord(grid, coordDim=1, localDE=0, & @@ -316,15 +310,15 @@ subroutine add_horz_coordinates_from_file(this, grid, unusable, rc) ! if (mapl_am_I_root()) then ! write(6,'(2x,a,10i8)') & -! 'ck: Xdim, Ydim, Xdim_full, Ydim_full', Xdim, Ydim, Xdim_full, Ydim_full +! 'ck: Xdim, Ydim', Xdim, Ydim ! write(6,'(2x,a,10i8)') & ! 'ck: i_1, i_n, j_1, j_n', i_1, i_n, j_1, j_n ! end if - write(6,*) 'MAPL_AmNodeRoot, MAPL_ShmInitialized=', MAPL_AmNodeRoot, MAPL_ShmInitialized - if (MAPL_AmNodeRoot .or. (.not. MAPL_ShmInitialized)) then - write(6,'(2x,a,2x,i10)') 'add_horz_coord: MAPL_AmNodeRoot: mypet=', mypet - end if +! write(6,*) 'MAPL_AmNodeRoot, MAPL_ShmInitialized=', MAPL_AmNodeRoot, MAPL_ShmInitialized +! if (MAPL_AmNodeRoot .or. (.not. MAPL_ShmInitialized)) then +! write(6,'(2x,a,2x,i10)') 'add_horz_coord: MAPL_AmNodeRoot: mypet=', mypet +! end if _RETURN(_SUCCESS) @@ -1485,15 +1479,15 @@ subroutine get_obs_time(this, grid, obs_time, rc) enddo deallocate( lon_true, lat_true, time_true ) - write(6,*) 'in root, time' - write(6,'(11x,100E12.5)') arr_time(::5,189) +! write(6,*) 'in root, time' +! write(6,'(11x,100E12.5)') arr_time(::5,189) end if call MAPL_SyncSharedMemory(_RC) call MAPL_BcastShared (VM, data=arr_time, N=count, Root=MAPL_ROOT, RootOnly=.false., _RC) - write(6,'(2x,a,2x,i5,4x,100E12.5)') 'PET, time', mypet, arr_time(::5,189) - call MPI_Barrier(mpic, status) +! write(6,'(2x,a,2x,i5,4x,100E12.5)') 'PET, time', mypet, arr_time(::5,189) +! call MPI_Barrier(mpic, status) !(Xdim, Ydim) obs_time = arr_time(i_1:i_n,j_1:j_n) @@ -1502,46 +1496,7 @@ subroutine get_obs_time(this, grid, obs_time, rc) call MAPL_DeAllocNodeArray(arr_time,_RC) else deallocate(arr_time) - end if - - -! !- shared mem case in MPI -! ! -! Xdim=this%im_world -! Ydim=this%jm_world -! -! call MAPL_grid_interior(grid, i_1, i_n, j_1, j_n) -! call MAPL_AllocateShared(centers,[Xdim,Ydim],transroot=.true.,_RC) -! call MAPL_SyncSharedMemory(_RC) -! -! ! read and set Time -! -! if (MAPL_AmNodeRoot .or. (.not. MAPL_ShmInitialized)) then -! allocate( lon_true(0,0), lat_true(0,0), time_true(0,0) ) -! call read_M_files_4_swath (this%filenames(1:this%M_file), nx, ny, & -! this%index_name_lon, this%index_name_lat, & -! var_name_lon=this%var_name_lon, & -! var_name_lat=this%var_name_lat, & -! var_name_time=this%var_name_time, & -! lon=lon_true, lat=lat_true, time=time_true, & -! Tfilter=.true., _RC) -! k=0 -! do j=this%epoch_index(3), this%epoch_index(4) -! k=k+1 -! centers(1:Xdim, k) = time_true(1:Xdim, j) -! enddo -! deallocate (lon_true, lat_true, time_true) -! end if -! call MAPL_SyncSharedMemory(_RC) -! -! !(Xdim, Ydim) -! obs_time = centers(i_1:i_n,j_1:j_n) -! -! if(MAPL_ShmInitialized) then -! call MAPL_DeAllocNodeArray(centers,_RC) -! else -! deallocate(centers) -! end if + end if _RETURN(_SUCCESS) end subroutine get_obs_time diff --git a/gridcomps/History/MAPL_HistoryGridComp.F90 b/gridcomps/History/MAPL_HistoryGridComp.F90 index a742d8654335..9f5329b99ec5 100644 --- a/gridcomps/History/MAPL_HistoryGridComp.F90 +++ b/gridcomps/History/MAPL_HistoryGridComp.F90 @@ -631,9 +631,6 @@ subroutine Initialize ( gc, import, dumexport, clock, rc ) end if call Hsampler%config_accumulate(key, config, _RC) output_grid = Hsampler%create_grid(key, currTime, grid_type=grid_type, _RC) - if (mapl_am_i_root()) write(6,*) 'nail af Hsampler%create_grid' - - end if call IntState%output_grids%set(key, output_grid) call iter%next() From ce97de1b85a31b633ddb729405aadafe51020cac Mon Sep 17 00:00:00 2001 From: Yonggang Yu Date: Fri, 12 Jan 2024 00:14:48 -0700 Subject: [PATCH 4/6] small changes in format --- CHANGELOG.md | 5 +++-- Tests/ExtDataDriverGridComp.F90 | 6 +----- base/MAPL_Comms.F90 | 4 ---- base/MAPL_SwathGridFactory.F90 | 1 - gridcomps/History/MAPL_EpochSwathMod.F90 | 2 +- 5 files changed, 5 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f512a9e0edf..c4adc1993125 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,8 +13,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Handle regrid accumulate for time step (1 sec) during which no obs exists - Use IntState%stampoffset(n) to adjust filenames for an epoch time - parse "GOCART::CO2" from 'geovals_fields' entry in PLATFORM -- Add Shmem to ExtDataDriverGridComp.F90 -- Read swath data on root, pass to NodeRoot for Shmem, so to avoid race in reading nc files +- Add call MAPL_InitializeShmem to ExtDataDriverGridComp.F90 +- Read swath data on root, call MAPL_CommsBcast [which sends data to Shmem (when Shmem initialized) or to MAPL_comm otherwise]. This approach avoids race in reading nc files [e.g. 37 files for 3 hr swath data] + - Added memory utility, MAPL_MemReport that can be used in any code linking MAPL diff --git a/Tests/ExtDataDriverGridComp.F90 b/Tests/ExtDataDriverGridComp.F90 index c303f61be6e1..551e2eb61297 100644 --- a/Tests/ExtDataDriverGridComp.F90 +++ b/Tests/ExtDataDriverGridComp.F90 @@ -11,7 +11,7 @@ module ExtData_DriverGridCompMod use MAPL_HistoryGridCompMod, only : Hist_SetServices => SetServices use MAPL_Profiler, only : get_global_time_profiler, BaseProfiler use mpi -! use MAPL_ShmemMod + implicit none private @@ -144,10 +144,8 @@ subroutine initialize_gc(gc, import_state, export_state, clock, rc) type(ExtData_DriverGridComp), pointer :: cap class(BaseProfiler), pointer :: t_p logical :: use_extdata2g - integer :: useShmem - _UNUSED_DUMMY(import_state) _UNUSED_DUMMY(export_state) _UNUSED_DUMMY(clock) @@ -171,7 +169,6 @@ subroutine initialize_gc(gc, import_state, export_state, clock, rc) cap%AmIRoot = AmIRoot_ - ! Open the CAP's configuration from CAP.rc !------------------------------------------ @@ -196,7 +193,6 @@ subroutine initialize_gc(gc, import_state, export_state, clock, rc) _VERIFY(status) end if - call ESMF_ConfigGetAttribute(cap%config,cap%run_fbf,label="RUN_FBF:",default=.false.) call ESMF_ConfigGetAttribute(cap%config,cap%run_hist,label="RUN_HISTORY:",default=.true.) call ESMF_ConfigGetAttribute(cap%config,cap%run_extdata,label="RUN_EXTDATA:",default=.true.) diff --git a/base/MAPL_Comms.F90 b/base/MAPL_Comms.F90 index a0684d51f9bb..d980491ebe30 100644 --- a/base/MAPL_Comms.F90 +++ b/base/MAPL_Comms.F90 @@ -1126,12 +1126,8 @@ subroutine MAPL_BcastShared_2DR8(VM, Data, N, Root, RootOnly, rc) integer, optional, intent(IN ) :: Root logical, intent(IN ) :: RootOnly integer, optional, intent( OUT) :: rc - - integer :: status - - if(.not.MAPL_ShmInitialized) then if (RootOnly) then _RETURN(ESMF_SUCCESS) diff --git a/base/MAPL_SwathGridFactory.F90 b/base/MAPL_SwathGridFactory.F90 index 8cec02c76410..7ce23e8ab65f 100644 --- a/base/MAPL_SwathGridFactory.F90 +++ b/base/MAPL_SwathGridFactory.F90 @@ -289,7 +289,6 @@ subroutine add_horz_coordinates_from_file(this, grid, unusable, rc) ! write(6,'(2x,a,2x,i5,4x,100f10.1)') 'PET', mypet, arr_lon(::5,189) ! call MPI_Barrier(mpic, status) - call ESMF_GridGetCoord(grid, coordDim=1, localDE=0, & staggerloc=ESMF_STAGGERLOC_CENTER, farrayPtr=fptr, _RC) fptr=real(arr_lon(i_1:i_n,j_1:j_n), kind=ESMF_KIND_R8) diff --git a/gridcomps/History/MAPL_EpochSwathMod.F90 b/gridcomps/History/MAPL_EpochSwathMod.F90 index 82fdebcbd9b6..ae42ac808963 100644 --- a/gridcomps/History/MAPL_EpochSwathMod.F90 +++ b/gridcomps/History/MAPL_EpochSwathMod.F90 @@ -262,7 +262,7 @@ end subroutine regrid_accumulate_on_xysubset subroutine destroy_rh_regen_ogrid (this, key_grid_label, output_grids, sp, rc) implicit none - class(samplerHQ), target :: this + class(samplerHQ) :: this class(sampler) :: sp type (StringGridMap), target, intent(inout) :: output_grids character(len=*), intent(in) :: key_grid_label From 84595af77da585916a0e304d91725ff945b5c881 Mon Sep 17 00:00:00 2001 From: Yonggang Yu Date: Fri, 12 Jan 2024 09:19:57 -0700 Subject: [PATCH 5/6] changed rc=status to _RC, EX to exist, and deleted some dead code to remove confusion. --- Tests/ExtDataDriverGridComp.F90 | 9 ++++----- base/MAPL_Comms.F90 | 12 ++++-------- base/MAPL_ObsUtil.F90 | 18 ++++++------------ 3 files changed, 14 insertions(+), 25 deletions(-) diff --git a/Tests/ExtDataDriverGridComp.F90 b/Tests/ExtDataDriverGridComp.F90 index 551e2eb61297..d4d11b038ed4 100644 --- a/Tests/ExtDataDriverGridComp.F90 +++ b/Tests/ExtDataDriverGridComp.F90 @@ -187,10 +187,9 @@ subroutine initialize_gc(gc, import_state, export_state, clock, rc) call MAPL_Set(MAPLOBJ, name = cap%name, cf = cap%config, rc = status) _VERIFY(status) - call MAPL_GetResource(MAPLOBJ, useShmem, label = 'USE_SHMEM:', default = 0, rc = status) + call MAPL_GetResource(MAPLOBJ, useShmem, label = 'USE_SHMEM:', default = 0, _RC) if (useShmem /= 0) then - call MAPL_InitializeShmem (rc = status) - _VERIFY(status) + call MAPL_InitializeShmem (_RC) end if call ESMF_ConfigGetAttribute(cap%config,cap%run_fbf,label="RUN_FBF:",default=.false.) @@ -492,8 +491,8 @@ subroutine finalize_gc(gc, import_state, export_state, clock, rc) call ESMF_ConfigDestroy(cap%config, rc = status) _VERIFY(status) - call MAPL_FinalizeSHMEM (rc = status) - _VERIFY(status) + call MAPL_FinalizeSHMEM (_RC) + _RETURN(ESMF_SUCCESS) end subroutine finalize_gc diff --git a/base/MAPL_Comms.F90 b/base/MAPL_Comms.F90 index d980491ebe30..12053ea06722 100644 --- a/base/MAPL_Comms.F90 +++ b/base/MAPL_Comms.F90 @@ -1132,15 +1132,11 @@ subroutine MAPL_BcastShared_2DR8(VM, Data, N, Root, RootOnly, rc) if (RootOnly) then _RETURN(ESMF_SUCCESS) end if - call MAPL_CommsBcast(vm, DATA=Data, N=N, ROOT=Root, RC=status) - _RETURN(STATUS) + call MAPL_CommsBcast(vm, DATA=Data, N=N, ROOT=Root, _RC) else - call MAPL_SyncSharedMemory(RC=STATUS) - _VERIFY(STATUS) - call MAPL_BroadcastToNodes(Data, N=N, ROOT=Root, rc=status) - _VERIFY(STATUS) - call MAPL_SyncSharedMemory(RC=STATUS) - _VERIFY(STATUS) + call MAPL_SyncSharedMemory(_RC) + call MAPL_BroadcastToNodes(Data, N=N, ROOT=Root, _RC) + call MAPL_SyncSharedMemory(_RC) endif _RETURN(ESMF_SUCCESS) diff --git a/base/MAPL_ObsUtil.F90 b/base/MAPL_ObsUtil.F90 index ba81b21584c1..981a1d3b8ac2 100644 --- a/base/MAPL_ObsUtil.F90 +++ b/base/MAPL_ObsUtil.F90 @@ -99,12 +99,6 @@ subroutine get_obsfile_Tbracket_from_epoch(currTime, & obsfile_Ts_index = n1 obsfile_Te_index = n2 -! if ( dT2_s - n2*dT0_s < 1 ) then -! obsfile_Te_index = n2 - 1 -! else -! obsfile_Te_index = n2 -! end if - _RETURN(ESMF_SUCCESS) end subroutine get_obsfile_Tbracket_from_epoch @@ -218,7 +212,7 @@ subroutine Find_M_files_for_currTime (currTime, & integer :: n1, n2 integer :: i, j integer :: status - logical :: EX + logical :: exist !__ s1. Arithmetic index list based on s,e,interval ! @@ -268,8 +262,8 @@ subroutine Find_M_files_for_currTime (currTime, & do i= n1, n2 test_file = get_filename_from_template_use_index & (obsfile_start_time, obsfile_interval, & - i, file_template, EX, rc=rc) - if (EX) then + i, file_template, exist, rc=rc) + if (exist) then j=j+1 filenames(j) = test_file end if @@ -474,7 +468,7 @@ end subroutine read_M_files_4_swath ! because of (bash ls) command therein ! function get_filename_from_template_use_index (obsfile_start_time, obsfile_interval, & - f_index, file_template, EX, rc) result(filename) + f_index, file_template, exist, rc) result(filename) use Plain_netCDF_Time, only : ESMF_time_to_two_integer use MAPL_StringTemplate, only : fill_grads_template character(len=ESMF_MAXSTR) :: filename @@ -482,7 +476,7 @@ function get_filename_from_template_use_index (obsfile_start_time, obsfile_inter type(ESMF_TimeInterval), intent(in) :: obsfile_interval character(len=*), intent(in) :: file_template integer, intent(in) :: f_index - logical, intent(out) :: EX + logical, intent(out) :: exist integer, optional, intent(out) :: rc integer :: itime(2) @@ -514,7 +508,7 @@ function get_filename_from_template_use_index (obsfile_start_time, obsfile_inter ! call fill_grads_template ( filename, file_template, & experiment_id='', nymd=nymd, nhms=nhms, _RC ) - inquire(file= trim(filename), EXIST = EX) + inquire(file= trim(filename), EXIST = exist) _RETURN(_SUCCESS) From 68480319861ede2ad9b379d50c91dc025d131fda Mon Sep 17 00:00:00 2001 From: Yonggang Yu Date: Fri, 12 Jan 2024 12:23:56 -0700 Subject: [PATCH 6/6] avoid using temporary variables for time_loc_R8, lon_loc and lat_loc in subroutine read_M_files_4_swath in MAPL_ObsUtil.F90 --- base/MAPL_ObsUtil.F90 | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/base/MAPL_ObsUtil.F90 b/base/MAPL_ObsUtil.F90 index 981a1d3b8ac2..96ada969b733 100644 --- a/base/MAPL_ObsUtil.F90 +++ b/base/MAPL_ObsUtil.F90 @@ -427,6 +427,19 @@ subroutine read_M_files_4_swath ( filenames, Xdim, Ydim, & else + if (allocated (time)) then + deallocate(time) + allocate (time(Xdim, Ydim)) + end if + if (allocated (lon)) then + deallocate(lon) + allocate (lon(Xdim, Ydim)) + end if + if (allocated (lat)) then + deallocate(lat) + allocate (lat(Xdim, Ydim)) + end if + jx=0 do i = 1, M filename = filenames(i) @@ -434,24 +447,13 @@ subroutine read_M_files_4_swath ( filenames, Xdim, Ydim, & nlat = nlats(i) if (present(var_name_time).AND.present(time)) then - allocate (time_loc_R8(nlon, nlat)) - call get_var_from_name_w_group (var_name_time, time_loc_R8, filename, _RC) - time(1:nlon,jx+1:jx+nlat) = time_loc_R8(1:nlon,1:nlat) - deallocate(time_loc_R8) + call get_var_from_name_w_group (var_name_time, time(1:nlon,jx+1:jx+nlat), filename, _RC) end if - if (present(var_name_lon).AND.present(lon)) then - allocate (lon_loc(nlon, nlat)) - call get_var_from_name_w_group (var_name_lon, lon_loc, filename, _RC) - lon(1:nlon,jx+1:jx+nlat) = lon_loc(1:nlon,1:nlat) - deallocate(lon_loc) + call get_var_from_name_w_group (var_name_lon, lon(1:nlon,jx+1:jx+nlat), filename, _RC) end if - if (present(var_name_lat).AND.present(lat)) then - allocate (lat_loc(nlon, nlat)) - call get_var_from_name_w_group (var_name_lat, lat_loc, filename, _RC) - lat(1:nlon,jx+1:jx+nlat) = lat_loc(1:nlon,1:nlat) - deallocate(lat_loc) + call get_var_from_name_w_group (var_name_lat, lat(1:nlon,jx+1:jx+nlat), filename, _RC) end if jx = jx + nlat