38 use constants_mod,
only : pi, radius
40 use fms2_io_mod,
only :
read_data, variable_exists
41 use platform_mod,
only : r4_kind, r8_kind, fms_path_len
46 character(len=*),
parameter :: &
49 integer,
parameter :: &
50 MAX_NAME = 256, & !> max length of the variable names
70 module procedure get_mosaic_xgrid_r4
71 module procedure get_mosaic_xgrid_r8
75 module procedure calc_mosaic_grid_area_r4
76 module procedure calc_mosaic_grid_area_r8
80 module procedure calc_mosaic_grid_great_circle_area_r4
81 module procedure calc_mosaic_grid_great_circle_area_r8
85 module procedure is_inside_polygon_r4
86 module procedure is_inside_polygon_r8
90 logical :: module_is_initialized = .true.
92 #include<file_version.h>
105 if (module_is_initialized)
return
106 module_is_initialized = .true.
119 type(fmsnetcdffile_t),
intent(in) :: fileobj
135 type(fmsnetcdffile_t),
intent(in) :: fileobj
151 type(fmsnetcdffile_t),
intent(in) :: fileobj
154 if(variable_exists(fileobj,
"contacts") )
then
173 type(fmsnetcdffile_t),
intent(in) :: fileobj
174 integer,
dimension(:),
intent(inout) :: nx, ny
176 character(len=FMS_PATH_LEN) :: gridfile
178 type(fmsnetcdffile_t) :: gridobj
181 if(ntiles .NE.
size(nx(:)) .OR. ntiles .NE.
size(ny(:)) )
then
182 call mpp_error(fatal,
"get_mosaic_grid_sizes: size of nx/ny does not equal to ntiles")
186 call read_data(fileobj,
'gridfiles', gridfile, corner=n)
187 gridfile = grid_dir//trim(gridfile)
189 if(.not.
open_file(gridobj, gridfile,
'read'))
then
190 call mpp_error(fatal,
'mosaic_mod(get_mosaic_grid_sizes):Error in opening file '//trim(gridfile))
192 call get_dimension_size(gridobj,
"nx", nx(n))
193 call get_dimension_size(gridobj,
"ny", ny(n))
195 if(mod(nx(n),x_refine) .NE. 0)
call mpp_error(fatal,
"get_mosaic_grid_sizes: nx is not divided by x_refine");
196 if(mod(ny(n),y_refine) .NE. 0)
call mpp_error(fatal,
"get_mosaic_grid_sizes: ny is not divided by y_refine");
197 nx(n) = nx(n)/x_refine;
198 ny(n) = ny(n)/y_refine;
222 istart2, iend2, jstart2, jend2)
223 type(fmsnetcdffile_t),
intent(in) :: fileobj
224 integer,
dimension(:),
intent(inout) :: tile1, tile2
225 integer,
dimension(:),
intent(inout) :: istart1, iend1, jstart1, jend1
226 integer,
dimension(:),
intent(inout) :: istart2, iend2, jstart2, jend2
227 character(len=MAX_NAME),
allocatable :: gridtiles(:)
228 character(len=MAX_NAME),
allocatable :: contacts(:)
229 character(len=MAX_NAME),
allocatable :: contacts_index(:)
230 character(len=MAX_NAME) :: strlist(8)
231 integer :: ntiles, n, m, ncontacts, nstr, ios
232 integer :: i1_type, j1_type, i2_type, j2_type
236 allocate(gridtiles(ntiles))
237 if(
mpp_pe()==mpp_root_pe())
then
240 gridtiles(n)(m:m) =
" "
244 call read_data(fileobj,
'gridtiles', gridtiles)
248 allocate(contacts(ncontacts), contacts_index(ncontacts))
249 if(
mpp_pe()==mpp_root_pe())
then
252 contacts(n)(m:m) =
" "
253 contacts_index(n)(m:m) =
" "
257 call read_data(fileobj,
"contacts", contacts)
258 call read_data(fileobj,
"contact_index", contacts_index)
261 nstr = parse_string(contacts(n),
":", strlist)
263 "mosaic_mod(get_mosaic_contact): number of elements in contact seperated by :/:: should be 4")
266 if(trim(gridtiles(m)) == trim(strlist(2)) )
then
274 "mosaic_mod(get_mosaic_contact):the first tile name specified in contact is not found in tile list")
278 if(trim(gridtiles(m)) == trim(strlist(4)) )
then
286 "mosaic_mod(get_mosaic_contact):the second tile name specified in contact is not found in tile list")
288 nstr = parse_string(contacts_index(n),
":,", strlist)
290 if(
mpp_pe()==mpp_root_pe())
then
291 print*,
"nstr is ", nstr
292 print*,
"contacts is ", contacts_index(n)
294 print*,
"strlist is ", trim(strlist(m))
298 "mosaic_mod(get_mosaic_contact): number of elements in contact_index seperated by :/, should be 8")
300 read(strlist(1), *, iostat=ios) istart1(n)
302 "mosaic_mod(get_mosaic_contact): Error in reading istart1")
303 read(strlist(2), *, iostat=ios) iend1(n)
305 "mosaic_mod(get_mosaic_contact): Error in reading iend1")
306 read(strlist(3), *, iostat=ios) jstart1(n)
308 "mosaic_mod(get_mosaic_contact): Error in reading jstart1")
309 read(strlist(4), *, iostat=ios) jend1(n)
311 "mosaic_mod(get_mosaic_contact): Error in reading jend1")
312 read(strlist(5), *, iostat=ios) istart2(n)
314 "mosaic_mod(get_mosaic_contact): Error in reading istart2")
315 read(strlist(6), *, iostat=ios) iend2(n)
317 "mosaic_mod(get_mosaic_contact): Error in reading iend2")
318 read(strlist(7), *, iostat=ios) jstart2(n)
320 "mosaic_mod(get_mosaic_contact): Error in reading jstart2")
321 read(strlist(8), *, iostat=ios) jend2(n)
323 "mosaic_mod(get_mosaic_contact): Error in reading jend2")
325 i1_type = transfer_to_model_index(istart1(n), iend1(n), x_refine)
326 j1_type = transfer_to_model_index(jstart1(n), jend1(n), y_refine)
327 i2_type = transfer_to_model_index(istart2(n), iend2(n), x_refine)
328 j2_type = transfer_to_model_index(jstart2(n), jend2(n), y_refine)
330 if( i1_type == 0 .AND. j1_type == 0 )
call mpp_error(fatal, &
331 "mosaic_mod(get_mosaic_contact): istart1==iend1 and jstart1==jend1")
332 if( i2_type == 0 .AND. j2_type == 0 )
call mpp_error(fatal, &
333 "mosaic_mod(get_mosaic_contact): istart2==iend2 and jstart2==jend2")
334 if( i1_type + j1_type .NE. i2_type + j2_type )
call mpp_error(fatal, &
335 "mosaic_mod(get_mosaic_contact): It is not a line or overlap contact")
339 deallocate(gridtiles)
340 if(ncontacts>0)
deallocate(contacts, contacts_index)
345 function transfer_to_model_index(istart, iend, refine_ratio)
346 integer,
intent(inout) :: istart, iend
347 integer :: refine_ratio
348 integer :: transfer_to_model_index
349 integer :: istart_in, iend_in
354 if( istart_in == iend_in )
then
355 transfer_to_model_index = 0
356 istart = (istart_in + 1)/refine_ratio
359 transfer_to_model_index = 1
360 if( iend_in > istart_in )
then
361 istart = istart_in + 1
367 if( mod(istart, refine_ratio) .NE. 0 .OR. mod(iend,refine_ratio) .NE. 0)
call mpp_error(fatal, &
368 "mosaic_mod(transfer_to_model_index): mismatch between refine_ratio and istart/iend")
369 istart = istart/refine_ratio
370 iend = iend/refine_ratio
376 end function transfer_to_model_index
378 function parse_string(string, set, sval)
379 character(len=*),
intent(in) :: string
380 character(len=*),
intent(in) :: set
381 character(len=*),
intent(out) :: sval(:)
382 integer :: parse_string
383 integer :: nelem, length, first, last
385 nelem =
size(sval(:))
386 length = len_trim(string)
391 do while(first .LE. length)
392 parse_string = parse_string + 1
393 if(parse_string>nelem)
then
394 call mpp_error(fatal,
"mosaic_mod(parse_string) : number of element is greater than size(sval(:))")
396 last = first - 1 + scan(string(first:length), set)
397 if(last == first-1 )
then
398 sval(parse_string) = string(first:length)
401 if(last <= first)
then
402 call mpp_error(fatal,
"mosaic_mod(parse_string) : last <= first")
404 sval(parse_string) = string(first:(last-1))
407 do while (first == last+1)
408 last = first - 1 + scan(string(first:length), set)
409 if(last == first)
then
420 end function parse_string
429 character(len=*),
intent(out) :: grid_file
430 type(fmsnetcdffile_t),
intent(in) :: fileobj
431 type(
domain2d),
intent(in) :: domain
432 integer,
intent(in),
optional :: tile_count
433 integer :: tile, ntileme
434 integer,
dimension(:),
allocatable :: tile_id
435 character(len=256),
allocatable :: filelist(:)
439 allocate(filelist(ntiles))
441 if(
present(tile_count)) tile = tile_count
443 allocate(tile_id(ntileme))
445 call read_data(fileobj,
"gridfiles", filelist)
446 grid_file =
'INPUT/'//trim(filelist(tile_id(tile)))
447 deallocate(tile_id, filelist)
451 #include "mosaic2_r4.fh"
452 #include "mosaic2_r8.fh"
454 end module mosaic2_mod
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.
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.
subroutine, public get_mosaic_tile_grid(grid_file, fileobj, domain, tile_count)
Gets the name of a mosaic tile grid file.
subroutine mosaic_init()
Initialize the mosaic_mod. Initialization routine for the mosaic module. It writes the version inform...
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.
integer function, dimension(size(domain%tile_id(:))) mpp_get_tile_id(domain)
Returns the tile_id on current pe.
integer function mpp_get_current_ntile(domain)
Returns number of tile on current pe.
The domain2D type contains all the necessary information to define the global, compute and data domai...
integer function mpp_pe()
Returns processor ID.