!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! !! !! GNU General Public License !! !! !! !! This file is part of the Flexible Modeling System (FMS). !! !! !! !! FMS is free software; you can redistribute it and/or modify !! !! it and are expected to follow the terms of the GNU General Public !! !! License as published by the Free Software Foundation. !! !! !! !! FMS is distributed in the hope that it will be useful, !! !! but WITHOUT ANY WARRANTY; without even the implied warranty of !! !! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the !! !! GNU General Public License for more details. !! !! !! !! You should have received a copy of the GNU General Public License !! !! along with FMS; if not, write to: !! !! Free Software Foundation, Inc. !! !! 59 Temple Place, Suite 330 !! !! Boston, MA 02111-1307 USA !! !! or see: !! !! http://www.gnu.org/licenses/gpl.txt !! !! !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 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 15.0 2007/08/14 04:14:22 fms Exp $' character(len=128) :: tagname = '$Name: mom4p1_pubrel_dec2009_nnz $' 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