Oasis3 4.0.2
|
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 //trim(text)//') from all PEs.' ) 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 //trim(text)//') from all PEs.' ) 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 //trim(text)//') from all PEs.' ) 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 //trim(text)//') from all PEs.' ) 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 //trim(text)//') from all PEs.' ) 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 //trim(text)//') from all PEs.' ) 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_