00001 subroutine MPP_UPDATE_DOMAINS_2D_( field, domain, flags )
00002 !updates data domain of 2D field whose computational domains have been computed
00003 MPP_TYPE_, intent(inout) :: field(:,:)
00004 type(domain2D), intent(in) :: domain
00005 integer, intent(in), optional :: flags
00006 MPP_TYPE_ :: field3D(size(field,1),size(field,2),1)
00007 #ifdef use_CRI_pointers
00008 pointer( ptr, field3D )
00009 ptr = LOC(field)
00010 call mpp_update_domains( field3D, domain, flags )
00011 #else
00012 field3D = RESHAPE( field, SHAPE(field3D) )
00013 call mpp_update_domains( field3D, domain, flags )
00014 field = RESHAPE( field3D, SHAPE(field) )
00015 #endif
00016 return
00017 end subroutine MPP_UPDATE_DOMAINS_2D_
00018
00019 subroutine MPP_UPDATE_DOMAINS_4D_( field, domain, flags )
00020 !updates data domain of 4D field whose computational domains have been computed
00021 MPP_TYPE_, intent(inout) :: field(:,:,:,:)
00022 type(domain2D), intent(in) :: domain
00023 integer, intent(in), optional :: flags
00024 MPP_TYPE_ :: field3D(size(field,1),size(field,2),size(field,3)*size(field,4))
00025 #ifdef use_CRI_pointers
00026 pointer( ptr, field3D )
00027 ptr = LOC(field)
00028 call mpp_update_domains( field3D, domain, flags )
00029 #else
00030 field3D = RESHAPE( field, SHAPE(field3D) )
00031 call mpp_update_domains( field3D, domain, flags )
00032 field = RESHAPE( field3D, SHAPE(field) )
00033 #endif
00034 return
00035 end subroutine MPP_UPDATE_DOMAINS_4D_
00036
00037 subroutine MPP_UPDATE_DOMAINS_5D_( field, domain, flags )
00038 !updates data domain of 5D field whose computational domains have been computed
00039 MPP_TYPE_, intent(inout) :: field(:,:,:,:,:)
00040 type(domain2D), intent(in) :: domain
00041 integer, intent(in), optional :: flags
00042 MPP_TYPE_ :: field3D(size(field,1),size(field,2),size(field,3)*size(field,4)*size(field,5))
00043 #ifdef use_CRI_pointers
00044 pointer( ptr, field3D )
00045 ptr = LOC(field)
00046 call mpp_update_domains( field3D, domain, flags )
00047 #else
00048 field3D = RESHAPE( field, SHAPE(field3D) )
00049 call mpp_update_domains( field3D, domain, flags )
00050 field = RESHAPE( field3D, SHAPE(field) )
00051 #endif
00052 return
00053 end subroutine MPP_UPDATE_DOMAINS_5D_
00054
00055 subroutine MPP_UPDATE_DOMAINS_3D_( field, domain, flags )
00056 !updates data domain of 3D field whose computational domains have been computed
00057 type(domain2D), intent(in) :: domain
00058 MPP_TYPE_, intent(inout) :: field(domain%x%data%begin:,domain%y%data%begin:,:)
00059 integer, intent(in), optional :: flags
00060 integer :: update_flags
00061 !equate to mpp_domains_stack
00062 integer :: wordlen !#words of MPP_TYPE_ fit in 1 word of mpp_domains_stack
00063 MPP_TYPE_ :: buffer(size(mpp_domains_stack))
00064 #ifdef use_CRI_pointers
00065 pointer( ptr, buffer )
00066 #endif
00067 integer :: buffer_pos
00068 integer :: i, j, k, m, n
00069 integer :: is, ie, js, je, ke
00070 !receive domains saved here for unpacking
00071 !for non-blocking version, could be recomputed
00072 integer, dimension(8) :: isr, ier, jsr, jer
00073 integer :: to_pe, from_pe, list, pos, msgsize
00074 logical :: recv_e, recv_se, recv_s, recv_sw, recv_w, recv_nw, recv_n, recv_ne
00075 logical :: send_e, send_se, send_s, send_sw, send_w, send_nw, send_n, send_ne
00076 logical :: folded
00077 character(len=8) :: text
00078
00079 update_flags = XUPDATE+YUPDATE !default
00080 if( PRESENT(flags) )update_flags = flags
00081 recv_w = BTEST(update_flags,WEST)
00082 recv_e = BTEST(update_flags,EAST)
00083 recv_s = BTEST(update_flags,SOUTH)
00084 recv_n = BTEST(update_flags,NORTH)
00085 recv_ne = recv_e .AND. recv_n
00086 recv_se = recv_e .AND. recv_s
00087 recv_sw = recv_w .AND. recv_s
00088 recv_nw = recv_w .AND. recv_n
00089 send_w = recv_e
00090 send_e = recv_w
00091 send_s = recv_n
00092 send_n = recv_s
00093 send_ne = send_e .AND. send_n
00094 send_se = send_e .AND. send_s
00095 send_sw = send_w .AND. send_s
00096 send_nw = send_w .AND. send_n
00097 if( recv_w .AND. BTEST(domain%fold,WEST) .AND. BTEST(grid_offset_type,EAST) ) &
00098 call mpp_error( FATAL, 'Incompatible grid offset and fold.' )
00099 if( recv_s .AND. BTEST(domain%fold,SOUTH) .AND. BTEST(grid_offset_type,NORTH) ) &
00100 call mpp_error( FATAL, 'Incompatible grid offset and fold.' )
00101 if( recv_e .AND. BTEST(domain%fold,EAST) .AND. BTEST(grid_offset_type,WEST) ) &
00102 call mpp_error( FATAL, 'Incompatible grid offset and fold.' )
00103 if( recv_n .AND. BTEST(domain%fold,NORTH) .AND. BTEST(grid_offset_type,SOUTH) ) &
00104 call mpp_error( FATAL, 'Incompatible grid offset and fold.' )
00105
00106
00107 n = size(domain%list)
00108 ke = size(field,3)
00109 buffer_pos = 0 !this initialization goes away if update_domains becomes non-blocking
00110 #ifdef use_CRI_pointers
00111 ptr = LOC(mpp_domains_stack)
00112 wordlen = size(transfer(buffer(1),mpp_domains_stack))
00113 #endif
00114 !send
00115 do list = 0,n-1
00116 m = mod( domain%pos+list, n )
00117 if( .NOT.domain%list(m)%overlap )cycle
00118 call mpp_clock_begin(pack_clock)
00119 to_pe = domain%list(m)%pe
00120 pos = buffer_pos
00121 if( send_w .AND. domain%list(m)%send_w%overlap )then
00122 is = domain%list(m)%send_w%is; ie = domain%list(m)%send_w%ie
00123 js = domain%list(m)%send_w%js; je = domain%list(m)%send_w%je
00124 if( grid_offset_type.NE.AGRID )then
00125 is = domain%list(m)%send_w_off%is; ie = domain%list(m)%send_w_off%ie
00126 js = domain%list(m)%send_w_off%js; je = domain%list(m)%send_w_off%je
00127 end if
00128 call mpp_clock_begin(pack_loop_clock)
00129 do k = 1,ke
00130 do j = js,je
00131 do i = is,ie
00132 pos = pos + 1
00133 buffer(pos) = field(i,j,k)
00134 end do
00135 end do
00136 end do
00137 call mpp_clock_end(pack_loop_clock)
00138 end if
00139 if( send_nw .AND. domain%list(m)%send_nw%overlap )then
00140 is = domain%list(m)%send_nw%is; ie = domain%list(m)%send_nw%ie
00141 js = domain%list(m)%send_nw%js; je = domain%list(m)%send_nw%je
00142 if( grid_offset_type.NE.AGRID )then
00143 is = domain%list(m)%send_nw_off%is; ie = domain%list(m)%send_nw_off%ie
00144 js = domain%list(m)%send_nw_off%js; je = domain%list(m)%send_nw_off%je
00145 end if
00146 call mpp_clock_begin(pack_loop_clock)
00147 do k = 1,ke
00148 do j = js,je
00149 do i = is,ie
00150 pos = pos + 1
00151 buffer(pos) = field(i,j,k)
00152 end do
00153 end do
00154 end do
00155 call mpp_clock_end(pack_loop_clock)
00156 end if
00157 if( send_n .AND. domain%list(m)%send_n%overlap )then
00158 is = domain%list(m)%send_n%is; ie = domain%list(m)%send_n%ie
00159 js = domain%list(m)%send_n%js; je = domain%list(m)%send_n%je
00160 if( grid_offset_type.NE.AGRID )then
00161 is = domain%list(m)%send_n_off%is; ie = domain%list(m)%send_n_off%ie
00162 js = domain%list(m)%send_n_off%js; je = domain%list(m)%send_n_off%je
00163 end if
00164 call mpp_clock_begin(pack_loop_clock)
00165 do k = 1,ke
00166 do j = js,je
00167 do i = is,ie
00168 pos = pos + 1
00169 buffer(pos) = field(i,j,k)
00170 end do
00171 end do
00172 end do
00173 call mpp_clock_end(pack_loop_clock)
00174 end if
00175 if( send_ne .AND. domain%list(m)%send_ne%overlap )then
00176 is = domain%list(m)%send_ne%is; ie = domain%list(m)%send_ne%ie
00177 js = domain%list(m)%send_ne%js; je = domain%list(m)%send_ne%je
00178 if( grid_offset_type.NE.AGRID )then
00179 is = domain%list(m)%send_ne_off%is; ie = domain%list(m)%send_ne_off%ie
00180 js = domain%list(m)%send_ne_off%js; je = domain%list(m)%send_ne_off%je
00181 end if
00182 call mpp_clock_begin(pack_loop_clock)
00183 do k = 1,ke
00184 do j = js,je
00185 do i = is,ie
00186 pos = pos + 1
00187 buffer(pos) = field(i,j,k)
00188 end do
00189 end do
00190 end do
00191 call mpp_clock_end(pack_loop_clock)
00192 end if
00193 if( send_e .AND. domain%list(m)%send_e%overlap )then
00194 is = domain%list(m)%send_e%is; ie = domain%list(m)%send_e%ie
00195 js = domain%list(m)%send_e%js; je = domain%list(m)%send_e%je
00196 if( grid_offset_type.NE.AGRID )then
00197 is = domain%list(m)%send_e_off%is; ie = domain%list(m)%send_e_off%ie
00198 js = domain%list(m)%send_e_off%js; je = domain%list(m)%send_e_off%je
00199 end if
00200 call mpp_clock_begin(pack_loop_clock)
00201 do k = 1,ke
00202 do j = js,je
00203 do i = is,ie
00204 pos = pos + 1
00205 buffer(pos) = field(i,j,k)
00206 end do
00207 end do
00208 end do
00209 call mpp_clock_end(pack_loop_clock)
00210 end if
00211 if( send_se .AND. domain%list(m)%send_se%overlap )then
00212 is = domain%list(m)%send_se%is; ie = domain%list(m)%send_se%ie
00213 js = domain%list(m)%send_se%js; je = domain%list(m)%send_se%je
00214 if( grid_offset_type.NE.AGRID )then
00215 is = domain%list(m)%send_se_off%is; ie = domain%list(m)%send_se_off%ie
00216 js = domain%list(m)%send_se_off%js; je = domain%list(m)%send_se_off%je
00217 end if
00218 call mpp_clock_begin(pack_loop_clock)
00219 do k = 1,ke
00220 do j = js,je
00221 do i = is,ie
00222 pos = pos + 1
00223 buffer(pos) = field(i,j,k)
00224 end do
00225 end do
00226 end do
00227 call mpp_clock_end(pack_loop_clock)
00228 end if
00229 if( send_s .AND. domain%list(m)%send_s%overlap )then
00230 is = domain%list(m)%send_s%is; ie = domain%list(m)%send_s%ie
00231 js = domain%list(m)%send_s%js; je = domain%list(m)%send_s%je
00232 if( grid_offset_type.NE.AGRID )then
00233 is = domain%list(m)%send_s_off%is; ie = domain%list(m)%send_s_off%ie
00234 js = domain%list(m)%send_s_off%js; je = domain%list(m)%send_s_off%je
00235 end if
00236 call mpp_clock_begin(pack_loop_clock)
00237 do k = 1,ke
00238 do j = js,je
00239 do i = is,ie
00240 pos = pos + 1
00241 buffer(pos) = field(i,j,k)
00242 end do
00243 end do
00244 end do
00245 call mpp_clock_end(pack_loop_clock)
00246 end if
00247 if( send_sw .AND. domain%list(m)%send_sw%overlap )then
00248 is = domain%list(m)%send_sw%is; ie = domain%list(m)%send_sw%ie
00249 js = domain%list(m)%send_sw%js; je = domain%list(m)%send_sw%je
00250 if( grid_offset_type.NE.AGRID )then
00251 is = domain%list(m)%send_sw_off%is; ie = domain%list(m)%send_sw_off%ie
00252 js = domain%list(m)%send_sw_off%js; je = domain%list(m)%send_sw_off%je
00253 end if
00254 call mpp_clock_begin(pack_loop_clock)
00255 do k = 1,ke
00256 do j = js,je
00257 do i = is,ie
00258 pos = pos + 1
00259 buffer(pos) = field(i,j,k)
00260 end do
00261 end do
00262 end do
00263 call mpp_clock_end(pack_loop_clock)
00264 end if
00265 call mpp_clock_end(pack_clock)
00266 call mpp_clock_begin(send_clock)
00267 msgsize = pos - buffer_pos
00268 print *,'msgsize ',msgsize
00269 if( msgsize.GT.0 )then
00270 print *,'mpp_domains_stack_hwm ',mpp_domains_stack_hwm
00271 print *,'pos*wordlen ',pos*wordlen
00272 print *,'max ',max( mpp_domains_stack_hwm, pos*wordlen )
00273 print *,'mpp_domains_stack_size ',mpp_domains_stack_size
00274 mpp_domains_stack_hwm = max( mpp_domains_stack_hwm, pos*wordlen )
00275 if( mpp_domains_stack_hwm.GT.mpp_domains_stack_size )then
00276 write( text,'(i8)' )mpp_domains_stack_hwm
00277 call mpp_error( FATAL, 'MPP_UPDATE_DOMAINS: mpp_domains1_stack overflow, call mpp_domains_set_stack_size(' &
00278
00279 end if
00280 call mpp_send( buffer(buffer_pos+1:buffer_pos+msgsize), msgsize, to_pe )
00281 buffer_pos = pos
00282 end if
00283 call mpp_clock_end(send_clock)
00284 end do
00285
00286 !recv
00287 do list = 0,n-1
00288 m = mod( domain%pos+n-list, n )
00289 if( .NOT.domain%list(m)%overlap )cycle
00290 call mpp_clock_begin(recv_clock)
00291 from_pe = domain%list(m)%pe
00292 msgsize = 0
00293 if( recv_e .AND. domain%list(m)%recv_e%overlap )then
00294 is = domain%list(m)%recv_e%is; ie = domain%list(m)%recv_e%ie
00295 js = domain%list(m)%recv_e%js; je = domain%list(m)%recv_e%je
00296 if( grid_offset_type.NE.AGRID )then
00297 is = domain%list(m)%recv_e_off%is; ie = domain%list(m)%recv_e_off%ie
00298 js = domain%list(m)%recv_e_off%js; je = domain%list(m)%recv_e_off%je
00299 end if
00300 msgsize = msgsize + (ie-is+1)*(je-js+1)*ke
00301 end if
00302 if( recv_se .AND. domain%list(m)%recv_se%overlap )then
00303 is = domain%list(m)%recv_se%is; ie = domain%list(m)%recv_se%ie
00304 js = domain%list(m)%recv_se%js; je = domain%list(m)%recv_se%je
00305 if( grid_offset_type.NE.AGRID )then
00306 is = domain%list(m)%recv_se_off%is; ie = domain%list(m)%recv_se_off%ie
00307 js = domain%list(m)%recv_se_off%js; je = domain%list(m)%recv_se_off%je
00308 end if
00309 msgsize = msgsize + (ie-is+1)*(je-js+1)*ke
00310 end if
00311 if( recv_s .AND. domain%list(m)%recv_s%overlap )then
00312 is = domain%list(m)%recv_s%is; ie = domain%list(m)%recv_s%ie
00313 js = domain%list(m)%recv_s%js; je = domain%list(m)%recv_s%je
00314 if( grid_offset_type.NE.AGRID )then
00315 is = domain%list(m)%recv_s_off%is; ie = domain%list(m)%recv_s_off%ie
00316 js = domain%list(m)%recv_s_off%js; je = domain%list(m)%recv_s_off%je
00317 end if
00318 msgsize = msgsize + (ie-is+1)*(je-js+1)*ke
00319 end if
00320 if( recv_sw .AND. domain%list(m)%recv_sw%overlap )then
00321 is = domain%list(m)%recv_sw%is; ie = domain%list(m)%recv_sw%ie
00322 js = domain%list(m)%recv_sw%js; je = domain%list(m)%recv_sw%je
00323 if( grid_offset_type.NE.AGRID )then
00324 is = domain%list(m)%recv_sw_off%is; ie = domain%list(m)%recv_sw_off%ie
00325 js = domain%list(m)%recv_sw_off%js; je = domain%list(m)%recv_sw_off%je
00326 end if
00327 msgsize = msgsize + (ie-is+1)*(je-js+1)*ke
00328 end if
00329 if( recv_w .AND. domain%list(m)%recv_w%overlap )then
00330 is = domain%list(m)%recv_w%is; ie = domain%list(m)%recv_w%ie
00331 js = domain%list(m)%recv_w%js; je = domain%list(m)%recv_w%je
00332 if( grid_offset_type.NE.AGRID )then
00333 is = domain%list(m)%recv_w_off%is; ie = domain%list(m)%recv_w_off%ie
00334 js = domain%list(m)%recv_w_off%js; je = domain%list(m)%recv_w_off%je
00335 end if
00336 msgsize = msgsize + (ie-is+1)*(je-js+1)*ke
00337 end if
00338 if( recv_nw .AND. domain%list(m)%recv_nw%overlap )then
00339 is = domain%list(m)%recv_nw%is; ie = domain%list(m)%recv_nw%ie
00340 js = domain%list(m)%recv_nw%js; je = domain%list(m)%recv_nw%je
00341 if( grid_offset_type.NE.AGRID )then
00342 is = domain%list(m)%recv_nw_off%is; ie = domain%list(m)%recv_nw_off%ie
00343 js = domain%list(m)%recv_nw_off%js; je = domain%list(m)%recv_nw_off%je
00344 end if
00345 msgsize = msgsize + (ie-is+1)*(je-js+1)*ke
00346 end if
00347 if( recv_n .AND. domain%list(m)%recv_n%overlap )then
00348 is = domain%list(m)%recv_n%is; ie = domain%list(m)%recv_n%ie
00349 js = domain%list(m)%recv_n%js; je = domain%list(m)%recv_n%je
00350 if( grid_offset_type.NE.AGRID )then
00351 is = domain%list(m)%recv_n_off%is; ie = domain%list(m)%recv_n_off%ie
00352 js = domain%list(m)%recv_n_off%js; je = domain%list(m)%recv_n_off%je
00353 end if
00354 msgsize = msgsize + (ie-is+1)*(je-js+1)*ke
00355 end if
00356 if( recv_ne .AND. domain%list(m)%recv_ne%overlap )then
00357 is = domain%list(m)%recv_ne%is; ie = domain%list(m)%recv_ne%ie
00358 js = domain%list(m)%recv_ne%js; je = domain%list(m)%recv_ne%je
00359 if( grid_offset_type.NE.AGRID )then
00360 is = domain%list(m)%recv_ne_off%is; ie = domain%list(m)%recv_ne_off%ie
00361 js = domain%list(m)%recv_ne_off%js; je = domain%list(m)%recv_ne_off%je
00362 end if
00363 msgsize = msgsize + (ie-is+1)*(je-js+1)*ke
00364 end if
00365 if( msgsize.GT.0 )then
00366 print *,'mpp_domains_stack_hwm ',mpp_domains_stack_hwm
00367 print *,'buffer_pos+msgsize)*wordlen ',(buffer_pos+msgsize)*wordlen
00368 print *,'max ',max( mpp_domains_stack_hwm, pos*wordlen )
00369 print *,'mpp_domains_stack_size ',mpp_domains_stack_size
00370 mpp_domains_stack_hwm = max( mpp_domains_stack_hwm, (buffer_pos+msgsize)*wordlen )
00371 if( mpp_domains_stack_hwm.GT.mpp_domains_stack_size )then
00372 write( text,'(i8)' )mpp_domains_stack_hwm
00373 call mpp_error( FATAL, 'MPP_UPDATE_DOMAINS: mpp_domains2_stack overflow, call mpp_domains_set_stack_size(' &
00374
00375 end if
00376 call mpp_recv( buffer(buffer_pos+1:buffer_pos+msgsize), msgsize, from_pe )
00377 buffer_pos = buffer_pos + msgsize
00378 end if
00379 call mpp_clock_end(recv_clock)
00380 end do
00381
00382 !unpack recv
00383 !unpack halos in reverse order
00384 do list = n-1,0,-1
00385 m = mod( domain%pos+n-list, n )
00386 if( .NOT.domain%list(m)%overlap )cycle
00387 call mpp_clock_begin(unpk_clock)
00388 from_pe = domain%list(m)%pe
00389 pos = buffer_pos
00390 if( recv_ne .AND. domain%list(m)%recv_ne%overlap )then
00391 is = domain%list(m)%recv_ne%is; ie = domain%list(m)%recv_ne%ie
00392 js = domain%list(m)%recv_ne%js; je = domain%list(m)%recv_ne%je
00393 if( grid_offset_type.NE.AGRID )then
00394 is = domain%list(m)%recv_ne_off%is; ie = domain%list(m)%recv_ne_off%ie
00395 js = domain%list(m)%recv_ne_off%js; je = domain%list(m)%recv_ne_off%je
00396 end if
00397 msgsize = (ie-is+1)*(je-js+1)*ke
00398 pos = buffer_pos - msgsize
00399 buffer_pos = pos
00400 if( domain%list(m)%recv_ne%folded )then
00401 do k = 1,ke
00402 do j = je,js,-1
00403 do i = ie,is,-1
00404 pos = pos + 1
00405 field(i,j,k) = buffer(pos)
00406 end do
00407 end do
00408 end do
00409 else
00410 do k = 1,ke
00411 do j = js,je
00412 do i = is,ie
00413 pos = pos + 1
00414 field(i,j,k) = buffer(pos)
00415 end do
00416 end do
00417 end do
00418 end if
00419 end if
00420 if( recv_n .AND. domain%list(m)%recv_n%overlap )then
00421 is = domain%list(m)%recv_n%is; ie = domain%list(m)%recv_n%ie
00422 js = domain%list(m)%recv_n%js; je = domain%list(m)%recv_n%je
00423 if( grid_offset_type.NE.AGRID )then
00424 is = domain%list(m)%recv_n_off%is; ie = domain%list(m)%recv_n_off%ie
00425 js = domain%list(m)%recv_n_off%js; je = domain%list(m)%recv_n_off%je
00426 end if
00427 msgsize = (ie-is+1)*(je-js+1)*ke
00428 pos = buffer_pos - msgsize
00429 buffer_pos = pos
00430 if( domain%list(m)%recv_n%folded )then
00431 do k = 1,ke
00432 do j = je,js,-1
00433 do i = ie,is,-1
00434 pos = pos + 1
00435 field(i,j,k) = buffer(pos)
00436 end do
00437 end do
00438 end do
00439 else
00440 do k = 1,ke
00441 do j = js,je
00442 do i = is,ie
00443 pos = pos + 1
00444 field(i,j,k) = buffer(pos)
00445 end do
00446 end do
00447 end do
00448 end if
00449 end if
00450 if( recv_nw .AND. domain%list(m)%recv_nw%overlap )then
00451 is = domain%list(m)%recv_nw%is; ie = domain%list(m)%recv_nw%ie
00452 js = domain%list(m)%recv_nw%js; je = domain%list(m)%recv_nw%je
00453 if( grid_offset_type.NE.AGRID )then
00454 is = domain%list(m)%recv_nw_off%is; ie = domain%list(m)%recv_nw_off%ie
00455 js = domain%list(m)%recv_nw_off%js; je = domain%list(m)%recv_nw_off%je
00456 end if
00457 msgsize = (ie-is+1)*(je-js+1)*ke
00458 pos = buffer_pos - msgsize
00459 buffer_pos = pos
00460 if( domain%list(m)%recv_nw%folded )then
00461 do k = 1,ke
00462 do j = je,js,-1
00463 do i = ie,is,-1
00464 pos = pos + 1
00465 field(i,j,k) = buffer(pos)
00466 end do
00467 end do
00468 end do
00469 else
00470 do k = 1,ke
00471 do j = js,je
00472 do i = is,ie
00473 pos = pos + 1
00474 field(i,j,k) = buffer(pos)
00475 end do
00476 end do
00477 end do
00478 end if
00479 end if
00480 if( recv_w .AND. domain%list(m)%recv_w%overlap )then
00481 is = domain%list(m)%recv_w%is; ie = domain%list(m)%recv_w%ie
00482 js = domain%list(m)%recv_w%js; je = domain%list(m)%recv_w%je
00483 if( grid_offset_type.NE.AGRID )then
00484 is = domain%list(m)%recv_w_off%is; ie = domain%list(m)%recv_w_off%ie
00485 js = domain%list(m)%recv_w_off%js; je = domain%list(m)%recv_w_off%je
00486 end if
00487 msgsize = (ie-is+1)*(je-js+1)*ke
00488 pos = buffer_pos - msgsize
00489 buffer_pos = pos
00490 if( domain%list(m)%recv_w%folded )then
00491 do k = 1,ke
00492 do j = je,js,-1
00493 do i = ie,is,-1
00494 pos = pos + 1
00495 field(i,j,k) = buffer(pos)
00496 end do
00497 end do
00498 end do
00499 else
00500 do k = 1,ke
00501 do j = js,je
00502 do i = is,ie
00503 pos = pos + 1
00504 field(i,j,k) = buffer(pos)
00505 end do
00506 end do
00507 end do
00508 end if
00509 end if
00510 if( recv_sw .AND. domain%list(m)%recv_sw%overlap )then
00511 is = domain%list(m)%recv_sw%is; ie = domain%list(m)%recv_sw%ie
00512 js = domain%list(m)%recv_sw%js; je = domain%list(m)%recv_sw%je
00513 if( grid_offset_type.NE.AGRID )then
00514 is = domain%list(m)%recv_sw_off%is; ie = domain%list(m)%recv_sw_off%ie
00515 js = domain%list(m)%recv_sw_off%js; je = domain%list(m)%recv_sw_off%je
00516 end if
00517 msgsize = (ie-is+1)*(je-js+1)*ke
00518 pos = buffer_pos - msgsize
00519 buffer_pos = pos
00520 if( domain%list(m)%recv_sw%folded )then
00521 do k = 1,ke
00522 do j = je,js,-1
00523 do i = ie,is,-1
00524 pos = pos + 1
00525 field(i,j,k) = buffer(pos)
00526 end do
00527 end do
00528 end do
00529 else
00530 do k = 1,ke
00531 do j = js,je
00532 do i = is,ie
00533 pos = pos + 1
00534 field(i,j,k) = buffer(pos)
00535 end do
00536 end do
00537 end do
00538 end if
00539 end if
00540 if( recv_s .AND. domain%list(m)%recv_s%overlap )then
00541 is = domain%list(m)%recv_s%is; ie = domain%list(m)%recv_s%ie
00542 js = domain%list(m)%recv_s%js; je = domain%list(m)%recv_s%je
00543 if( grid_offset_type.NE.AGRID )then
00544 is = domain%list(m)%recv_s_off%is; ie = domain%list(m)%recv_s_off%ie
00545 js = domain%list(m)%recv_s_off%js; je = domain%list(m)%recv_s_off%je
00546 end if
00547 msgsize = (ie-is+1)*(je-js+1)*ke
00548 pos = buffer_pos - msgsize
00549 buffer_pos = pos
00550 if( domain%list(m)%recv_s%folded )then
00551 do k = 1,ke
00552 do j = je,js,-1
00553 do i = ie,is,-1
00554 pos = pos + 1
00555 field(i,j,k) = buffer(pos)
00556 end do
00557 end do
00558 end do
00559 else
00560 do k = 1,ke
00561 do j = js,je
00562 do i = is,ie
00563 pos = pos + 1
00564 field(i,j,k) = buffer(pos)
00565 end do
00566 end do
00567 end do
00568 end if
00569 end if
00570 if( recv_se .AND. domain%list(m)%recv_se%overlap )then
00571 is = domain%list(m)%recv_se%is; ie = domain%list(m)%recv_se%ie
00572 js = domain%list(m)%recv_se%js; je = domain%list(m)%recv_se%je
00573 if( grid_offset_type.NE.AGRID )then
00574 is = domain%list(m)%recv_se_off%is; ie = domain%list(m)%recv_se_off%ie
00575 js = domain%list(m)%recv_se_off%js; je = domain%list(m)%recv_se_off%je
00576 end if
00577 msgsize = (ie-is+1)*(je-js+1)*ke
00578 pos = buffer_pos - msgsize
00579 buffer_pos = pos
00580 if( domain%list(m)%recv_se%folded )then
00581 do k = 1,ke
00582 do j = je,js,-1
00583 do i = ie,is,-1
00584 pos = pos + 1
00585 field(i,j,k) = buffer(pos)
00586 end do
00587 end do
00588 end do
00589 else
00590 do k = 1,ke
00591 do j = js,je
00592 do i = is,ie
00593 pos = pos + 1
00594 field(i,j,k) = buffer(pos)
00595 end do
00596 end do
00597 end do
00598 end if
00599 end if
00600 if( recv_e .AND. domain%list(m)%recv_e%overlap )then
00601 is = domain%list(m)%recv_e%is; ie = domain%list(m)%recv_e%ie
00602 js = domain%list(m)%recv_e%js; je = domain%list(m)%recv_e%je
00603 if( grid_offset_type.NE.AGRID )then
00604 is = domain%list(m)%recv_e_off%is; ie = domain%list(m)%recv_e_off%ie
00605 js = domain%list(m)%recv_e_off%js; je = domain%list(m)%recv_e_off%je
00606 end if
00607 msgsize = (ie-is+1)*(je-js+1)*ke
00608 pos = buffer_pos - msgsize
00609 buffer_pos = pos
00610 if( domain%list(m)%recv_e%folded )then
00611 do k = 1,ke
00612 do j = je,js,-1
00613 do i = ie,is,-1
00614 pos = pos + 1
00615 field(i,j,k) = buffer(pos)
00616 end do
00617 end do
00618 end do
00619 else
00620 do k = 1,ke
00621 do j = js,je
00622 do i = is,ie
00623 pos = pos + 1
00624 field(i,j,k) = buffer(pos)
00625 end do
00626 end do
00627 end do
00628 end if
00629 end if
00630 call mpp_clock_end(unpk_clock)
00631 end do
00632
00633 call mpp_clock_begin(wait_clock)
00634 call mpp_sync_self( domain%list(:)%pe )
00635 call mpp_clock_end(wait_clock)
00636 return
00637 end subroutine MPP_UPDATE_DOMAINS_3D_
00638
00639 subroutine MPP_REDISTRIBUTE_2D_( domain_in, field_in, domain_out, field_out )
00640 type(domain2D), intent(in) :: domain_in, domain_out
00641 MPP_TYPE_, intent(in) :: field_in (:,:)
00642 MPP_TYPE_, intent(out) :: field_out(:,:)
00643 MPP_TYPE_ :: field3D_in (size(field_in, 1),size(field_in, 2),1)
00644 MPP_TYPE_ :: field3D_out(size(field_out,1),size(field_out,2),1)
00645 #ifdef use_CRI_pointers
00646 pointer( ptr_in, field3D_in )
00647 pointer( ptr_out, field3D_out )
00648 ptr_in = LOC(field_in )
00649 ptr_out = LOC(field_out)
00650 call mpp_redistribute( domain_in, field3D_in, domain_out, field3D_out )
00651 #else
00652 field3D_in = RESHAPE( field_in, SHAPE(field3D_in) )
00653 call mpp_redistribute( domain_in, field3D_in, domain_out, field3D_out )
00654 field_out = RESHAPE( field3D_out, SHAPE(field_out) )
00655 #endif
00656 return
00657 end subroutine MPP_REDISTRIBUTE_2D_
00658
00659 subroutine MPP_REDISTRIBUTE_3D_( domain_in, field_in, domain_out, field_out )
00660 type(domain2D), intent(in) :: domain_in, domain_out
00661 ! MPP_TYPE_, intent(in) :: field_in ( domain_in%x%data%begin:, domain_in%y%data%begin:,:)
00662 ! MPP_TYPE_, intent(out) :: field_out(domain_out%x%data%begin:,domain_out%y%data%begin:,:)
00663 MPP_TYPE_, intent(in) :: field_in (:,:,:)
00664 MPP_TYPE_, intent(out) :: field_out(:,:,:)
00665 integer :: is, ie, js, je, ke, isc, iec, jsc, jec
00666 integer :: i, j, k
00667 integer :: list, m, n, pos, msgsize
00668 integer :: to_pe, from_pe
00669 ! MPP_TYPE_, dimension(domain_in%x%compute%size*domain_in%y%compute%size*size(field_in,3)) :: send_buf, recv_buf
00670 MPP_TYPE_ :: buffer(size(mpp_domains_stack))
00671 #ifdef use_CRI_pointers
00672 pointer( ptr, buffer )
00673 #endif
00674 integer :: buffer_pos, wordlen
00675 character(len=8) :: text
00676
00677 ! ke = size(field_in,3)
00678 ! if( ke.NE.size(field_out,3) )call mpp_error( FATAL, 'MPP_REDISTRIBUTE: mismatch between field_in and field_out.' )
00679 ! if( UBOUND(field_in,1).NE.domain_in%x%data%end .OR. &
00680 ! UBOUND(field_in,2).NE.domain_in%y%data%end ) &
00681 ! call mpp_error( FATAL, 'MPP_REDISTRIBUTE: field_in must be on data domain of domain_in.' )
00682 ! if( UBOUND(field_out,1).NE.domain_out%x%data%end .OR. &
00683 ! UBOUND(field_out,2).NE.domain_out%y%data%end ) &
00684 ! call mpp_error( FATAL, 'MPP_REDISTRIBUTE: field_out must be on data domain of domain_out.' )
00685
00686 !fix ke
00687 ke = 0
00688 if( domain_in%pe.NE.NULL_PE )ke = size(field_in,3)
00689 if( domain_out%pe.NE.NULL_PE )then
00690 if( ke.NE.0 .AND. ke.NE.size(field_out,3) ) &
00691 call mpp_error( FATAL, 'MPP_REDISTRIBUTE: mismatch between field_in and field_out.' )
00692 ke = size(field_out,3)
00693 end if
00694 if( ke.EQ.0 )call mpp_error( FATAL, 'MPP_REDISTRIBUTE: either domain_in or domain_out must be native.' )
00695 !check sizes
00696 if( domain_in%pe.NE.NULL_PE )then
00697 if( size(field_in,1).NE.domain_in%x%data%size .OR. size(field_in,2).NE.domain_in%y%data%size ) &
00698 call mpp_error( FATAL, 'MPP_REDISTRIBUTE: field_in must be on data domain of domain_in.' )
00699 end if
00700 if( domain_out%pe.NE.NULL_PE )then
00701 if( size(field_out,1).NE.domain_out%x%data%size .OR. size(field_out,2).NE.domain_out%y%data%size ) &
00702 call mpp_error( FATAL, 'MPP_REDISTRIBUTE: field_out must be on data domain of domain_out.' )
00703 end if
00704
00705 buffer_pos = 0
00706 #ifdef use_CRI_pointers
00707 ptr = LOC(mpp_domains_stack)
00708 wordlen = size(TRANSFER(buffer(1),mpp_domains_stack))
00709 #endif
00710 !send
00711 call mpp_get_compute_domain( domain_in, isc, iec, jsc, jec )
00712 n = size(domain_out%list)
00713 do list = 0,n-1
00714 m = mod( domain_out%pos+list+n, n )
00715 to_pe = domain_out%list(m)%pe
00716 call mpp_get_compute_domain( domain_out%list(m), is, ie, js, je )
00717 is = max(is,isc); ie = min(ie,iec)
00718 js = max(js,jsc); je = min(je,jec)
00719 if( ie.GE.is .AND. je.GE.js )then
00720 msgsize = (ie-is+1)*(je-js+1)*ke
00721 mpp_domains_stack_hwm = max( mpp_domains_stack_hwm, (buffer_pos+msgsize)*wordlen )
00722 if( mpp_domains_stack_hwm.GT.mpp_domains_stack_size )then
00723 write( text,'(i8)' )mpp_domains_stack_hwm
00724 call mpp_error( FATAL, 'MPP_REDISTRIBUTE: mpp_domains_stack overflow, call mpp_domains_set_stack_size(' &
00725
00726 end if
00727 pos = buffer_pos
00728 do k = 1,ke
00729 do j = js-domain_in%y%data%begin+1,je-domain_in%y%data%begin+1
00730 do i = is-domain_in%x%data%begin+1,ie-domain_in%x%data%begin+1
00731 pos = pos+1
00732 buffer(pos) = field_in(i,j,k)
00733 end do
00734 end do
00735 end do
00736 if( debug )write( stderr(),* )'PE', pe, ' to PE ', to_pe, 'is,ie,js,je=', is, ie, js, je
00737 call mpp_send( buffer(buffer_pos+1:buffer_pos+msgsize), msgsize, to_pe )
00738 buffer_pos = pos
00739 end if
00740 end do
00741 !recv
00742 call mpp_get_compute_domain( domain_out, isc, iec, jsc, jec )
00743 n = size(domain_in%list)
00744 do list = 0,n-1
00745 m = mod( domain_in%pos+n-list, n )
00746 from_pe = domain_in%list(m)%pe
00747 call mpp_get_compute_domain( domain_in%list(m), is, ie, js, je )
00748 is = max(is,isc); ie = min(ie,iec)
00749 js = max(js,jsc); je = min(je,jec)
00750 if( ie.GE.is .AND. je.GE.js )then
00751 msgsize = (ie-is+1)*(je-js+1)*ke
00752 mpp_domains_stack_hwm = max( mpp_domains_stack_hwm, (buffer_pos+msgsize)*wordlen )
00753 if( mpp_domains_stack_hwm.GT.mpp_domains_stack_size )then
00754 write( text,'(i8)' )mpp_domains_stack_hwm
00755 call mpp_error( FATAL, 'MPP_REDISTRIBUTE: mpp_domains_stack overflow, call mpp_domains_set_stack_size(' &
00756
00757 end if
00758 if( debug )write( stderr(),* )'PE', pe, ' from PE ', from_pe, 'is,ie,js,je=', is, ie, js, je
00759 call mpp_recv( buffer(buffer_pos+1:buffer_pos+msgsize), msgsize, from_pe )
00760 pos = buffer_pos
00761 do k = 1,ke
00762 do j = js-domain_out%y%data%begin+1,je-domain_out%y%data%begin+1
00763 do i = is-domain_out%x%data%begin+1,ie-domain_out%x%data%begin+1
00764 pos = pos+1
00765 field_out(i,j,k) = buffer(pos)
00766 end do
00767 end do
00768 end do
00769 buffer_pos = pos
00770 end if
00771 end do
00772
00773 ! call mpp_sync_self( domain_in%list(:)%pe )
00774 call mpp_sync_self()
00775 return
00776 end subroutine MPP_REDISTRIBUTE_3D_
00777
00778 subroutine MPP_REDISTRIBUTE_4D_( domain_in, field_in, domain_out, field_out )
00779 type(domain2D), intent(in) :: domain_in, domain_out
00780 MPP_TYPE_, intent(in) :: field_in (:,:,:,:)
00781 MPP_TYPE_, intent(out) :: field_out(:,:,:,:)
00782 MPP_TYPE_ :: field3D_in (size(field_in, 1),size(field_in, 2),size(field_in ,3)*size(field_in ,4))
00783 MPP_TYPE_ :: field3D_out(size(field_out,1),size(field_out,2),size(field_out,3)*size(field_out,4))
00784 #ifdef use_CRI_pointers
00785 pointer( ptr_in, field3D_in )
00786 pointer( ptr_out, field3D_out )
00787 ptr_in = LOC(field_in )
00788 ptr_out = LOC(field_out)
00789 call mpp_redistribute( domain_in, field3D_in, domain_out, field3D_out )
00790 #else
00791 field3D_in = RESHAPE( field_in, SHAPE(field3D_in) )
00792 call mpp_redistribute( domain_in, field3D_in, domain_out, field3D_out )
00793 field_out = RESHAPE( field3D_out, SHAPE(field_out) )
00794 #endif
00795 return
00796 end subroutine MPP_REDISTRIBUTE_4D_
00797
00798 subroutine MPP_REDISTRIBUTE_5D_( domain_in, field_in, domain_out, field_out )
00799 type(domain2D), intent(in) :: domain_in, domain_out
00800 MPP_TYPE_, intent(in) :: field_in (:,:,:,:,:)
00801 MPP_TYPE_, intent(out) :: field_out(:,:,:,:,:)
00802 MPP_TYPE_ :: field3D_in (size(field_in, 1),size(field_in, 2),&
00803 size(field_in ,3)*size(field_in ,4)*size(field_in ,5))
00804 MPP_TYPE_ :: field3D_out(size(field_out,1),size(field_out,2),&
00805 size(field_out,3)*size(field_out,4)*size(field_out,5))
00806 #ifdef use_CRI_pointers
00807 pointer( ptr_in, field3D_in )
00808 pointer( ptr_out, field3D_out )
00809 ptr_in = LOC(field_in )
00810 ptr_out = LOC(field_out)
00811 call mpp_redistribute( domain_in, field3D_in, domain_out, field3D_out )
00812 #else
00813 field3D_in = RESHAPE( field_in, SHAPE(field3D_in) )
00814 call mpp_redistribute( domain_in, field3D_in, domain_out, field3D_out )
00815 field_out = RESHAPE( field3D_out, SHAPE(field_out) )
00816 #endif
00817 return
00818 end subroutine MPP_REDISTRIBUTE_5D_
00819 #ifdef VECTOR_FIELD_
00820 !VECTOR_FIELD_ is set to false for MPP_TYPE_ integer or logical.
00821 !vector fields
00822 subroutine MPP_UPDATE_DOMAINS_2D_V_( fieldx, fieldy, domain, flags, gridtype )
00823 !updates data domain of 2D field whose computational domains have been computed
00824 MPP_TYPE_, intent(inout), dimension(:,:) :: fieldx, fieldy
00825 type(domain2D), intent(inout) :: domain
00826 integer, intent(in), optional :: flags, gridtype
00827 MPP_TYPE_ :: field3Dx(size(fieldx,1),size(fieldx,2),1)
00828 MPP_TYPE_ :: field3Dy(size(fieldy,1),size(fieldy,2),1)
00829 #ifdef use_CRI_pointers
00830 pointer( ptrx, field3Dx )
00831 pointer( ptry, field3Dy )
00832 ptrx = LOC(fieldx)
00833 ptry = LOC(fieldy)
00834 call mpp_update_domains( field3Dx, field3Dy, domain, flags, gridtype )
00835 #else
00836 field3Dx = RESHAPE( fieldx, SHAPE(field3Dx) )
00837 field3Dy = RESHAPE( fieldy, SHAPE(field3Dy) )
00838 call mpp_update_domains( field3Dx, field3Dy, domain, flags, gridtype )
00839 fieldx = RESHAPE( field3Dx, SHAPE(fieldx) )
00840 fieldy = RESHAPE( field3Dy, SHAPE(fieldy) )
00841 #endif
00842 return
00843 end subroutine MPP_UPDATE_DOMAINS_2D_V_
00844
00845 subroutine MPP_UPDATE_DOMAINS_3D_V_( fieldx, fieldy, domain, flags, gridtype )
00846 !updates data domain of 3D field whose computational domains have been computed
00847 type(domain2D), intent(inout) :: domain
00848 MPP_TYPE_, intent(inout), dimension(domain%x%data%begin:,domain%y%data%begin:,:) :: fieldx, fieldy
00849 integer, intent(in), optional :: flags, gridtype
00850 integer :: update_flags
00851 integer :: i,j,k,n, is, ie, js, je, ke, pos
00852 integer :: ioff, joff
00853 MPP_TYPE_ :: buffer(size(mpp_domains_stack))
00854 #ifdef use_CRI_pointers
00855 pointer( ptr, buffer )
00856 MPP_TYPE_ :: field(size(fieldx,1),size(fieldx,2),2*size(fieldx,3))
00857 pointer( ptrf, field )
00858 #endif
00859 integer :: buffer_pos, msgsize, wordlen
00860 character(len=8) :: text
00861
00862 !gridtype
00863 grid_offset_type = AGRID
00864 if( PRESENT(gridtype) )then
00865 if( gridtype.NE.AGRID .AND. &
00866 gridtype.NE.BGRID_NE .AND. gridtype.NE.BGRID_SW .AND. &
00867 gridtype.NE.CGRID_NE .AND. gridtype.NE.CGRID_SW ) &
00868 call mpp_error( FATAL, 'MPP_UPDATE_DOMAINS: gridtype must be one of AGRID|BGRID_NE|BGRID_SW|CGRID_NE|CGRID_SW.' )
00869 !grid_offset_type used by update domains to determine shifts.
00870 grid_offset_type = gridtype
00871 call compute_overlaps(domain)
00872 if( grid_offset_type.NE.domain%gridtype ) &
00873 call mpp_error( FATAL, 'MPP_UPDATE_DOMAINS: gridtype cannot be changed during run.' )
00874 end if
00875 !need to add code for EWS boundaries
00876 if( BTEST(domain%fold,WEST) .AND. BTEST(update_flags,WEST) ) &
00877 call mpp_error( FATAL, 'velocity stencil not yet active for WEST fold, contact author.' )
00878 if( BTEST(domain%fold,EAST) .AND. BTEST(update_flags,EAST) ) &
00879 call mpp_error( FATAL, 'velocity stencil not yet active for EAST fold, contact author.' )
00880 if( BTEST(domain%fold,SOUTH) .AND. BTEST(update_flags,SOUTH) ) &
00881 call mpp_error( FATAL, 'velocity stencil not yet active for SOUTH fold, contact author.' )
00882
00883 #ifdef use_CRI_pointers
00884 !optimization for BGRID when fieldx and fieldy are contiguous
00885 ptrf = LOC(fieldx)
00886 if( LOC(field(1,1,size(fieldx,3)+1)).EQ.LOC(fieldy) .AND. &
00887 ( domain%gridtype.EQ.BGRID_NE .OR. domain%gridtype.EQ.BGRID_SW ) )then
00888 call mpp_update_domains( field, domain, flags )
00889 else
00890 call mpp_update_domains( fieldx, domain, flags )
00891 call mpp_update_domains( fieldy, domain, flags )
00892 end if
00893 #else
00894 call mpp_update_domains( fieldx, domain, flags )
00895 call mpp_update_domains( fieldy, domain, flags )
00896 #endif
00897
00898 #ifdef use_CRI_pointers
00899 ptr = LOC(mpp_domains_stack)
00900 #endif
00901 wordlen = size(TRANSFER(buffer(1),mpp_domains_stack))
00902 buffer_pos = 0
00903 !for all gridtypes
00904 update_flags = XUPDATE+YUPDATE !default
00905 if( PRESENT(flags) )update_flags = flags
00906 ke = size(fieldx,3)
00907 call mpp_get_global_domain( domain, xsize=ioff, ysize=joff )
00908 !northern boundary fold
00909 if( BTEST(domain%fold,NORTH) .AND. BTEST(update_flags,NORTH) )then
00910 js = domain%y%global%end + 1
00911 je = domain%y%data%end
00912 if( je.GE.js )then
00913 !on offset grids, we need to move data leftward by one point
00914 pos = domain%x%pos - 1 !the one on your left
00915 if( pos.GE.0 )then
00916 is = domain%x%list(pos)%data%end+1; ie=is
00917 else if( domain%x%cyclic )then
00918 pos = pos + size(domain%x%list)
00919 is = domain%x%list(pos)%data%end+1 - ioff; ie=is
00920 else
00921 is=1; ie=0
00922 end if
00923 n = buffer_pos
00924 if( ie.EQ.is )then
00925 msgsize = (je-js+1)*ke*2 !only half this on CGRID actually
00926 mpp_domains_stack_hwm = max( mpp_domains_stack_hwm, (buffer_pos+msgsize)*wordlen )
00927 if( mpp_domains_stack_hwm.GT.mpp_domains_stack_size )then
00928 write( text,'(i8)' )mpp_domains_stack_hwm
00929 call mpp_error( FATAL, 'MPP_UPDATE: mpp_domains_stack overflow, call mpp_domains_set_stack_size(' &
00930
00931 end if
00932 select case(grid_offset_type)
00933 case(BGRID_NE)
00934 do k = 1,ke
00935 do j = js,je
00936 n = n + 2
00937 buffer(n-1) = fieldx(is,j,k)
00938 buffer(n ) = fieldy(is,j,k)
00939 end do
00940 end do
00941 call mpp_send( buffer(buffer_pos+1:buffer_pos+n), n, domain%x%list(pos)%pe )
00942 buffer_pos = buffer_pos + n
00943 case(CGRID_NE)
00944 do k = 1,ke
00945 do j = js,je
00946 n = n + 1
00947 buffer(n) = fieldx(is,j,k)
00948 end do
00949 end do
00950 call mpp_send( buffer(buffer_pos+1:buffer_pos+n), n, domain%x%list(pos)%pe )
00951 buffer_pos = buffer_pos + n
00952 end select
00953 !receive data at x%data%end
00954 pos = domain%x%pos + 1 !the one on your right
00955 if( pos.LT.size(domain%x%list) )then
00956 n = (je-js+1)*ke
00957 else if( domain%x%cyclic )then
00958 pos = pos - size(domain%x%list)
00959 n = (je-js+1)*ke
00960 else
00961 n = 0
00962 end if
00963 if( n.GT.0 )then
00964 mpp_domains_stack_hwm = max( mpp_domains_stack_hwm, (buffer_pos+n)*wordlen )
00965 if( mpp_domains_stack_hwm.GT.mpp_domains_stack_size )then
00966 write( text,'(i8)' )mpp_domains_stack_hwm
00967 call mpp_error( FATAL, 'MPP_UPDATE: mpp_domains_stack overflow, call mpp_domains_set_stack_size(' &
00968
00969 end if
00970 select case(grid_offset_type)
00971 case(BGRID_NE)
00972 do k = 1,ke
00973 do j = js,je
00974 do i = domain%x%data%begin,domain%x%data%end-1
00975 fieldx(i,j,k) = fieldx(i+1,j,k)
00976 fieldy(i,j,k) = fieldy(i+1,j,k)
00977 end do
00978 end do
00979 end do
00980 n = n*2
00981 call mpp_recv( buffer(buffer_pos+1:buffer_pos+n), n, domain%x%list(pos)%pe )
00982 i = domain%x%data%end
00983 n = buffer_pos
00984 do k = 1,ke
00985 do j = js,je
00986 n = n + 2
00987 fieldx(i,j,k) = buffer(n-1)
00988 fieldy(i,j,k) = buffer(n )
00989 end do
00990 end do
00991 case(CGRID_NE)
00992 do k = 1,ke
00993 do j = js,je
00994 do i = domain%x%data%begin,domain%x%data%end-1
00995 fieldx(i,j,k) = fieldx(i+1,j,k)
00996 fieldy(i,j,k) = fieldy(i+1,j,k)
00997 end do
00998 end do
00999 end do
01000 call mpp_recv( buffer(buffer_pos+1:buffer_pos+n), n, domain%x%list(pos)%pe )
01001 i = domain%x%data%end
01002 n = buffer_pos
01003 do k = 1,ke
01004 do j = js,je
01005 n = n + 1
01006 fieldx(i,j,k) = buffer(n)
01007 end do
01008 end do
01009 end select
01010 end if
01011 end if
01012 !flip the sign
01013 is = domain%x%data%begin
01014 ie = domain%x%data%end
01015 do k = 1,ke
01016 do j = js,je
01017 do i = is,ie
01018 fieldx(i,j,k) = -fieldx(i,j,k)
01019 fieldy(i,j,k) = -fieldy(i,j,k)
01020 end do
01021 end do
01022 end do
01023 end if
01024 !eliminate redundant vector data at fold
01025 j = domain%y%global%end
01026 if( domain%y%data%begin.LE.j .AND. j.LE.domain%y%data%end )then !fold is within domain
01027 !ship left-half data to right half: on BGRID_NE the x%data%end point is not in mirror domain and must be done separately.
01028 if( domain%x%pos.LT.(size(domain%x%list)+1)/2 )then
01029 is = domain%x%data%begin
01030 ie = min(domain%x%data%end,(domain%x%global%begin+domain%x%global%end)/2)
01031 n = buffer_pos
01032 select case(grid_offset_type)
01033 case(BGRID_NE)
01034 do k = 1,ke
01035 do i = is,ie-1
01036 n = n + 2
01037 buffer(n-1) = fieldx(i,j,k)
01038 buffer(n) = fieldy(i,j,k)
01039 end do
01040 end do
01041 call mpp_send( buffer(buffer_pos+1:n), n-buffer_pos, domain%x%list(size(domain%x%list)-domain%x%pos-1)%pe )
01042 buffer_pos = n
01043 case(CGRID_NE)
01044 do k = 1,ke
01045 do i = is,ie
01046 n = n + 1
01047 buffer(n) = fieldy(i,j,k)
01048 end do
01049 end do
01050 call mpp_send( buffer(buffer_pos+1:n), n-buffer_pos, domain%x%list(size(domain%x%list)-domain%x%pos-1)%pe )
01051 buffer_pos = n
01052 end select
01053 end if
01054 if( domain%x%pos.GE.size(domain%x%list)/2 )then
01055 is = max(domain%x%data%begin,(domain%x%global%begin+domain%x%global%end)/2+1)
01056 ie = domain%x%data%end
01057 select case(grid_offset_type)
01058 case(BGRID_NE)
01059 n = (ie-is+1)*ke*2
01060 call mpp_recv( buffer(buffer_pos+1:buffer_pos+n), n, domain%x%list(size(domain%x%list)-domain%x%pos-1)%pe )
01061 n = buffer_pos
01062 !get all values except at x%data%end
01063 do k = 1,ke
01064 do i = ie-1,is,-1
01065 n = n + 2
01066 fieldx(i,j,k) = -buffer(n-1)
01067 fieldy(i,j,k) = -buffer(n)
01068 end do
01069 end do
01070 !now get the value at domain%x%data%end
01071 pos = domain%x%pos - 1
01072 if( pos.GE.size(domain%x%list)/2 )then
01073 i = domain%x%list(pos)%data%end
01074 buffer_pos = n
01075 do k = 1,ke
01076 n = n + 2
01077 buffer(n-1) = fieldx(i,j,k)
01078 buffer(n ) = fieldy(i,j,k)
01079 end do
01080 call mpp_send( buffer(buffer_pos+1:n), n-buffer_pos, domain%x%list(pos)%pe )
01081 buffer_pos = n
01082 end if
01083 pos = domain%x%pos + 1
01084 if( pos.LT.size(domain%x%list) )then
01085 n = ke*2
01086 call mpp_recv( buffer(buffer_pos+1:buffer_pos+n), n, domain%x%list(pos)%pe )
01087 n = buffer_pos
01088 i = domain%x%data%end
01089 do k = 1,ke
01090 n = n + 2
01091 fieldx(i,j,k) = buffer(n-1)
01092 fieldy(i,j,k) = buffer(n )
01093 end do
01094 end if
01095 case(CGRID_NE)
01096 n = (ie-is+1)*ke
01097 call mpp_recv( buffer(buffer_pos+1:buffer_pos+n), n, domain%x%list(size(domain%x%list)-domain%x%pos-1)%pe )
01098 n = buffer_pos
01099 do k = 1,ke
01100 do i = ie,is,-1
01101 n = n + 1
01102 fieldy(i,j,k) = -buffer(n)
01103 end do
01104 end do
01105 end select
01106 end if
01107 !poles set to 0: BGRID only
01108 if( grid_offset_type.EQ.BGRID_NE )then
01109 do i = domain%x%global%begin-1,domain%x%global%end,(domain%x%global%begin+domain%x%global%end)/2
01110 if( domain%x%data%begin.LE.i .AND. i.LE.domain%x%data%end )then
01111 do k = 1,ke
01112 fieldx(i,j,k) = 0.
01113 fieldy(i,j,k) = 0.
01114 end do
01115 end if
01116 end do
01117 end if
01118 !these last three code blocks correct an error where the data in your halo coming from other half may have the wrong sign
01119 !off west edge
01120 select case(grid_offset_type)
01121 case(BGRID_NE)
01122 is = domain%x%global%begin - 1
01123 if( is.GT.domain%x%data%begin )then
01124 if( 2*is-domain%x%data%begin.GT.domain%x%data%end ) &
01125 call mpp_error( FATAL, 'MPP_UPDATE_DOMAINS_V: BGRID_NE west edge ubound error.' )
01126 do k = 1,ke
01127 do i = domain%x%data%begin,is-1
01128 fieldx(i,j,k) = fieldx(2*is-i,j,k)
01129 fieldy(i,j,k) = fieldy(2*is-i,j,k)
01130 end do
01131 end do
01132 end if
01133 case(CGRID_NE)
01134 is = domain%x%global%begin
01135 if( is.GT.domain%x%data%begin )then
01136 if( 2*is-domain%x%data%begin-1.GT.domain%x%data%end ) &
01137 call mpp_error( FATAL, 'MPP_UPDATE_DOMAINS_V: CGRID_NE west edge ubound error.' )
01138 do k = 1,ke
01139 do i = domain%x%data%begin,is-1
01140 fieldy(i,j,k) = fieldy(2*is-i-1,j,k)
01141 end do
01142 end do
01143 end if
01144 end select
01145 !right of midpoint
01146 is = (domain%x%global%begin+domain%x%global%end)/2
01147 if( domain%x%compute%begin.LE.is .AND. is.LT.domain%x%data%end )then
01148 select case(grid_offset_type)
01149 case(BGRID_NE)
01150 ie = domain%x%data%end
01151 if( 2*is-ie.LT.domain%x%data%begin )ie = ie - 1
01152 if( 2*is-ie.LT.domain%x%data%begin ) &
01153 call mpp_error( FATAL, 'MPP_UPDATE_DOMAINS_V: BGRID_NE midpoint lbound error.' )
01154 do k = 1,ke
01155 do i = is+1,ie
01156 fieldx(i,j,k) = -fieldx(2*is-i,j,k)
01157 fieldy(i,j,k) = -fieldy(2*is-i,j,k)
01158 end do
01159 end do
01160 case(CGRID_NE)
01161 if( 2*is-domain%x%data%end+1.LT.domain%x%data%begin ) &
01162 call mpp_error( FATAL, 'MPP_UPDATE_DOMAINS_V: CGRID_NE midpoint lbound error.' )
01163 do k = 1,ke
01164 do i = is+1,domain%x%data%end
01165 fieldy(i,j,k) = -fieldy(2*is-i+1,j,k)
01166 end do
01167 end do
01168 end select
01169 end if
01170 !off east edge
01171 is = domain%x%global%end
01172 if( is.LT.domain%x%data%end )then
01173 select case(grid_offset_type)
01174 case(BGRID_NE)
01175 if( 2*is-domain%x%data%end.LT.domain%x%data%begin ) &
01176 call mpp_error( FATAL, 'MPP_UPDATE_DOMAINS_V: BGRID_NE east edge lbound error.' )
01177 do k = 1,ke
01178 do i = is+1,domain%x%data%end
01179 fieldx(i,j,k) = fieldx(2*is-i,j,k)
01180 fieldy(i,j,k) = fieldy(2*is-i,j,k)
01181 end do
01182 end do
01183 case(CGRID_NE)
01184 if( 2*is-domain%x%data%end+1.LT.domain%x%data%begin ) &
01185 call mpp_error( FATAL, 'MPP_UPDATE_DOMAINS_V: CGRID_NE east edge lbound error.' )
01186 do k = 1,ke
01187 do i = is+1,domain%x%data%end
01188 fieldy(i,j,k) = fieldy(2*is-i+1,j,k)
01189 end do
01190 end do
01191 end select
01192 end if
01193 end if
01194 end if
01195
01196 grid_offset_type = AGRID !reset
01197 call mpp_sync_self()
01198 return
01199 end subroutine MPP_UPDATE_DOMAINS_3D_V_
01200
01201 subroutine MPP_UPDATE_DOMAINS_4D_V_( fieldx, fieldy, domain, flags, gridtype )
01202 !updates data domain of 4D field whose computational domains have been computed
01203 MPP_TYPE_, intent(inout), dimension(:,:,:,:) :: fieldx, fieldy
01204 type(domain2D), intent(inout) :: domain
01205 integer, intent(in), optional :: flags, gridtype
01206 MPP_TYPE_ :: field3Dx(size(fieldx,1),size(fieldx,2),size(fieldx,3)*size(fieldx,4))
01207 MPP_TYPE_ :: field3Dy(size(fieldy,1),size(fieldy,2),size(fieldy,3)*size(fieldy,4))
01208 #ifdef use_CRI_pointers
01209 pointer( ptrx, field3Dx )
01210 pointer( ptry, field3Dy )
01211 ptrx = LOC(fieldx)
01212 ptry = LOC(fieldy)
01213 call mpp_update_domains( field3Dx, field3Dy, domain, flags, gridtype )
01214 #else
01215 field3Dx = RESHAPE( fieldx, SHAPE(field3Dx) )
01216 field3Dy = RESHAPE( fieldy, SHAPE(field3Dy) )
01217 call mpp_update_domains( field3Dx, field3Dy, domain, flags, gridtype )
01218 fieldx = RESHAPE( field3Dx, SHAPE(fieldx) )
01219 fieldy = RESHAPE( field3Dy, SHAPE(fieldy) )
01220 #endif
01221 return
01222 end subroutine MPP_UPDATE_DOMAINS_4D_V_
01223
01224 subroutine MPP_UPDATE_DOMAINS_5D_V_( fieldx, fieldy, domain, flags, gridtype )
01225 !updates data domain of 5D field whose computational domains have been computed
01226 MPP_TYPE_, intent(inout), dimension(:,:,:,:,:) :: fieldx, fieldy
01227 type(domain2D), intent(inout) :: domain
01228 integer, intent(in), optional :: flags, gridtype
01229 MPP_TYPE_ :: field3Dx(size(fieldx,1),size(fieldx,2),size(fieldx,3)*size(fieldx,4)*size(fieldx,5))
01230 MPP_TYPE_ :: field3Dy(size(fieldy,1),size(fieldy,2),size(fieldy,3)*size(fieldy,4)*size(fieldy,5))
01231 #ifdef use_CRI_pointers
01232 pointer( ptrx, field3Dx )
01233 pointer( ptry, field3Dy )
01234 ptrx = LOC(fieldx)
01235 ptry = LOC(fieldy)
01236 call mpp_update_domains( field3Dx, field3Dy, domain, flags, gridtype )
01237 #else
01238 field3Dx = RESHAPE( fieldx, SHAPE(field3Dx) )
01239 field3Dy = RESHAPE( fieldy, SHAPE(field3Dy) )
01240 call mpp_update_domains( field3Dx, field3Dy, domain, flags, gridtype )
01241 fieldx = RESHAPE( field3Dx, SHAPE(fieldx) )
01242 fieldy = RESHAPE( field3Dy, SHAPE(fieldy) )
01243 #endif
01244 return
01245 end subroutine MPP_UPDATE_DOMAINS_5D_V_
01246 #endif VECTOR_FIELD_