25 subroutine mpp_define_unstruct_domain(UG_domain, SG_domain, npts_tile, grid_nlev, ndivs, npes_io_group, &
27 type(domainUG),
intent(inout) :: UG_domain
28 type(domain2d),
target,
intent(in) :: SG_domain
29 integer,
intent(in) :: npts_tile(:)
30 integer,
intent(in) :: grid_nlev(:)
31 integer,
intent(in) :: ndivs
32 integer,
intent(in) :: npes_io_group
35 integer,
intent(in) :: grid_index(:)
36 character(len=*),
optional,
intent(in) :: name
37 integer,
dimension(size(npts_tile(:))) :: ndivs_tile, pe_start, pe_end
38 integer,
dimension(0:ndivs-1) :: ibegin, iend, costs_list
39 integer :: ntiles, ndivs_used, cur_tile
40 integer :: n, ts, te, p, pos, tile_id, ngroup, group_id, my_pos, i
41 integer :: npes_in_group, is, ie, ntotal_costs, max_cost, cur_cost, costs_left
42 integer :: npts_left, ndiv_left, cur_pos, ndiv, prev_cost, ioff
44 integer :: costs(size(npts_tile(:)))
46 ug_domain%SG_domain => sg_domain
47 ntiles =
size(npts_tile(:))
48 ug_domain%ntiles = ntiles
51 if(sum(npts_tile)<ndivs)
call mpp_error(fatal, &
52 &
"mpp_define_unstruct_domain: total number of points is less than ndivs")
54 do n = 1,
size(grid_nlev(:))
55 if(grid_nlev(n) < 1)
call mpp_error(fatal, &
56 &
"mpp_define_unstruct_domain: grid_nlev at some point is less than 1")
63 do i = 1, npts_tile(n)
65 costs(n) = costs(n) + grid_nlev(pos)
69 ntotal_costs = sum(costs)
72 ndivs_tile(n) = ceiling(real(costs(n)*ndivs)/ntotal_costs)
75 ndivs_used = sum(ndivs_tile)
76 do while (ndivs_used > ndivs)
80 if( ndivs_tile(n) > 1 )
then
81 cur_cost = ceiling(real(costs(n))/(ndivs_tile(n)-1))
82 if( max_cost == 0 .OR. cur_cost<max_cost)
then
88 ndivs_used = ndivs_used-1
89 ndivs_tile(cur_tile) = ndivs_tile(cur_tile) - 1
96 te = ts + ndivs_tile(n) - 1
98 ndiv_left = ndivs_tile(n)
99 npts_left = npts_tile(n)
101 do ndiv = 1, ndivs_tile(n)
103 ibegin(ts+ndiv-1) = cur_pos
104 avg_cost = real(costs_left)/ndiv_left
105 do i = cur_pos, npts_tile(n)
106 cur_cost = cur_cost + grid_nlev(i+ioff)
107 costs_left = costs_left - grid_nlev(i+ioff)
108 if(npts_left < ndiv_left )
then
109 call mpp_error(fatal,
"mpp_define_unstruct_domain: npts_left < ndiv_left")
110 else if(npts_left == ndiv_left )
then
113 else if(cur_cost .GE. avg_cost)
then
114 prev_cost = cur_cost - grid_nlev(i+ioff)
118 else if( cur_cost - avg_cost .LE. avg_cost - prev_cost )
then
124 costs_left = costs_left + grid_nlev(i+ioff)
125 npts_left = npts_left+1
129 npts_left = npts_left-1
131 iend(ts+ndiv-1) = cur_pos - 1
132 costs_list(ts+ndiv-1) = cur_cost
133 ndiv_left = ndiv_left-1
134 npts_left = npts_left-1
138 ioff = ioff+ npts_tile(n)
140 if (
associated(ug_domain%list))
deallocate(ug_domain%list)
141 allocate(ug_domain%list(0:ndivs-1))
143 ug_domain%list(p)%compute%begin = ibegin(p)
144 ug_domain%list(p)%compute%end = iend(p)
145 ug_domain%list(p)%compute%size = ug_domain%list(p)%compute%end - ug_domain%list(p)%compute%begin + 1
146 ug_domain%list(p)%compute%max_size = 0
147 ug_domain%list(p)%pos = p
148 ug_domain%list(p)%pe = p + mpp_root_pe()
151 if( p .GE. pe_start(n) .AND. p .LE. pe_end(n) )
then
152 ug_domain%list(p)%tile_id = n
155 pos = pos + npts_tile(n)
157 is = ug_domain%list(p)%compute%begin+pos
158 ie = ug_domain%list(p)%compute%end+pos
159 ug_domain%list(p)%compute%begin_index = minval(grid_index(is:ie))
160 ug_domain%list(p)%compute%end_index = maxval(grid_index(is:ie))
164 if(mpp_pe() == mpp_root_pe() .and.
present(name))
then
165 write(stdout(),*)
"unstruct domain name = ", trim(name)
166 write(stdout(),*) ug_domain%list(:)%compute%size
169 pos = mpp_pe() - mpp_root_pe()
170 ug_domain%pe = mpp_pe()
172 ug_domain%tile_id = ug_domain%list(pos)%tile_id
173 p = pe_start(ug_domain%tile_id)
174 ug_domain%tile_root_pe = ug_domain%list(p)%pe
175 ug_domain%tile_npes = pe_end(ug_domain%tile_id) - pe_start(ug_domain%tile_id) + 1
176 ug_domain%compute = ug_domain%list(pos)%compute
177 ug_domain%compute%max_size = maxval( ug_domain%list(:)%compute%size )
178 ug_domain%global%begin = 1
179 ug_domain%global%end = npts_tile(ug_domain%tile_id)
180 ug_domain%global%size = ug_domain%global%end - ug_domain%global%begin + 1
181 ug_domain%global%max_size = -1
183 do n = 1, ug_domain%tile_id-1
184 pos = pos + npts_tile(n)
186 ug_domain%global%begin_index = grid_index(pos+1)
187 ug_domain%global%end_index = grid_index(pos+npts_tile(n))
189 if (
associated(ug_domain%grid_index))
deallocate(ug_domain%grid_index)
190 allocate(ug_domain%grid_index(ug_domain%compute%size))
191 do n = 1, ug_domain%compute%size
192 ug_domain%grid_index(n) = grid_index(pos+ug_domain%compute%begin+n-1)
196 if (
associated(ug_domain%io_domain))
deallocate(ug_domain%io_domain)
197 allocate(ug_domain%io_domain)
198 tile_id = ug_domain%tile_id
199 ug_domain%io_domain%pe = ug_domain%pe
201 if(npes_io_group == 0)
then
204 ngroup = ceiling(real(ndivs_tile(tile_id))/ npes_io_group)
209 ug_domain%npes_io_group = npes_io_group
210 ug_domain%io_layout = ngroup
213 call mpp_compute_extent(1, ndivs_tile(tile_id), ngroup, ibegin(0:ngroup-1), iend(0:ngroup-1))
214 my_pos = ug_domain%pe - ug_domain%tile_root_pe + 1
216 if( my_pos .GE. ibegin(n) .AND. my_pos .LE. iend(n) )
then
222 ug_domain%io_domain%tile_id = group_id+1
223 ug_domain%io_domain%compute = ug_domain%compute
224 ug_domain%io_domain%pe = ug_domain%pe
225 ug_domain%io_domain%pos = my_pos - ibegin(group_id) + 1
226 ug_domain%io_domain%tile_root_pe = ibegin(group_id) + ug_domain%tile_root_pe - 1
227 pos = ug_domain%io_domain%tile_root_pe - mpp_root_pe()
228 ug_domain%io_domain%global%begin = ug_domain%list(pos)%compute%begin
229 ug_domain%io_domain%global%begin_index = ug_domain%list(pos)%compute%begin_index
230 pos = iend(group_id) + ug_domain%tile_root_pe - mpp_root_pe() - 1
231 ug_domain%io_domain%global%end = ug_domain%list(pos)%compute%end
232 ug_domain%io_domain%global%end_index = ug_domain%list(pos)%compute%end_index
233 ug_domain%io_domain%global%size = ug_domain%io_domain%global%end - ug_domain%io_domain%global%begin + 1
235 npes_in_group = iend(group_id) - ibegin(group_id) + 1
236 if (
associated(ug_domain%io_domain%list))
deallocate(ug_domain%io_domain%list)
237 allocate(ug_domain%io_domain%list(0:npes_in_group-1))
238 do n = 0, npes_in_group-1
239 pos = ug_domain%io_domain%tile_root_pe - mpp_root_pe() + n
240 ug_domain%io_domain%list(n)%compute = ug_domain%list(pos)%compute
241 ug_domain%io_domain%list(n)%pos = n
242 ug_domain%io_domain%list(n)%pe = ug_domain%list(pos)%pe
243 ug_domain%io_domain%list(n)%tile_id = group_id+1
246 call compute_overlap_sg2ug(ug_domain, sg_domain)
247 call compute_overlap_ug2sg(ug_domain)
251 end subroutine mpp_define_unstruct_domain
255 subroutine compute_overlap_sg2ug(UG_domain, SG_domain)
256 type(domainUG),
intent(inout) :: UG_domain
257 type(domain2d),
intent(in) :: SG_domain
258 integer,
dimension(0:size(SG_domain%list(:))-1) :: send_cnt, recv_cnt
259 integer,
dimension(0:size(SG_domain%list(:))-1) :: send_buffer_pos, recv_buffer_pos
260 integer,
dimension(:),
allocatable :: send_buffer, recv_buffer, index_list
261 integer,
dimension(:),
allocatable :: buffer_pos
262 integer :: tile_id, nlist, nxg, begin_index, end_index, i, j
263 integer :: m, n, list, l, isc, iec, jsc, jec, ibegin, iend, grid_index
264 integer :: nrecv, nsend, send_pos, recv_pos, pos
267 tile_id = ug_domain%tile_id
268 nlist =
size(sg_domain%list(:))
269 nxg = sg_domain%x(1)%global%size
270 begin_index = ug_domain%compute%begin_index
271 end_index = ug_domain%compute%end_index
274 allocate(index_list(ug_domain%compute%size))
275 allocate(send_buffer(ug_domain%compute%size))
278 if(sg_domain%list(n)%tile_id(1) .NE. tile_id) cycle
279 isc = sg_domain%list(n)%x(1)%compute%begin; iec = sg_domain%list(n)%x(1)%compute%end
280 jsc = sg_domain%list(n)%y(1)%compute%begin; jec = sg_domain%list(n)%y(1)%compute%end
281 ibegin = (jsc-1)*nxg + isc
282 iend = (jec-1)*nxg + iec
283 if(ibegin > end_index .OR. iend < begin_index) cycle
284 do l = 1, ug_domain%compute%size
285 grid_index = ug_domain%grid_index(l)
286 i = mod((grid_index-1), nxg) + 1
287 j = (grid_index-1)/nxg + 1
288 if( i .GE. isc .AND. i .LE. iec .and. j .GE. jsc .AND. j .LE. jec )
then
289 recv_cnt(n) = recv_cnt(n) + 1
291 if(pos > ug_domain%compute%size)
call mpp_error(fatal, &
292 'compute_overlap_SG2UG: pos > UG_domain%compute%size')
294 send_buffer(pos) = grid_index
300 if( ug_domain%compute%size .NE. sum(recv_cnt) )
then
301 print*,
"pe=", mpp_pe(), ug_domain%compute%size, sum(recv_cnt)
302 call mpp_error(fatal, &
303 .NE.
"compute_overlap_SG2UG: UG_domain%compute%size sum(recv_cnt)")
305 allocate(buffer_pos(0:nlist-1))
308 buffer_pos(list) = pos
309 pos = pos + recv_cnt(list)
312 nrecv = count( recv_cnt > 0 )
313 ug_domain%SG2UG%nrecv = nrecv
314 if (
associated(ug_domain%SG2UG%recv))
deallocate(ug_domain%SG2UG%recv)
315 allocate(ug_domain%SG2UG%recv(nrecv))
319 m = mod( sg_domain%pos+nlist-list, nlist )
320 if( recv_cnt(m) > 0 )
then
322 ug_domain%SG2UG%recv(nrecv)%count = recv_cnt(m)
323 ug_domain%SG2UG%recv(nrecv)%pe = ug_domain%list(m)%pe
324 allocate(ug_domain%SG2UG%recv(nrecv)%i(recv_cnt(m)))
326 do l = 1, recv_cnt(m)
328 ug_domain%SG2UG%recv(nrecv)%i(l) = index_list(pos)
336 call mpp_alltoall(send_cnt,1,recv_cnt,1)
338 if( ug_domain%compute%size .NE. sum(send_cnt) )
call mpp_error(fatal, &
339 .NE.
"compute_overlap_SG2UG: UG_domain%compute%size sum(send_cnt)")
340 allocate(recv_buffer(sum(recv_cnt)))
341 send_buffer_pos = 0; recv_buffer_pos = 0
342 send_pos = 0; recv_pos = 0
344 if(send_cnt(n) > 0)
then
345 send_buffer_pos(n) = send_pos
346 send_pos = send_pos + send_cnt(n)
348 if(recv_cnt(n) > 0)
then
349 recv_buffer_pos(n) = recv_pos
350 recv_pos = recv_pos + recv_cnt(n)
354 call mpp_alltoall(send_buffer, send_cnt, send_buffer_pos, &
355 recv_buffer, recv_cnt, recv_buffer_pos)
357 nsend = count( recv_cnt(:) > 0 )
358 ug_domain%SG2UG%nsend = nsend
359 if (
associated(ug_domain%SG2UG%send))
deallocate(ug_domain%SG2UG%send)
360 allocate(ug_domain%SG2UG%send(nsend))
362 isc = sg_domain%x(1)%compute%begin
363 jsc = sg_domain%y(1)%compute%begin
365 m = mod( sg_domain%pos+list, nlist )
366 if( recv_cnt(m) > 0 )
then
368 ug_domain%SG2UG%send(nsend)%count = recv_cnt(m)
369 ug_domain%SG2UG%send(nsend)%pe = ug_domain%list(m)%pe
370 allocate(ug_domain%SG2UG%send(nsend)%i(recv_cnt(m)))
371 allocate(ug_domain%SG2UG%send(nsend)%j(recv_cnt(m)))
372 pos = recv_buffer_pos(m)
373 do l = 1, recv_cnt(m)
374 grid_index = recv_buffer(pos+l)
375 ug_domain%SG2UG%send(nsend)%i(l) = mod(grid_index-1,nxg) + 1
376 ug_domain%SG2UG%send(nsend)%j(l) = (grid_index-1)/nxg + 1
380 deallocate(send_buffer, recv_buffer, index_list, buffer_pos)
384 end subroutine compute_overlap_sg2ug
387 subroutine compute_overlap_ug2sg(UG_domain)
388 type(domainUG),
intent(inout) :: UG_domain
391 ug_domain%UG2SG%nsend = ug_domain%SG2UG%nrecv
392 ug_domain%UG2SG%send => ug_domain%SG2UG%recv
393 ug_domain%UG2SG%nrecv = ug_domain%SG2UG%nsend
394 ug_domain%UG2SG%recv => ug_domain%SG2UG%send
398 end subroutine compute_overlap_ug2sg
401 subroutine mpp_get_ug_sg_domain(UG_domain,SG_domain)
402 type(domainUG),
intent(inout) :: UG_domain
403 type(domain2d),
pointer :: SG_domain
405 sg_domain => ug_domain%SG_domain
409 end subroutine mpp_get_ug_sg_domain
412 function mpp_get_ug_io_domain(domain)
413 type(domainUG),
intent(in) :: domain
414 type(domainUG),
pointer :: mpp_get_UG_io_domain
416 if(
ASSOCIATED(domain%io_domain))
then
417 mpp_get_ug_io_domain => domain%io_domain
419 call mpp_error(fatal,
"mpp_get_UG_io_domain: io_domain is not defined, contact developer")
422 end function mpp_get_ug_io_domain
425 subroutine mpp_get_ug_compute_domain( domain, begin, end, size)
426 type(domainUG),
intent(in) :: domain
427 integer,
intent(out),
optional :: begin, end, size
429 if(
PRESENT(begin) )begin = domain%compute%begin
430 if(
PRESENT(
end) )end = domain%compute%end
431 if(
PRESENT(size) )
size = domain%compute%size
433 end subroutine mpp_get_ug_compute_domain
436 subroutine mpp_get_ug_global_domain( domain, begin, end, size)
437 type(domainUG),
intent(in) :: domain
438 integer,
intent(out),
optional :: begin, end, size
440 if(
PRESENT(begin) )begin = domain%global%begin
441 if(
PRESENT(
end) )end = domain%global%end
442 if(
PRESENT(size) )
size = domain%global%size
444 end subroutine mpp_get_ug_global_domain
447 subroutine mpp_get_ug_compute_domains( domain, begin, end, size )
448 type(domainUG),
intent(in) :: domain
449 integer,
intent(out),
optional,
dimension(:) :: begin, end, size
452 if(
PRESENT(begin) )
then
453 if( any(shape(begin).NE.shape(domain%list)) ) &
454 call mpp_error( fatal,
'mpp_get_UG_compute_domains: begin array size does not match domain.' )
455 begin(:) = domain%list(:)%compute%begin
457 if(
PRESENT(
end) )then
458 if( any(shape(
end).NE.shape(domain%list)) ) &
459 call mpp_error( fatal,
'mpp_get_UG_compute_domains: end array size does not match domain.' )
460 end(:) = domain%list(:)%compute%end
462 if(
PRESENT(size) )
then
463 if( any(shape(size).NE.shape(domain%list)) ) &
464 call mpp_error( fatal,
'mpp_get_UG_compute_domains: size array size does not match domain.' )
465 size(:) = domain%list(:)%compute%size
468 end subroutine mpp_get_ug_compute_domains
471 subroutine mpp_get_ug_domains_index( domain, begin, end)
472 type(domainUG),
intent(in) :: domain
473 integer,
intent(out),
dimension(:) :: begin, end
476 if( any(shape(begin).NE.shape(domain%list)) ) &
477 call mpp_error( fatal,
'mpp_get_UG_compute_domains: begin array size does not match domain.' )
478 begin(:) = domain%list(:)%compute%begin_index
479 if( any(shape(
end).NE.shape(domain%list)) ) &
480 call mpp_error( fatal,
'mpp_get_UG_compute_domains: end array size does not match domain.' )
481 end(:) = domain%list(:)%compute%end_index
483 end subroutine mpp_get_ug_domains_index
486 function mpp_get_ug_domain_ntiles(domain)
487 type(domainUG),
intent(in) :: domain
488 integer :: mpp_get_UG_domain_ntiles
490 mpp_get_ug_domain_ntiles = domain%ntiles
492 end function mpp_get_ug_domain_ntiles
495 subroutine mpp_get_ug_domain_tile_list(domain, tiles)
496 type(domainUG),
intent(in) :: domain
497 integer,
intent(inout) :: tiles(:)
500 if(
size(tiles(:)).NE.
size(domain%list(:)) ) &
501 call mpp_error( fatal,
'mpp_get_ug_domain_tile_list: tiles array size does not match domain.' )
502 do i = 1,
size(tiles(:))
503 tiles(i) = domain%list(i-1)%tile_id
506 end subroutine mpp_get_ug_domain_tile_list
509 function mpp_get_ug_domain_tile_id(domain)
510 type(domainUG),
intent(in) :: domain
511 integer :: mpp_get_UG_domain_tile_id
513 mpp_get_ug_domain_tile_id = domain%tile_id
515 end function mpp_get_ug_domain_tile_id
518 function mpp_get_ug_domain_npes(domain)
519 type(domainUG),
intent(in) :: domain
520 integer :: mpp_get_UG_domain_npes
522 mpp_get_ug_domain_npes =
size(domain%list(:))
525 end function mpp_get_ug_domain_npes
529 subroutine mpp_get_ug_domain_pelist( domain, pelist)
530 type(domainUG),
intent(in) :: domain
531 integer,
intent(out) :: pelist(:)
533 if(
size(pelist(:)).NE.
size(domain%list(:)) ) &
534 call mpp_error( fatal,
'mpp_get_UG_domain_pelist: pelist array size does not match domain.' )
536 pelist(:) = domain%list(:)%pe
539 end subroutine mpp_get_ug_domain_pelist
542 subroutine mpp_get_ug_domain_tile_pe_inf( domain, root_pe, npes, pelist)
543 type(domainUG),
intent(in) :: domain
544 integer,
optional,
intent(out) :: root_pe, npes
545 integer,
optional,
intent(out) :: pelist(:)
547 if(
present(root_pe)) root_pe = domain%tile_root_pe
548 if(
present(npes)) npes = domain%tile_npes
550 if(
present(pelist))
then
551 if(
size(pelist(:)).NE. domain%tile_npes ) &
552 call mpp_error( fatal,
'mpp_get_UG_domain_tile_pe_inf: pelist array size does not match domain.' )
553 pelist(:) = domain%list(domain%pos:domain%pos+domain%tile_npes-1)%pe
557 end subroutine mpp_get_ug_domain_tile_pe_inf
561 subroutine mpp_get_ug_domain_grid_index( domain, grid_index)
562 type(domainUG),
intent(in) :: domain
563 integer,
intent(out) :: grid_index(:)
565 if(
size(grid_index(:)).NE.
size(domain%grid_index(:)) ) &
566 call mpp_error( fatal,
'mpp_get_UG_domain_grid_index: grid_index array size does not match domain.' )
568 grid_index(:) = domain%grid_index(:)
571 end subroutine mpp_get_ug_domain_grid_index
574 subroutine mpp_define_null_ug_domain(domain)
575 type(domainUG),
intent(inout) :: domain
577 domain%global%begin = -1; domain%global%end = -1; domain%global%size = 0
578 domain%compute%begin = -1; domain%compute%end = -1; domain%compute%size = 0
583 domain%tile_root_pe = -1
585 end subroutine mpp_define_null_ug_domain
589 subroutine mpp_broadcast_domain_ug( domain )
590 type(domainUG),
intent(inout) :: domain
591 integer,
allocatable :: pes(:)
593 integer :: listsize, listpos
595 integer,
dimension(7) :: msg, info
599 if( .NOT.module_is_initialized ) &
600 call mpp_error( fatal,
'MPP_BROADCAST_DOMAIN_ug: You must first call mpp_domains_init.' )
603 allocate( pes(0:mpp_npes()-1) )
604 call mpp_get_current_pelist(pes)
607 native =
ASSOCIATED(domain%list)
611 listsize =
size(domain%list(:))
615 call mpp_max(listsize)
617 if( .NOT.native )
then
619 if (
associated(domain%list))
deallocate(domain%list)
620 allocate( domain%list(0:listsize-1) )
624 domain%compute%begin = 1
625 domain%compute%end = -1
626 domain%compute%begin_index = 1
627 domain%compute%end_index = -1
628 domain%global %begin = -1
629 domain%global %end = -1
631 domain%tile_root_pe = -1
636 info(3) = domain%tile_id
637 call mpp_get_ug_compute_domain( domain, info(4), info(5))
638 info(6) = domain%compute%begin_index
639 info(7) = domain%compute%end_index
642 do n = 0,mpp_npes()-1
644 if( mpp_pe().EQ.pes(n) .AND. debug )
write( errunit,* )
'PE ', mpp_pe(),
'broadcasting msg ', msg
645 call mpp_broadcast( msg, 7, pes(n) )
648 if( .NOT.native .AND. msg(1).NE.null_pe )
then
649 domain%list(listpos)%pe = msg(1)
650 domain%list(listpos)%pos = msg(2)
651 domain%list(listpos)%tile_id = msg(3)
652 domain%list(listpos)%compute%begin = msg(4)
653 domain%list(listpos)%compute%end = msg(5)
654 domain%list(listpos)%compute%begin_index = msg(6)
655 domain%list(listpos)%compute%end_index = msg(7)
656 listpos = listpos + 1
657 if( debug )
write( errunit,* )
'PE ', mpp_pe(),
'received domain from PE ', msg(1),
'ls,le=', msg(4:5)
661 end subroutine mpp_broadcast_domain_ug
664function mpp_domain_ug_is_tile_root_pe(domain)
result(is_root)
667 type(domainUG),
intent(in) :: domain
668 logical(l8_kind) :: is_root
670 if (domain%pe .eq. domain%tile_root_pe)
then
677end function mpp_domain_ug_is_tile_root_pe
683function mpp_get_io_domain_ug_layout(domain)
result(io_layout)
686 type(domainUG),
intent(in) :: domain
687 integer(i4_kind) :: io_layout
689 io_layout = domain%io_layout
696subroutine deallocate_unstruct_overlap_type(overlap)
697 type(unstruct_overlap_type),
intent(inout) :: overlap
699 if(
associated(overlap%i))
deallocate(overlap%i)
700 if(
associated(overlap%j))
deallocate(overlap%j)
702end subroutine deallocate_unstruct_overlap_type
705subroutine deallocate_unstruct_pass_type(domain)
706 type(domainUG),
intent(inout) :: domain
709 do n = 1, domain%UG2SG%nsend
710 call deallocate_unstruct_overlap_type(domain%UG2SG%send(n))
712 do n = 1, domain%UG2SG%nrecv
713 call deallocate_unstruct_overlap_type(domain%UG2SG%recv(n))
719 if(
associated(domain%UG2SG%send))
then
720 deallocate(domain%UG2SG%send)
721 nullify(domain%UG2SG%send)
722 nullify(domain%SG2UG%recv)
724 if(
associated(domain%UG2SG%recv))
then
725 deallocate(domain%UG2SG%recv)
726 nullify(domain%UG2SG%recv)
727 nullify(domain%SG2UG%send)
729end subroutine deallocate_unstruct_pass_type
732subroutine mpp_deallocate_domainug(domain)
735 type(domainUG),
intent(inout) :: domain
737 if (
associated(domain%list))
then
738 deallocate(domain%list)
739 domain%list => null()
742 if (
associated(domain%io_domain))
then
743 if (
associated(domain%io_domain%list))
then
744 deallocate(domain%io_domain%list)
745 domain%io_domain%list => null()
747 deallocate(domain%io_domain)
748 domain%io_domain => null()
751 call deallocate_unstruct_pass_type(domain)
753 if (
associated(domain%grid_index))
then
754 deallocate(domain%grid_index)
755 domain%grid_index => null()
758 if (
associated(domain%SG_domain))
then
759 domain%SG_domain => null()
763end subroutine mpp_deallocate_domainug
767 function mpp_domainug_eq( a, b )
768 logical :: mpp_domainUG_eq
769 type(domainUG),
intent(in) :: a, b
771 if (
associated(a%SG_domain) .and.
associated(b%SG_domain))
then
772 if (a%SG_domain .ne. b%SG_domain)
then
773 mpp_domainug_eq = .false.
776 elseif (
associated(a%SG_domain) .and. .not.
associated(b%SG_domain))
then
777 mpp_domainug_eq = .false.
779 elseif (.not.
associated(a%SG_domain) .and.
associated(b%SG_domain))
then
780 mpp_domainug_eq = .false.
784 mpp_domainug_eq = (a%npes_io_group .EQ. b%npes_io_group) .AND. &
785 (a%pos .EQ. b%pos) .AND. &
786 (a%ntiles .EQ. b%ntiles) .AND. &
787 (a%tile_id .EQ. b%tile_id) .AND. &
788 (a%tile_npes .EQ. b%tile_npes) .AND. &
789 (a%tile_root_pe .EQ. b%tile_root_pe)
791 if(.not. mpp_domainug_eq)
return
793 mpp_domainug_eq = ( a%compute%begin.EQ.b%compute%begin .AND. &
794 a%compute%end .EQ.b%compute%end .AND. &
795 a%global%begin .EQ.b%global%begin .AND. &
796 a%global%end .EQ.b%global%end .AND. &
797 a%SG2UG%nsend .EQ.b%SG2UG%nsend .AND. &
798 a%SG2UG%nrecv .EQ.b%SG2UG%nrecv .AND. &
799 a%UG2SG%nsend .EQ.b%UG2SG%nsend .AND. &
800 a%UG2SG%nrecv .EQ.b%UG2SG%nrecv &
804 end function mpp_domainug_eq
807 function mpp_domainug_ne( a, b )
808 logical :: mpp_domainUG_ne
809 type(domainUG),
intent(in) :: a, b
811 mpp_domainug_ne = .NOT. ( a.EQ.b )
813 end function mpp_domainug_ne
816#define MPP_TYPE_ real(r8_kind)
817#undef mpp_pass_SG_to_UG_2D_
818#define mpp_pass_SG_to_UG_2D_ mpp_pass_SG_to_UG_r8_2d
819#undef mpp_pass_SG_to_UG_3D_
820#define mpp_pass_SG_to_UG_3D_ mpp_pass_SG_to_UG_r8_3d
821#undef mpp_pass_UG_to_SG_2D_
822#define mpp_pass_UG_to_SG_2D_ mpp_pass_UG_to_SG_r8_2d
823#undef mpp_pass_UG_to_SG_3D_
824#define mpp_pass_UG_to_SG_3D_ mpp_pass_UG_to_SG_r8_3d
825#include <mpp_unstruct_pass_data.fh>
828#define MPP_TYPE_ real(r4_kind)
829#undef mpp_pass_SG_to_UG_2D_
830#define mpp_pass_SG_to_UG_2D_ mpp_pass_SG_to_UG_r4_2d
831#undef mpp_pass_SG_to_UG_3D_
832#define mpp_pass_SG_to_UG_3D_ mpp_pass_SG_to_UG_r4_3d
833#undef mpp_pass_UG_to_SG_2D_
834#define mpp_pass_UG_to_SG_2D_ mpp_pass_UG_to_SG_r4_2d
835#undef mpp_pass_UG_to_SG_3D_
836#define mpp_pass_UG_to_SG_3D_ mpp_pass_UG_to_SG_r4_3d
837#include <mpp_unstruct_pass_data.fh>
840#define MPP_TYPE_ integer(i4_kind)
841#undef mpp_pass_SG_to_UG_2D_
842#define mpp_pass_SG_to_UG_2D_ mpp_pass_SG_to_UG_i4_2d
843#undef mpp_pass_SG_to_UG_3D_
844#define mpp_pass_SG_to_UG_3D_ mpp_pass_SG_to_UG_i4_3d
845#undef mpp_pass_UG_to_SG_2D_
846#define mpp_pass_UG_to_SG_2D_ mpp_pass_UG_to_SG_i4_2d
847#undef mpp_pass_UG_to_SG_3D_
848#define mpp_pass_UG_to_SG_3D_ mpp_pass_UG_to_SG_i4_3d
849#include <mpp_unstruct_pass_data.fh>
852#define MPP_TYPE_ logical(i4_kind)
853#undef mpp_pass_SG_to_UG_2D_
854#define mpp_pass_SG_to_UG_2D_ mpp_pass_SG_to_UG_l4_2d
855#undef mpp_pass_SG_to_UG_3D_
856#define mpp_pass_SG_to_UG_3D_ mpp_pass_SG_to_UG_l4_3d
857#undef mpp_pass_UG_to_SG_2D_
858#define mpp_pass_UG_to_SG_2D_ mpp_pass_UG_to_SG_l4_2d
859#undef mpp_pass_UG_to_SG_3D_
860#define mpp_pass_UG_to_SG_3D_ mpp_pass_UG_to_SG_l4_3d
861#include <mpp_unstruct_pass_data.fh>
863#undef MPP_GLOBAL_FIELD_UG_2D_
864#define MPP_GLOBAL_FIELD_UG_2D_ mpp_global_field2D_ug_r8_2d
865#undef MPP_GLOBAL_FIELD_UG_3D_
866#define MPP_GLOBAL_FIELD_UG_3D_ mpp_global_field2D_ug_r8_3d
867#undef MPP_GLOBAL_FIELD_UG_4D_
868#define MPP_GLOBAL_FIELD_UG_4D_ mpp_global_field2D_ug_r8_4d
869#undef MPP_GLOBAL_FIELD_UG_5D_
870#define MPP_GLOBAL_FIELD_UG_5D_ mpp_global_field2D_ug_r8_5d
872#define MPP_TYPE_ real(r8_kind)
873#include <mpp_global_field_ug.fh>
875#undef MPP_GLOBAL_FIELD_UG_2D_
876#define MPP_GLOBAL_FIELD_UG_2D_ mpp_global_field2D_ug_i8_2d
877#undef MPP_GLOBAL_FIELD_UG_3D_
878#define MPP_GLOBAL_FIELD_UG_3D_ mpp_global_field2D_ug_i8_3d
879#undef MPP_GLOBAL_FIELD_UG_4D_
880#define MPP_GLOBAL_FIELD_UG_4D_ mpp_global_field2D_ug_i8_4d
881#undef MPP_GLOBAL_FIELD_UG_5D_
882#define MPP_GLOBAL_FIELD_UG_5D_ mpp_global_field2D_ug_i8_5d
884#define MPP_TYPE_ integer(i8_kind)
885#include <mpp_global_field_ug.fh>
887#undef MPP_GLOBAL_FIELD_UG_2D_
888#define MPP_GLOBAL_FIELD_UG_2D_ mpp_global_field2D_ug_r4_2d
889#undef MPP_GLOBAL_FIELD_UG_3D_
890#define MPP_GLOBAL_FIELD_UG_3D_ mpp_global_field2D_ug_r4_3d
891#undef MPP_GLOBAL_FIELD_UG_4D_
892#define MPP_GLOBAL_FIELD_UG_4D_ mpp_global_field2D_ug_r4_4d
893#undef MPP_GLOBAL_FIELD_UG_5D_
894#define MPP_GLOBAL_FIELD_UG_5D_ mpp_global_field2D_ug_r4_5d
896#define MPP_TYPE_ real(r4_kind)
897#include <mpp_global_field_ug.fh>
899#undef MPP_GLOBAL_FIELD_UG_2D_
900#define MPP_GLOBAL_FIELD_UG_2D_ mpp_global_field2D_ug_i4_2d
901#undef MPP_GLOBAL_FIELD_UG_3D_
902#define MPP_GLOBAL_FIELD_UG_3D_ mpp_global_field2D_ug_i4_3d
903#undef MPP_GLOBAL_FIELD_UG_4D_
904#define MPP_GLOBAL_FIELD_UG_4D_ mpp_global_field2D_ug_i4_4d
905#undef MPP_GLOBAL_FIELD_UG_5D_
906#define MPP_GLOBAL_FIELD_UG_5D_ mpp_global_field2D_ug_i4_5d
908#define MPP_TYPE_ integer(i4_kind)
909#include <mpp_global_field_ug.fh>
subroutine mpp_compute_extent(isg, ieg, ndivs, ibegin, iend, extent)
Computes extents for a grid decomposition with the given indices and divisions.