27 function mpp_redistribute_init_comm(domain_in,l_addrs_in, domain_out,l_addrs_out, &
28 isize_in,jsize_in,ksize_in,isize_out,jsize_out,ksize_out)
RESULT(d_comm)
29 type(DomainCommunicator2D),
pointer :: d_comm
30 type(domain2D),
target,
intent(in) :: domain_in
31 integer(i8_kind),
intent(in) :: l_addrs_in(:)
32 type(domain2D),
target,
intent(in) :: domain_out
33 integer(i8_kind),
intent(in) :: l_addrs_out(:)
34 integer,
intent(in) :: isize_in
35 integer,
intent(in) :: jsize_in
36 integer,
intent(in) :: ksize_in
37 integer,
intent(in) :: isize_out
38 integer,
intent(in) :: jsize_out
39 integer,
intent(in) :: ksize_out
41 integer(i8_kind) :: domain_id
43 integer :: is, ie, js, je, ke, ioff, joff, list_size
44 integer :: isc, iec, jsc, jec, mytile
45 integer :: lsize,rsize,msgsize,to_pe,from_pe
46 integer,
allocatable,
dimension(:) :: isL, jsL
47 integer(i8_kind),
allocatable,
dimension(:,:) :: slist_addr
48 character(len=8) :: text
63 if( domain_in%pe /= null_pe )ke = ksize_in
64 if( domain_out%pe /= null_pe )
then
65 if( ke /= 0 .AND. ke /= ksize_out ) &
66 call mpp_error( fatal,
'MPP_REDISTRIBUTE_INIT_COMM: mismatch between field_in and field_out.' )
69 if( ke == 0 )
call mpp_error( fatal, &
70 &
'MPP_REDISTRIBUTE_INIT_COMM: either domain_in or domain_out must be native.' )
72 if( domain_in%pe /= null_pe )
then
73 if( isize_in /= domain_in%x(1)%domain_data%size .OR. jsize_in /= domain_in%y(1)%domain_data%size ) &
74 call mpp_error( fatal,
'MPP_REDISTRIBUTE_INIT_COMM: field_in must be on data domain of domain_in.' )
76 if( domain_out%pe /= null_pe )
then
77 if( isize_out /= domain_out%x(1)%domain_data%size .OR. jsize_out /= domain_out%y(1)%domain_data%size ) &
78 call mpp_error( fatal,
'MPP_REDISTRIBUTE_INIT_COMM: field_out must be on data domain of domain_out.' )
83 list_size =
size(l_addrs_in(:))
84 if(l_addrs_out(1) > 0)
then
85 domain_id = set_domain_id(domain_out%id,ke+list_size)
87 domain_id = set_domain_id(domain_in%id,ke+list_size)
90 d_comm =>get_comm(domain_id,l_addrs_in(1),l_addrs_out(1))
92 if(d_comm%initialized)
return
94 d_comm%l_addr = l_addrs_in(1)
95 d_comm%domain_in =>domain_in
96 d_comm%Slist_size =
size(domain_out%list(:))
97 d_comm%isize_in = isize_in
98 d_comm%jsize_in = jsize_in
102 lsize = d_comm%Slist_size-1
103 allocate(d_comm%sendis(1,0:lsize), d_comm%sendie(1,0:lsize), &
104 d_comm%sendjs(1,0:lsize), d_comm%sendje(1,0:lsize), &
105 d_comm%S_msize(0:lsize),isl(0:lsize),jsl(0:lsize))
106 allocate(slist_addr(list_size,0:lsize))
107 allocate(d_comm%cto_pe(0:lsize), d_comm%S_do_buf(0:lsize))
112 d_comm%sendis=0; d_comm%sendie=0
113 d_comm%sendjs=0; d_comm%sendje=0;
115 d_comm%S_do_buf=.false.
117 ioff = domain_in%x(1)%domain_data%begin
118 joff = domain_in%y(1)%domain_data%begin
119 mytile = domain_in%tile_id(1)
121 call mpp_get_compute_domain( domain_in, isc, iec, jsc, jec )
123 m = mod( domain_out%pos+list+lsize+1, lsize+1 )
124 if( mytile .NE. domain_out%list(m)%tile_id(1) ) cycle
125 d_comm%cto_pe(list) = domain_out%list(m)%pe
126 to_pe = d_comm%cto_pe(list)
127 is = domain_out%list(m)%x(1)%compute%begin
128 ie = domain_out%list(m)%x(1)%compute%end
129 js = domain_out%list(m)%y(1)%compute%begin
130 je = domain_out%list(m)%y(1)%compute%end
131 is = max(is,isc); ie = min(ie,iec)
132 js = max(js,jsc); je = min(je,jec)
133 if( ie >= is .AND. je >= js )
then
134 d_comm%S_do_buf(list) = .true.
135 d_comm%sendis(1,list)=is; d_comm%sendie(1,list)=ie
136 d_comm%sendjs(1,list)=js; d_comm%sendje(1,list)=je
137 d_comm%S_msize(list) = (ie-is+1)*(je-js+1)*ke
138 isl(list) = is-ioff+1; jsl(list) = js-joff+1
144 d_comm%domain_out =>domain_out
145 d_comm%Rlist_size =
size(domain_in%list(:))
146 d_comm%isize_out = isize_out
147 d_comm%jsize_out = jsize_out
149 rsize = d_comm%Rlist_size-1
150 allocate(d_comm%recvis(1,0:rsize), d_comm%recvie(1,0:rsize), &
151 d_comm%recvjs(1,0:rsize), d_comm%recvje(1,0:rsize), &
152 d_comm%R_msize(0:rsize))
153 allocate(d_comm%cfrom_pe(0:rsize), d_comm%R_do_buf(0:rsize))
154 allocate(d_comm%isizeR(0:rsize), d_comm%jsizeR(0:rsize))
155 allocate(d_comm%sendisR(1,0:rsize), d_comm%sendjsR(1,0:rsize))
156 allocate(d_comm%rem_addrl(list_size,0:rsize))
157 d_comm%rem_addrl=-9999
159 d_comm%recvis=0; d_comm%recvie=0
160 d_comm%recvjs=0; d_comm%recvje=0;
162 d_comm%R_do_buf=.false.
163 d_comm%isizeR=0; d_comm%jsizeR=0
164 d_comm%sendisR=0; d_comm%sendjsR=0
166 mytile = domain_out%tile_id(1)
167 call mpp_get_compute_domain( domain_out, isc, iec, jsc, jec )
169 m = mod( domain_in%pos+rsize+1-list, rsize+1 )
170 if( mytile .NE. domain_in%list(m)%tile_id(1) ) cycle
171 d_comm%cfrom_pe(list) = domain_in%list(m)%pe
172 from_pe = d_comm%cfrom_pe(list)
173 is = domain_in%list(m)%x(1)%compute%begin
174 ie = domain_in%list(m)%x(1)%compute%end
175 js = domain_in%list(m)%y(1)%compute%begin
176 je = domain_in%list(m)%y(1)%compute%end
177 is = max(is,isc); ie = min(ie,iec)
178 js = max(js,jsc); je = min(je,jec)
179 if( ie >= is .AND. je >= js )
then
180 d_comm%R_do_buf(list) = .true.
181 d_comm%recvis(1,list)=is; d_comm%recvie(1,list)=ie
182 d_comm%recvjs(1,list)=js; d_comm%recvje(1,list)=je
183 d_comm%R_msize(list) = (ie-is+1)*(je-js+1)*ke
187 d_comm%isize_max = isize_in;
call mpp_max(d_comm%isize_max)
188 d_comm%jsize_max = jsize_in;
call mpp_max(d_comm%jsize_max)
191 msgsize = ( maxval( (/0,sum(d_comm%S_msize(:))/) ) + maxval( (/0,sum(d_comm%R_msize(:))/) ) ) * list_size
193 mpp_domains_stack_hwm = max( mpp_domains_stack_hwm, msgsize )
194 if( mpp_domains_stack_hwm.GT.mpp_domains_stack_size )
then
195 write( text,
'(i8)' )mpp_domains_stack_hwm
196 call mpp_error( fatal, &
197 &
'MPP_REDISTRIBUTE_INIT_COMM: mpp_domains_stack overflow, call mpp_domains_set_stack_size(' &
198 & //trim(text)//
') from all PEs.' )
202 DEALLOCATE(slist_addr,isl,jsl)
204 d_comm%initialized = .true.
206 end function mpp_redistribute_init_comm
210 jsize_l, ksize,l_addr2,flags, position)
RESULT(d_comm)
211 type(domaincommunicator2d),
pointer :: d_comm
212 type(domain2d),
target,
intent(in) :: domain
213 integer(i8_kind),
intent(in) :: l_addr
214 integer,
intent(in) :: isize_g
215 integer,
intent(in) :: jsize_g
216 integer,
intent(in) :: isize_l
217 integer,
intent(in) :: jsize_l
218 integer,
intent(in) :: ksize
219 integer(i8_kind),
optional,
intent(in) :: l_addr2
220 integer,
optional,
intent(in) :: flags
221 integer,
optional,
intent(in) :: position
223 integer(i8_kind) :: domain_id
224 integer :: n, lpos, rpos, list, nlist, tile_id
225 integer :: update_flags
226 logical :: xonly, yonly
227 integer :: is, ie, js, je, ioff, joff, ishift, jshift
228 integer :: lsize,msgsize,from_pe
229 integer,
allocatable,
dimension(:) :: isl, jsl
230 integer(i8_kind),
allocatable,
dimension(:,:) :: slist_addr
231 integer(i8_kind),
save ,
dimension(2) :: rem_addr
232 character(len=8) :: text
234 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_GLOBAL_FIELD: must first call mpp_domains_init.' )
235 update_flags=xupdate+yupdate; xonly = .false.; yonly = .false.
236 if(
PRESENT(flags) )
then
238 xonly = btest(flags,east)
239 yonly = btest(flags,south)
240 if( .NOT.xonly .AND. .NOT.yonly )
call mpp_error( warning, &
241 'MPP_GLOBAL_FIELD: you must have flags=XUPDATE, YUPDATE or XUPDATE+YUPDATE' )
242 if(xonly .AND. yonly)
then
243 xonly = .false.; yonly = .false.
249 if( isize_g /= (domain%x(1)%global%size+ishift) .OR. jsize_g /= (domain%y(1)%global%size+jshift) ) &
250 call mpp_error( fatal,
'MPP_GLOBAL_FIELD_INIT_COMM: incoming arrays do not match domain.' )
252 if( isize_l == (domain%x(1)%compute%size+ishift) .AND. jsize_l == (domain%y(1)%compute%size+jshift) )
then
254 ioff = -domain%x(1)%compute%begin + 1
255 joff = -domain%y(1)%compute%begin + 1
256 elseif( isize_l == (domain%x(1)%memory%size+ishift) .AND. jsize_l == (domain%y(1)%memory%size+jshift) )
then
258 ioff = -domain%x(1)%domain_data%begin + 1
259 joff = -domain%y(1)%domain_data%begin + 1
261 call mpp_error(fatal, &
262 &
'MPP_GLOBAL_FIELD_INIT_COMM: incoming field array must match either compute domain or data domain.')
266 domain_id=set_domain_id(domain%id,ksize,update_flags, position=position)
267 d_comm =>get_comm(domain_id,l_addr,l_addr2)
269 if(d_comm%initialized)
return
270 d_comm%domain => domain
271 d_comm%isize_in = isize_l; d_comm%isize_out = isize_g
272 d_comm%jsize_in = jsize_l; d_comm%jsize_out = jsize_g
274 d_comm%gf_ioff=ioff; d_comm%gf_joff=joff
278 lsize =
size(domain%x(1)%list(:))
280 allocate(d_comm%cto_pe(0:lsize-1))
283 lpos = mod(domain%x(1)%pos+lsize-list,lsize)
284 d_comm%cto_pe(list) = domain%x(1)%list(lpos)%pe
287 allocate(d_comm%cfrom_pe(0:lsize-1))
288 allocate(d_comm%recvis(1,0:lsize-1), d_comm%recvie(1,0:lsize-1), &
289 d_comm%recvjs(1,0:lsize-1), d_comm%recvje(1,0:lsize-1), &
290 d_comm%R_msize(0:lsize-1))
292 d_comm%recvis=0; d_comm%recvie=0
293 d_comm%recvjs=0; d_comm%recvje=0;
296 rpos = mod(domain%x(1)%pos+list,lsize)
297 from_pe = domain%x(1)%list(rpos)%pe
298 d_comm%cfrom_pe(list) = from_pe
299 is = domain%list(from_pe)%x(1)%compute%begin; ie = domain%list(from_pe)%x(1)%compute%end+ishift
300 js = domain%y(1)%compute%begin; je = domain%y(1)%compute%end+jshift
301 d_comm%recvis(1,list)=is; d_comm%recvie(1,list)=ie
302 d_comm%recvjs(1,list)=js; d_comm%recvje(1,list)=je
303 d_comm%R_msize(list) = (ie-is+1) * (je-js+1) * ksize
307 lsize =
size(domain%y(1)%list(:))
309 allocate(d_comm%cto_pe(0:lsize-1))
312 lpos = mod(domain%y(1)%pos+lsize-list,lsize)
313 d_comm%cto_pe(list) = domain%y(1)%list(lpos)%pe
316 allocate(d_comm%cfrom_pe(0:lsize-1))
317 allocate(d_comm%recvis(1,0:lsize-1), d_comm%recvie(1,0:lsize-1), &
318 d_comm%recvjs(1,0:lsize-1), d_comm%recvje(1,0:lsize-1), &
319 d_comm%R_msize(0:lsize-1))
321 d_comm%recvis=0; d_comm%recvie=0
322 d_comm%recvjs=0; d_comm%recvje=0;
325 rpos = mod(domain%y(1)%pos+list,lsize)
326 from_pe = domain%y(1)%list(rpos)%pe
327 d_comm%cfrom_pe(list) = from_pe
328 is = domain%x(1)%compute%begin; ie = domain%x(1)%compute%end+ishift
329 js = domain%list(from_pe)%y(1)%compute%begin; je = domain%list(from_pe)%y(1)%compute%end+jshift
330 d_comm%recvis(1,list)=is; d_comm%recvie(1,list)=ie
331 d_comm%recvjs(1,list)=js; d_comm%recvje(1,list)=je
332 d_comm%R_msize(list) = (ie-is+1) * (je-js+1) * ksize
336 nlist =
size(domain%list(:))
337 tile_id = domain%tile_id(1)
341 if( domain%list(list)%tile_id(1) .NE. tile_id ) cycle
346 allocate(d_comm%cto_pe(0:lsize-1))
350 lpos = mod(domain%pos+nlist-list,nlist)
351 if( domain%list(lpos)%tile_id(1) .NE. tile_id ) cycle
352 d_comm%cto_pe(n) = domain%list(lpos)%pe
356 allocate(d_comm%cfrom_pe(0:lsize-1))
357 allocate(d_comm%recvis(1,0:lsize-1), d_comm%recvie(1,0:lsize-1), &
358 d_comm%recvjs(1,0:lsize-1), d_comm%recvje(1,0:lsize-1), &
359 d_comm%R_msize(0:lsize-1))
361 d_comm%recvis=0; d_comm%recvie=0
362 d_comm%recvjs=0; d_comm%recvje=0;
366 rpos = mod(domain%pos+list,nlist)
367 if( domain%list(rpos)%tile_id(1) .NE. tile_id ) cycle
368 d_comm%cfrom_pe(n) = domain%list(rpos)%pe
369 is = domain%list(rpos)%x(1)%compute%begin; ie = domain%list(rpos)%x(1)%compute%end+ishift
370 js = domain%list(rpos)%y(1)%compute%begin; je = domain%list(rpos)%y(1)%compute%end+jshift
371 d_comm%recvis(1,n)=is; d_comm%recvie(1,n)=ie
372 d_comm%recvjs(1,n)=js; d_comm%recvje(1,n)=je
373 d_comm%R_msize(n) = (je-js+1) * (ie-is+1) * ksize
379 d_comm%Slist_size = lsize
380 d_comm%Rlist_size = lsize
383 allocate(d_comm%sendis(1,0:lsize-1), d_comm%sendie(1,0:lsize-1), &
384 d_comm%sendjs(1,0:lsize-1), d_comm%sendje(1,0:lsize-1), &
385 d_comm%S_msize(0:lsize-1),isl(0:lsize-1),jsl(0:lsize-1))
386 allocate(slist_addr(2,0:lsize-1))
389 d_comm%sendis=0; d_comm%sendie=0
390 d_comm%sendjs=0; d_comm%sendje=0;
393 is=domain%x(1)%compute%begin; ie=domain%x(1)%compute%end+ishift
394 js=domain%y(1)%compute%begin; je=domain%y(1)%compute%end+jshift
395 d_comm%sendis(1,list)=is; d_comm%sendie(1,list)=ie
396 d_comm%sendjs(1,list)=js; d_comm%sendje(1,list)=je
397 d_comm%S_msize(list) = (je-js+1) * (ie-is+1) * ksize
398 isl(list) = ioff+domain%x(1)%compute%begin; jsl(list) = joff+domain%y(1)%compute%begin
402 allocate(d_comm%isizeR(0:lsize-1), d_comm%jsizeR(0:lsize-1))
403 allocate(d_comm%sendisR(1,0:lsize-1), d_comm%sendjsR(1,0:lsize-1))
404 if(.not.
PRESENT(l_addr2))
then
405 allocate(d_comm%rem_addr(0:lsize-1))
406 d_comm%rem_addr=-9999
408 allocate(d_comm%rem_addrx(0:lsize-1),d_comm%rem_addry(0:lsize-1))
409 d_comm%rem_addrx=-9999; d_comm%rem_addry=-9999
411 d_comm%isizeR=0; d_comm%jsizeR=0
412 d_comm%sendisR=0; d_comm%sendjsR=0
416 msgsize = maxval( (/0,sum(d_comm%S_msize(:))/) ) + maxval( (/0,sum(d_comm%R_msize(:))/) )
418 mpp_domains_stack_hwm = max( mpp_domains_stack_hwm, msgsize )
419 if( mpp_domains_stack_hwm.GT.mpp_domains_stack_size )
then
420 write( text,
'(i8)' )mpp_domains_stack_hwm
421 call mpp_error( fatal, &
422 &
'MPP_GLOBAL_FIELD_INIT_COMM: mpp_domains_stack overflow, call mpp_domains_set_stack_size(' &
423 & //trim(text)//
') from all PEs.' )
427 DEALLOCATE(slist_addr,isl,jsl)
429 d_comm%initialized = .true.
434 subroutine mpp_redistribute_free_comm(domain_in,l_addr,domain_out,l_addr2,ksize,lsize)
437 type(domain2d),
intent(in) :: domain_in
438 integer(i8_kind),
intent(in) :: l_addr
439 type(domain2d),
intent(in) :: domain_out
440 integer(i8_kind),
intent(in) :: l_addr2
441 integer,
intent(in) :: ksize,lsize
443 integer(i8_kind) :: domain_id
446 domain_id = set_domain_id(domain_out%id,ksize+lsize)
448 domain_id = set_domain_id(domain_in%id,ksize+lsize)
450 call free_comm(domain_id,l_addr,l_addr2)
451 end subroutine mpp_redistribute_free_comm
454 subroutine mpp_global_field_free_comm(domain,l_addr,ksize,l_addr2,flags)
457 type(domain2d),
intent(in) :: domain
458 integer(i8_kind),
intent(in) :: l_addr
459 integer,
intent(in) :: ksize
460 integer(i8_kind),
optional,
intent(in) :: l_addr2
461 integer,
optional,
intent(in) :: flags
463 integer :: update_flags
464 integer(i8_kind) :: domain_id
466 update_flags=0;
if(
PRESENT(flags))update_flags=flags
467 domain_id=set_domain_id(domain%id,ksize,update_flags)
468 call free_comm(domain_id,l_addr,l_addr2)
469 end subroutine mpp_global_field_free_comm
472 subroutine free_comm(domain_id,l_addr,l_addr2)
475 integer(i8_kind),
intent(in) :: domain_id
476 integer(i8_kind),
intent(in) :: l_addr
477 integer(i8_kind),
optional,
intent(in) :: l_addr2
479 integer(i8_kind) :: dc_key,a_key
480 integer :: dc_idx,a_idx,i_idx,insert,insert_a,insert_i
481 integer :: a2_idx,insert_a2
484 i_idx = find_key(domain_id,ids_sorted(1:n_ids),insert_i)
485 a_idx = find_key(l_addr,addrs_sorted(1:a_sort_len),insert_a)
486 a_key = int(addrs_idx(a_idx),kind(i8_kind))
487 if(
PRESENT(l_addr2))
then
488 a2_idx = find_key(l_addr2,addrs2_sorted(1:a2_sort_len),insert_a2)
489 a_key = a_key + addr2_base*int(addrs2_idx(a2_idx),kind(i8_kind))
491 dc_key = domain_id_base*int(ids_idx(i_idx),kind(i8_kind)) + a_key
492 dc_idx = find_key(dc_key,dckey_sorted(1:dc_sort_len),insert)
495 call mpp_error(fatal,
'FREE_COMM: attempt to remove nonexistent domains communicator key')
497 call deallocate_comm(d_comm(dc_idx))
498 call pop_key(dckey_sorted,d_comm_idx,dc_sort_len,dc_idx)
499 call pop_key(addrs_sorted,addrs_idx,a_sort_len,a_idx)
500 if(
PRESENT(l_addr2))
call pop_key(addrs2_sorted,addrs2_idx,a2_sort_len,a2_idx)
501 end subroutine free_comm
504 function get_comm(domain_id,l_addr,l_addr2)
505 integer(i8_kind),
intent(in) :: domain_id
506 integer(i8_kind),
intent(in) :: l_addr
507 integer(i8_kind),
intent(in),
optional :: l_addr2
508 type(domaincommunicator2d),
pointer :: get_comm
510 integer(i8_kind) :: dc_key,a_key
511 integer :: i,dc_idx,a_idx,i_idx,insert,insert_a,insert_i
512 integer :: a2_idx,insert_a2
514 if(.not.
ALLOCATED(d_comm))
ALLOCATE(d_comm(max_fields))
515 i_idx = find_key(domain_id,ids_sorted(1:n_ids),insert_i)
516 a_idx = find_key(l_addr,addrs_sorted(1:a_sort_len),insert_a)
517 a_key = int(addrs_idx(a_idx),kind(i8_kind))
518 if(
PRESENT(l_addr2))
then
519 a2_idx = find_key(l_addr2,addrs2_sorted(1:a2_sort_len),insert_a2)
520 a_key = a_key + addr2_base*int(addrs2_idx(a2_idx),kind(i8_kind))
522 dc_key = domain_id_base*int(ids_idx(i_idx),kind(i8_kind)) + a_key
523 dc_idx = find_key(dc_key,dckey_sorted(1:dc_sort_len),insert)
525 get_comm =>d_comm(d_comm_idx(dc_idx))
528 if(n_ids == max_dom_ids)
then
529 call mpp_error(fatal,
'GET_COMM: Maximum number of domains exceeded')
532 i_idx = push_key(ids_sorted,ids_idx,i_sort_len,insert_i,domain_id,n_ids)
535 if(n_addrs == max_addrs)
then
536 call mpp_error(fatal,
'GET_COMM: Maximum number of memory addresses exceeded')
538 n_addrs = n_addrs + 1
539 a_idx = push_key(addrs_sorted,addrs_idx,a_sort_len,insert_a,l_addr,n_addrs)
541 if(
PRESENT(l_addr2))
then
543 if(n_addrs2 == max_addrs2)
then
544 call mpp_error(fatal,
'GET_COMM: Maximum number of 2nd memory addresses exceeded')
546 n_addrs2 = n_addrs2 + 1
547 a2_idx = push_key(addrs2_sorted,addrs2_idx,a2_sort_len,insert_a2,l_addr2,n_addrs2)
550 if(n_comm == max_fields)
then
551 call mpp_error(fatal,
'GET_COMM: Maximum number of fields exceeded')
553 a_key = int(addrs_idx(a_idx),kind(8))
554 if(
PRESENT(l_addr2))a_key = a_key + addr2_base*int(addrs2_idx(a2_idx),kind(8))
555 dc_key = domain_id_base*int(ids_idx(i_idx),kind(i8_kind)) + a_key
556 dc_idx = find_key(dc_key,dckey_sorted(1:dc_sort_len),insert)
557 if(dc_idx /= -1)
call mpp_error(fatal,
'GET_COMM: attempt to insert existing key')
559 i = push_key(dckey_sorted,d_comm_idx,dc_sort_len,insert,dc_key,n_comm)
560 d_comm_idx(insert) = n_comm
561 if(
PRESENT(l_addr2))
then
562 d_comm(n_comm)%l_addrx = l_addr
563 d_comm(n_comm)%l_addry = l_addr2
565 d_comm(n_comm)%l_addr = l_addr
567 get_comm =>d_comm(n_comm)
569 end function get_comm
572 function push_key(sorted,idx,n_idx,insert,key,ival)
573 integer(i8_kind),
intent(inout),
dimension(:) :: sorted
574 integer,
intent(inout),
dimension(-1:) :: idx
575 integer,
intent(inout) :: n_idx
576 integer,
intent(in) :: insert
577 integer(i8_kind),
intent(in) :: key
578 integer,
intent(in) :: ival
580 integer :: push_key,i
583 sorted(i+1) = sorted(i)
590 end function push_key
593 subroutine pop_key(sorted,idx,n_idx,key_idx)
594 integer(i8_kind),
intent(inout),
dimension(:) :: sorted
595 integer,
intent(inout),
dimension(-1:) :: idx
596 integer,
intent(inout) :: n_idx
597 integer,
intent(in) :: key_idx
602 sorted(i) = sorted(i+1)
605 sorted(n_idx) = -9999
608 end subroutine pop_key
611 function find_key(key,sorted,insert)
RESULT(n)
613 integer(i8_kind),
intent(in) :: key
614 integer(i8_kind),
dimension(:),
intent(in) :: sorted
615 integer,
intent(out) :: insert
616 integer :: n, n_max, n_min, n_key
619 n_key =
size(sorted(:))
624 if(key < sorted(1))
then
626 elseif(key > sorted(n_key))
then
627 insert = n_key+1;
return
630 if(key == sorted(1))
then
632 elseif(key == sorted(n_key))
then
640 if(key == sorted(n))
then
642 elseif(key > sorted(n))
then
643 if(key < sorted(n+1))
then
649 if(key > sorted(n-1))
then
655 if(n==1 .or. n==n_key)
exit
658 end function find_key
661 subroutine deallocate_comm(d_comm)
662 type(domaincommunicator2d),
intent(inout) :: d_comm
664 d_comm%domain =>null()
665 d_comm%domain_in =>null()
666 d_comm%domain_out =>null()
668 d_comm%initialized=.false.
671 d_comm%l_addrx =-9999
672 d_comm%l_addry =-9999
674 if(
allocated(d_comm%sendis) )
DEALLOCATE(d_comm%sendis);
675 if(
allocated(d_comm%sendie) )
DEALLOCATE(d_comm%sendie);
676 if(
allocated(d_comm%sendjs) )
DEALLOCATE(d_comm%sendjs);
677 if(
allocated(d_comm%sendje) )
DEALLOCATE(d_comm%sendje);
678 if(
allocated(d_comm%S_msize) )
DEALLOCATE(d_comm%S_msize);
679 if(
allocated(d_comm%S_do_buf) )
DEALLOCATE(d_comm%S_do_buf);
680 if(
allocated(d_comm%cto_pe) )
DEALLOCATE(d_comm%cto_pe);
681 if(
allocated(d_comm%recvis) )
DEALLOCATE(d_comm%recvis);
682 if(
allocated(d_comm%recvie) )
DEALLOCATE(d_comm%recvie);
683 if(
allocated(d_comm%recvjs) )
DEALLOCATE(d_comm%recvjs);
684 if(
allocated(d_comm%recvje) )
DEALLOCATE(d_comm%recvje);
685 if(
allocated(d_comm%R_msize) )
DEALLOCATE(d_comm%R_msize);
686 if(
allocated(d_comm%R_do_buf) )
DEALLOCATE(d_comm%R_do_buf);
687 if(
allocated(d_comm%cfrom_pe) )
DEALLOCATE(d_comm%cfrom_pe);
688 d_comm%Slist_size=0; d_comm%Rlist_size=0
689 d_comm%isize=0; d_comm%jsize=0; d_comm%ke=0
690 d_comm%isize_in=0; d_comm%jsize_in=0
691 d_comm%isize_out=0; d_comm%jsize_out=0
692 d_comm%isize_max=0; d_comm%jsize_max=0
693 d_comm%gf_ioff=0; d_comm%gf_joff=0
695 if(
allocated(d_comm%isizeR) )
DEALLOCATE(d_comm%isizeR);
696 if(
allocated(d_comm%jsizeR) )
DEALLOCATE(d_comm%jsizeR);
697 if(
allocated(d_comm%sendisR) )
DEALLOCATE(d_comm%sendisR);
698 if(
allocated(d_comm%sendjsR) )
DEALLOCATE(d_comm%sendjsR);
699 if(
allocated(d_comm%rem_addr) )
DEALLOCATE(d_comm%rem_addr);
700 if(
allocated(d_comm%rem_addrx) )
DEALLOCATE(d_comm%rem_addrx);
701 if(
allocated(d_comm%rem_addry) )
DEALLOCATE(d_comm%rem_addry);
702 if(
allocated(d_comm%rem_addrl) )
DEALLOCATE(d_comm%rem_addrl);
703 end subroutine deallocate_comm
706 function set_domain_id(d_id,ksize,flags,gtype, position, whalo, ehalo, shalo, nhalo)
707 integer(i8_kind),
intent(in) :: d_id
708 integer ,
intent(in) :: ksize
709 integer ,
optional,
intent(in) :: flags
710 integer ,
optional,
intent(in) :: gtype
711 integer ,
optional,
intent(in) :: position
712 integer ,
optional,
intent(in) :: whalo, ehalo, shalo, nhalo
714 integer(i8_kind) :: set_domain_id
716 set_domain_id=d_id + ke_base*int(ksize,kind(d_id))
717 if(
PRESENT(flags))set_domain_id=set_domain_id+int(flags,kind(d_id))
718 if(
PRESENT(gtype))set_domain_id=set_domain_id+gt_base*int(gtype,kind(d_id))
721 if(
present(position)) set_domain_id=set_domain_id+gt_base*int(2**position, kind(d_id))
723 if(
present(whalo))
then
725 set_domain_id=set_domain_id+gt_base*int(2**4*2**whalo, kind(d_id))
727 set_domain_id=set_domain_id-gt_base*int(2**4*2**(-whalo), kind(d_id))
730 if(
present(ehalo))
then
732 set_domain_id=set_domain_id+gt_base*int(2**4*2**ehalo, kind(d_id))
734 set_domain_id=set_domain_id-gt_base*int(2**4*2**(-ehalo), kind(d_id))
737 if(
present(shalo))
then
739 set_domain_id=set_domain_id+gt_base*int(2**4*2**shalo, kind(d_id))
741 set_domain_id=set_domain_id-gt_base*int(2**4*2**(-shalo), kind(d_id))
744 if(
present(nhalo))
then
746 set_domain_id=set_domain_id+gt_base*int(2**4*2**nhalo, kind(d_id))
748 set_domain_id=set_domain_id-gt_base*int(2**4*2**(-nhalo), kind(d_id))
751 end function set_domain_id
type(domaincommunicator2d) function, pointer mpp_global_field_init_comm(domain, l_addr, isize_g, jsize_g, isize_l, jsize_l, ksize, l_addr2, flags, position)
initializes a DomainCommunicator2D type for use in mpp_global_field
subroutine mpp_get_domain_shift(domain, ishift, jshift, position)
Returns the shift value in x and y-direction according to domain position..
subroutine mpp_sync_self(pelist, check, request, msg_size, msg_type)
This is to check if current PE's outstanding puts are complete but we can't use shmem_fence because w...