! +-======-+ ! Copyright (c) 2003-2007 United States Government as represented by ! the Admistrator of the National Aeronautics and Space Administration. ! All Rights Reserved. ! ! THIS OPEN SOURCE AGREEMENT ("AGREEMENT") DEFINES THE RIGHTS OF USE, ! REPRODUCTION, DISTRIBUTION, MODIFICATION AND REDISTRIBUTION OF CERTAIN ! COMPUTER SOFTWARE ORIGINALLY RELEASED BY THE UNITED STATES GOVERNMENT AS ! REPRESENTED BY THE GOVERNMENT AGENCY LISTED BELOW ("GOVERNMENT AGENCY"). ! THE UNITED STATES GOVERNMENT, AS REPRESENTED BY GOVERNMENT AGENCY, IS AN ! INTENDED THIRD-PARTY BENEFICIARY OF ALL SUBSEQUENT DISTRIBUTIONS OR ! REDISTRIBUTIONS OF THE SUBJECT SOFTWARE. ANYONE WHO USES, REPRODUCES, ! DISTRIBUTES, MODIFIES OR REDISTRIBUTES THE SUBJECT SOFTWARE, AS DEFINED ! HEREIN, OR ANY PART THEREOF, IS, BY THAT ACTION, ACCEPTING IN FULL THE ! RESPONSIBILITIES AND OBLIGATIONS CONTAINED IN THIS AGREEMENT. ! ! Government Agency: National Aeronautics and Space Administration ! Government Agency Original Software Designation: GSC-15354-1 ! Government Agency Original Software Title: GEOS-5 GCM Modeling Software ! User Registration Requested. Please Visit http://opensource.gsfc.nasa.gov ! Government Agency Point of Contact for Original Software: ! Dale Hithon, SRA Assistant, (301) 286-2691 ! ! +-======-+ module mosaic_mod ! ! Zhi Liang ! ! ! ! mosaic_mod implements some utility routines to read mosaic information. ! ! ! mosaic_mod implements some utility routines to read mosaic information. ! The information includes number of tiles and contacts in the mosaic, ! mosaic grid resolution of each tile, mosaic contact information, mosaic exchange ! grid information. Each routine will call a C-version routine to get these information. ! use mpp_mod, only : mpp_error, FATAL implicit none private ! --- public interface public :: get_mosaic_ntiles public :: get_mosaic_ncontacts public :: get_mosaic_grid_sizes public :: get_mosaic_contact public :: get_mosaic_xgrid_size public :: get_mosaic_xgrid public :: calc_mosaic_grid_area logical :: module_is_initialized = .true. ! version information varaible character(len=128) :: version = '$Id: mosaic.F90,v 1.1.1.1 2010-03-19 21:18:54 atrayano Exp $' character(len=128) :: tagname = '$Name: Fortuna-2_5_p1 $' contains !####################################################################### ! ! ! Initialize the mosaic_mod. ! ! ! Initialization routine for the mosaic module. It writes the ! version information to the log file. ! ! subroutine mosaic_init() if (module_is_initialized) return module_is_initialized = .TRUE. !--------- write version number and namelist ------------------ ! call write_version_number (version, tagname) end subroutine mosaic_init ! !####################################################################### ! ! ! return exchange grid size of mosaic xgrid file. ! ! ! return exchange grid size of mosaic xgrid file. ! ! ! ! The file that contains exchange grid information. ! function get_mosaic_xgrid_size(xgrid_file) character(len=*), intent(in) :: xgrid_file integer :: get_mosaic_xgrid_size character(len=len_trim(xgrid_file)+1) :: xfile integer :: read_mosaic_xgrid_size integer :: strlen !---- transfer to C-stype string strlen = len_trim(xgrid_file) xfile(1:strlen) = xgrid_file(1:strlen) strlen = strlen+1 xfile(strlen:strlen) = CHAR(0) get_mosaic_xgrid_size = read_mosaic_xgrid_size(xfile) return end function get_mosaic_xgrid_size ! !####################################################################### ! ! ! get exchange grid information from mosaic xgrid file. ! ! ! get exchange grid information from mosaic xgrid file. ! ! ! ! The file that contains exchange grid information. ! ! ! number of exchange grid in xgrid_file ! ! ! i and j-index in grid 1 of exchange grid. ! ! ! i and j-index in grid 2 of exchange grid. ! ! ! area of the exchange grid. The area is scaled to represent unit earth area. ! subroutine get_mosaic_xgrid(xgrid_file, i1, j1, i2, j2, area, di, dj) character(len=*), intent(in) :: xgrid_file integer, intent(inout) :: i1(:), j1(:), i2(:), j2(:) real, intent(inout) :: area(:) real, optional,intent(inout) :: di(:), dj(:) character(len=len_trim(xgrid_file)+1) :: xfile integer :: n, strlen, nxgrid !---- transfer to C-stype string strlen = len_trim(xgrid_file) xfile(1:strlen) = xgrid_file(1:strlen) strlen = strlen+1 xfile(strlen:strlen) = CHAR(0) !--- order 2 xgrid will be implemented later nxgrid = size(i1(:)) if(PRESENT(di)) then if(.NOT. PRESENT(dj) ) call mpp_error(FATAL, "mosaic_mod: when di is present, dj should be present") call read_mosaic_xgrid_order2(xfile, i1, j1, i2, j2, area, di, dj) else call read_mosaic_xgrid_order1(xfile, i1, j1, i2, j2, area) end if ! in C, programming, the starting index is 0, so need add 1 to the index. do n = 1, nxgrid i1(n) = i1(n) + 1 j1(n) = j1(n) + 1 i2(n) = i2(n) + 1 j2(n) = j2(n) + 1 end do end subroutine get_mosaic_xgrid ! !############################################################################### ! ! ! get number of tiles in the mosaic_file. ! ! ! get number of tiles in the mosaic_file. ! ! ! ! The file that contains mosaic information. ! function get_mosaic_ntiles(mosaic_file) character(len=*), intent(in) :: mosaic_file integer :: get_mosaic_ntiles character(len=len_trim(mosaic_file)+1) :: mfile integer :: strlen integer :: read_mosaic_ntiles !---- transfer to C-stype string strlen = len_trim(mosaic_file) mfile(1:strlen) = mosaic_file(1:strlen) strlen = strlen+1 mfile(strlen:strlen) = CHAR(0) get_mosaic_ntiles = read_mosaic_ntiles(mfile) end function get_mosaic_ntiles ! !############################################################################### ! ! ! get number of contacts in the mosaic_file. ! ! ! get number of contacts in the mosaic_file. ! ! ! ! The file that contains mosaic information. ! function get_mosaic_ncontacts( mosaic_file) character(len=*), intent(in) :: mosaic_file integer :: get_mosaic_ncontacts character(len=len_trim(mosaic_file)+1) :: mfile integer :: strlen integer :: read_mosaic_ncontacts !---- transfer to C-stype string strlen = len_trim(mosaic_file) mfile(1:strlen) = mosaic_file(1:strlen) strlen = strlen+1 mfile(strlen:strlen) = CHAR(0) get_mosaic_ncontacts = read_mosaic_ncontacts(mfile) end function get_mosaic_ncontacts ! !############################################################################### ! ! ! get grid size of each tile from mosaic_file ! ! ! get grid size of each tile from mosaic_file ! ! ! ! The file that contains mosaic information. ! ! ! List of grid size in x-direction of each tile. ! ! ! List of grid size in y-direction of each tile. ! subroutine get_mosaic_grid_sizes( mosaic_file, nx, ny) character(len=*), intent(in) :: mosaic_file integer, dimension(:), intent(inout) :: nx, ny character(len=len_trim(mosaic_file)+1) :: mfile integer :: strlen !---- transfer to C-stype string strlen = len_trim(mosaic_file) mfile(1:strlen) = mosaic_file(1:strlen) strlen = strlen+1 mfile(strlen:strlen) = CHAR(0) call read_mosaic_grid_sizes(mfile, nx, ny) end subroutine get_mosaic_grid_sizes ! !############################################################################### ! ! ! get contact information from mosaic_file ! ! ! get contact information from mosaic_file ! ! ! ! The file that contains mosaic information. ! ! ! list tile number in tile 1 of each contact. ! ! ! list tile number in tile 2 of each contact. ! ! ! list starting i-index in tile 1 of each contact. ! ! ! list ending i-index in tile 1 of each contact. ! ! ! list starting j-index in tile 1 of each contact. ! ! ! list ending j-index in tile 1 of each contact. ! ! ! list starting i-index in tile 2 of each contact. ! ! ! list ending i-index in tile 2 of each contact. ! ! ! list starting j-index in tile 2 of each contact. ! ! ! list ending j-index in tile 2 of each contact. ! subroutine get_mosaic_contact( mosaic_file, tile1, tile2, istart1, iend1, jstart1, jend1, & istart2, iend2, jstart2, jend2) character(len=*), intent(in) :: mosaic_file integer, dimension(:), intent(inout) :: tile1, tile2 integer, dimension(:), intent(inout) :: istart1, iend1, jstart1, jend1 integer, dimension(:), intent(inout) :: istart2, iend2, jstart2, jend2 character(len=len_trim(mosaic_file)+1) :: mfile integer :: strlen !---- transfer to C-stype string strlen = len_trim(mosaic_file) mfile(1:strlen) = mosaic_file(1:strlen) strlen = strlen+1 mfile(strlen:strlen) = CHAR(0) call read_mosaic_contact(mfile, tile1, tile2, istart1, iend1, jstart1, jend1, & istart2, iend2, jstart2, jend2) !--- transfer C-index to Fortran-index. istart1 = istart1 + 1 iend1 = iend1 + 1 jstart1 = jstart1 + 1 jend1 = jend1 + 1 istart2 = istart2 + 1 iend2 = iend2 + 1 jstart2 = jstart2 + 1 jend2 = jend2 + 1 end subroutine get_mosaic_contact ! !############################################################################### ! ! ! calculate grid cell area. ! ! ! calculate the grid cell area. The purpose of this routine is to make ! sure the consistency between model grid area and exchange grid area. ! ! ! ! geographical longitude of grid cell vertices. ! ! ! geographical latitude of grid cell vertices. ! ! ! grid cell area. ! subroutine calc_mosaic_grid_area(lon, lat, area) real, dimension(:,:), intent(in) :: lon real, dimension(:,:), intent(in) :: lat real, dimension(:,:), intent(inout) :: area integer :: nlon, nlat nlon = size(area,1) nlat = size(area,2) ! make sure size of lon, lat and area are consitency if( size(lon,1) .NE. nlon+1 .OR. size(lat,1) .NE. nlon+1 ) & call mpp_error(FATAL, "mosaic_mod: size(lon,1) and size(lat,1) should equal to size(area,1)+1") if( size(lon,2) .NE. nlat+1 .OR. size(lat,2) .NE. nlat+1 ) & call mpp_error(FATAL, "mosaic_mod: size(lon,2) and size(lat,2) should equal to size(area,2)+1") call get_grid_area( nlon, nlat, lon, lat, area) end subroutine calc_mosaic_grid_area ! end module mosaic_mod #ifdef TEST_MOSAIC program test_mosaic use mosaic_mod, only : get_mosaic_ntiles, get_mosaic_ncontacts use mosaic_mod, only : get_mosaic_grid_sizes, get_mosaic_contact implicit none integer :: ntiles, ncontacts, n integer, allocatable :: tile1(:), tile2(:), nx(:), ny(:) integer, allocatable :: istart1(:), iend1(:), jstart1(:), jend1(:) integer, allocatable :: istart2(:), iend2(:), jstart2(:), jend2(:) character(len=128) :: mosaic_file = "INPUT/mosaic.nc" ntiles = get_mosaic_ntiles(mosaic_file) ncontacts = get_mosaic_ncontacts(mosaic_file) allocate(nx(ntiles), ny(ntiles)) allocate(tile1(ncontacts), tile2(ncontacts) ) allocate(istart1(ncontacts), iend1(ncontacts), jstart1(ncontacts), jend1(ncontacts) ) allocate(istart2(ncontacts), iend2(ncontacts), jstart2(ncontacts), jend2(ncontacts) ) call get_mosaic_grid_sizes(mosaic_file, nx, ny ) call get_mosaic_contact(mosaic_file, tile1, tile2, istart1, iend1, jstart1, jend1, istart2, iend2, jstart2, jend2) ! print out information print '(a,i3,a,a)', "****** There is ", ntiles, " tiles in ", trim(mosaic_file) do n = 1, ntiles print '(a,i3,a,i3,a,i3)', " tile = ", n, ", nx = ", nx(n), ", ny = ", ny(n) end do print '(a,i3,a,a)', "****** There is ", ncontacts, " contacts in ", trim(mosaic_file) do n = 1, ncontacts print '(a,i3,a,i3,a,i3,a,i4,a,i4,a,i4,a,i4,a,i4,a,i4,a,i4,a,i4)', & "contact=", n, ": tile1=", tile1(n), " tile2=", tile2(n), & " is1=", istart1(n), " ie1=", iend1(n), & " js1=", jstart1(n), " je1=", jend1(n), & " is2=", istart2(n), " ie2=", iend2(n), & " js2=", jstart2(n), " je2=", jend2(n) end do deallocate(tile1, tile2, nx, ny) deallocate(istart1, iend1, jstart1, jend1) deallocate(istart2, iend2, jstart2, jend2) end program test_mosaic #endif