26 use mpp_mod,
only : mpp_root_pe,
mpp_error, uppercase, lowercase, fatal, note
27 use constants_mod,
only : pi, radius
28 use fms2_io_mod,
only : get_global_attribute,
read_data, global_att_exists, &
31 use fms_string_utils_mod,
only:
string
72 module procedure get_grid_cell_vertices_1d_r4
73 module procedure get_grid_cell_vertices_1d_r8
74 module procedure get_grid_cell_vertices_2d_r4
75 module procedure get_grid_cell_vertices_2d_r8
76 module procedure get_grid_cell_vertices_ug_r4
77 module procedure get_grid_cell_vertices_ug_r8
83 module procedure get_grid_cell_centers_1d_r4
84 module procedure get_grid_cell_centers_1d_r8
85 module procedure get_grid_cell_centers_2d_r4
86 module procedure get_grid_cell_centers_2d_r8
87 module procedure get_grid_cell_centers_ug_r4
88 module procedure get_grid_cell_centers_ug_r8
94 module procedure get_grid_cell_area_sg_r4
95 module procedure get_grid_cell_area_sg_r8
96 module procedure get_grid_cell_area_ug_r4
97 module procedure get_grid_cell_area_ug_r8
103 module procedure get_grid_comp_area_sg_r4
104 module procedure get_grid_comp_area_sg_r8
105 module procedure get_grid_comp_area_ug_r4
106 module procedure get_grid_comp_area_ug_r8
112 character(len=*),
parameter :: &
113 module_name =
'grid2_mod'
116 #include<file_version.h>
118 character(len=*),
parameter :: &
119 grid_dir =
'INPUT/', & !< root directory for all grid files
122 integer,
parameter :: &
123 max_name = 256, & !< max length of the variable names
135 logical :: great_circle_algorithm = .false.
136 logical :: module_is_initialized = .false.
137 logical :: grid_spec_exists = .true.
138 type(fmsnetcdffile_t) :: gridfileobj
139 type(fmsnetcdffile_t),
dimension(3) :: mosaic_fileobj
145 if (module_is_initialized)
return
147 module_is_initialized = .true.
148 grid_spec_exists = .false.
156 module_is_initialized = .true.
161 if (.not. module_is_initialized)
return
162 if (grid_spec_exists)
then
166 module_is_initialized = .false.
171 character(len=*),
intent(in) :: subroutine_name
173 if (.not. module_is_initialized)
then
174 call mpp_error(fatal,
"grid2_mod::"//trim(subroutine_name)//
" is being called but grid2 was never initialized. "//&
175 "Please ensure that grid_init is called before calling "//trim(subroutine_name)//
".")
178 if (.not. grid_spec_exists)
then
179 call mpp_error(fatal,
"grid2_mod::"//trim(subroutine_name)//
" is being called, but "//trim(
grid_file)//&
180 " does not exist, so grid2 was not initialized properly."//&
181 " Please ensure that "//trim(
grid_file)//
" is accessible.")
188 character(len=128) :: attvalue
192 if (.not. grid_spec_exists)
return
193 if (global_att_exists(gridfileobj,
"great_circle_algorithm"))
then
194 call get_global_attribute(gridfileobj,
"great_circle_algorithm", attvalue)
195 if(trim(attvalue) ==
"TRUE")
then
197 else if(trim(attvalue) .NE.
"FALSE")
then
199 '/get_great_circle_algorithm value of global attribute "great_circle_algorthm" in file'// &
200 trim(
grid_file)//
' should be TRUE or FALSE')
207 type(fmsnetcdffile_t),
intent(out) :: myfileobj
208 character(len=*),
intent(in) :: myfilename
209 if(.not.
open_file(myfileobj, myfilename,
'read'))
then
210 call mpp_error(fatal,
'grid2_mod(open_grid_file):Error in opening file '//trim(myfilename))
216 type(fmsnetcdffile_t),
intent(out) :: mymosaicfileobj
217 character(len=3),
intent(in) :: component
219 character(len=FMS_PATH_LEN) :: mosaicfilename
221 call read_data(gridfileobj,trim(lowercase(component))//
'_mosaic_file', mosaicfilename)
228 type(fmsnetcdffile_t),
intent(in) :: thisfileobj
229 character(len=*),
intent(in) :: filevar
230 integer,
intent(in) :: level
231 integer,
dimension(2) :: file_list_size
233 character(len=FMS_PATH_LEN),
dimension(:),
allocatable :: file_names
235 call get_variable_size(thisfileobj, filevar, file_list_size)
236 allocate(file_names(file_list_size(2)))
237 call read_data(thisfileobj, filevar, file_names)
239 deallocate(file_names)
245 type(fmsnetcdffile_t),
intent(in) :: fileobj
249 if(variable_exists(fileobj,
'geolon_t'))
then
251 else if(variable_exists(fileobj,
'x_T'))
then
253 else if(variable_exists(fileobj,
'ocn_mosaic_file') )
then
255 else if(variable_exists(fileobj,
'gridfiles') )
then
258 call mpp_error(fatal, module_name//
'/get_grid_version Can''t determine the version of the grid spec:'// &
259 &
' none of "x_T", "geolon_t", or "ocn_mosaic_file" exist in file "'//trim(
grid_file)//
'"')
266 mosaic_fileobj(1) = gridfileobj
267 mosaic_fileobj(2) = gridfileobj
268 mosaic_fileobj(3) = gridfileobj
273 if (variable_exists(gridfileobj,
'atm_mosaic_file'))
call open_mosaic_file(mosaic_fileobj(1),
'atm')
274 if (variable_exists(gridfileobj,
'ocn_mosaic_file'))
call open_mosaic_file(mosaic_fileobj(2),
'ocn')
275 if (variable_exists(gridfileobj,
'lnd_mosaic_file'))
call open_mosaic_file(mosaic_fileobj(3),
'lnd')
280 if (variable_exists(gridfileobj,
'atm_mosaic_file'))
call close_file(mosaic_fileobj(1))
281 if (variable_exists(gridfileobj,
'ocn_mosaic_file'))
call close_file(mosaic_fileobj(2))
282 if (variable_exists(gridfileobj,
'lnd_mosaic_file'))
call close_file(mosaic_fileobj(3))
288 character(len=*),
intent(in) :: component
290 select case(lowercase(component))
302 character(len=*) :: component
303 integer,
intent(out) :: ntiles
316 character(len=*) :: component
317 integer,
intent(inout) :: nx(:),ny(:)
321 character(len=MAX_NAME) :: varname1
324 varname1 =
'AREA_'//trim(uppercase(component))
328 call get_variable_size(gridfileobj, varname1, siz)
329 nx(1) = siz(1); ny(1)=siz(2)
337 character(len=*) :: component
338 integer,
intent(in) :: tile
339 integer,
intent(inout) :: nx,ny
342 integer,
allocatable :: nnx(:), nny(:)
347 if(tile>0.and.tile<=ntiles)
then
348 allocate(nnx(ntiles),nny(ntiles))
350 nx = nnx(tile); ny = nny(tile)
354 'requested tile index '//trim(
string(tile))//
' is out of bounds (1:'//trim(
string(ntiles))//
')')
361 character(len=*) ,
intent(in) :: component
362 type(
domain2d) ,
intent(inout) :: domain
363 integer ,
intent(in) :: layout(2)
364 integer,
optional,
intent(in) :: halo
365 logical,
optional,
intent(in) :: maskmap(:,:,:)
371 integer :: ng, pe_pos, npes
372 integer,
allocatable :: nlon(:), nlat(:), global_indices(:,:)
373 integer,
allocatable :: pe_start(:), pe_end(:), layout_2d(:,:)
374 integer,
allocatable :: tile1(:),tile2(:)
375 integer,
allocatable :: is1(:),ie1(:),js1(:),je1(:)
376 integer,
allocatable :: is2(:),ie2(:),js2(:),je2(:)
380 allocate(nlon(ntiles), nlat(ntiles))
381 allocate(global_indices(4,ntiles))
382 allocate(pe_start(ntiles),pe_end(ntiles))
383 allocate(layout_2d(2,ntiles))
386 pe_pos = mpp_root_pe()
388 global_indices(:,n) = (/ 1, nlon(n), 1, nlat(n) /)
389 layout_2d(:,n) = layout
390 if(
present(maskmap))
then
391 npes = count(maskmap(:,:,n))
393 npes = layout(1)*layout(2)
396 pe_end(n) = pe_pos + npes - 1
397 pe_pos = pe_end(n) + 1
402 allocate(tile1(ncontacts),tile2(ncontacts))
403 allocate(is1(ncontacts),ie1(ncontacts),js1(ncontacts),je1(ncontacts))
404 allocate(is2(ncontacts),ie2(ncontacts),js2(ncontacts),je2(ncontacts))
406 is1, ie1, js1, je1, is2, ie2, js2, je2)
409 if(
present(halo)) ng = halo
412 ntiles, ncontacts, tile1, tile2, &
413 is1, ie1, js1, je1, &
414 is2, ie2, js2, je2, &
415 pe_start=pe_start, pe_end=pe_end, symmetry=.true., &
416 shalo = ng, nhalo = ng, whalo = ng, ehalo = ng, &
418 name = trim(component)//
'Cubic-Sphere Grid' )
420 deallocate(nlon,nlat,global_indices,pe_start,pe_end,layout_2d)
421 deallocate(tile1,tile2)
422 deallocate(is1,ie1,js1,je1)
423 deallocate(is2,ie2,js2,je2)
426 #include "grid2_r4.fh"
427 #include "grid2_r8.fh"
Close a netcdf or domain file opened with open_file or open_virtual_file.
Opens a given netcdf or domain file.
Read data from a defined field in a file.
character(:) function, allocatable, public string(v, fmt)
Converts a number or a Boolean value to a string.
integer grid_version
Value to indicate what type of grid file is being read, based on which variables are present.
integer, parameter version_gridfiles
indicates gridfiles variable is present in grid_file
subroutine, public grid_end
Shutdown the grid2 module.
subroutine, public grid_init
Initialize the grid2 module.
subroutine open_mosaic_file(mymosaicfileobj, component)
Open a mosaic file.
integer function get_component_number(component)
Get the component number of a model component (atm, lnd, ocn)
integer, parameter version_ocn_mosaic_file
indicates ocn_mosaic_file variable is present in grid_file
integer, parameter version_geolon_t
indicates gelon_t variable is present in grid_file
character(len=fms_path_len) function read_file_name(thisfileobj, filevar, level)
Read a tile file name from a netcdf file.
subroutine open_component_mosaics
Open the component mosaic files for atm, lnd, and ocn.
subroutine, public get_grid_ntiles(component, ntiles)
returns number of tiles for a given component
subroutine assign_component_mosaics
Assign the component mosaic files if grid_spec is Version 3.
character(len= *), parameter grid_dir
root directory for all grid files
integer, parameter version_x_t
indicates x_t variable is present in grid_file
subroutine open_grid_file(myfileobj, myfilename)
Open a grid file.
subroutine close_component_mosaics
Close the component mosaic files for atm, lnd, and ocn.
integer, parameter bufsize
This is used to control memory usage in get_grid_comp_area We may change this to a namelist variable ...
subroutine init_checks(subroutine_name)
Checks that the grid2 module was initialized propertly.
subroutine get_grid_size_for_one_tile(component, tile, nx, ny)
returns size of the grid for one of the tiles
integer, parameter max_name
max length of the variable names
character(len= *), parameter grid_file
name of the grid spec file
integer function get_grid_version(fileobj)
Get the grid version from a file object.
subroutine, public define_cube_mosaic(component, domain, layout, halo, maskmap)
given a model component, a layout, and (optionally) a halo size, returns a domain for current process...
logical function, public get_great_circle_algorithm()
Determine if we are using the great circle algorithm.
subroutine get_grid_size_for_all_tiles(component, nx, ny)
returns size of the grid for each of the tiles
Finds area of a grid cell.
Gets arrays of global grid cell boundaries for given model component and mosaic tile number.
Gets the area of a given component per grid cell.
Gets the size of the grid for one or all tiles.
integer function, public get_mosaic_xgrid_size(fileobj)
return exchange grid size of mosaic xgrid file.
subroutine, public get_mosaic_contact(fileobj, tile1, tile2, istart1, iend1, jstart1, jend1, istart2, iend2, jstart2, jend2)
Get contact information from mosaic_file Example usage: call get_mosaic_contact(mosaic_file,...
integer function, public get_mosaic_ntiles(fileobj)
Get number of tiles in the mosaic_file.
integer function, public get_mosaic_ncontacts(fileobj)
Get number of contacts in the mosaic_file.
subroutine, public get_mosaic_grid_sizes(fileobj, nx, ny)
Get grid size of each tile from mosaic_file.
subroutine mpp_define_mosaic(global_indices, layout, domain, num_tile, num_contact, tile1, tile2, istart1, iend1, jstart1, jend1, istart2, iend2, jstart2, jend2, pe_start, pe_end, pelist, whalo, ehalo, shalo, nhalo, xextent, yextent, maskmap, name, memory_size, symmetry, xflags, yflags, tile_id)
Defines a domain for mosaic tile grids.
These routines retrieve the axis specifications associated with the compute domains....
These routines retrieve the axis specifications associated with the global domains....
Passes data from a structured grid to an unstructured grid Example usage:
The domain2D type contains all the necessary information to define the global, compute and data domai...
Domain information for managing data on unstructured grids.