mpp_domains_mod_oa.F90

Go to the documentation of this file.
00001 #ifndef key_noIO
00002 !-----------------------------------------------------------------------
00003 !   Domain decomposition and domain update for message-passing codes
00004 !
00005 ! AUTHOR: V. Balaji (vbalaji@noaa.gov)
00006 !         Princeton University/GFDL
00007 !
00008 ! MODIFICATIONS: Reiner Vogelsang (reiner@sgi.com)
00009 !                Sophie Valcke: renamed the routine with _oa suffix
00010 !
00011 ! This program is free software; The author agrees that you can
00012 ! redistribute and/or modify this version of the program under the
00013 ! terms of the Lesser GNU General Public License as published
00014 ! by the Free Software Foundation.
00015 !
00016 ! This program is distributed in the hope that it will be useful,
00017 ! but WITHOUT ANY WARRANTY; without even the implied warranty of
00018 ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019 ! Lesser GNU General Public License for more details
00020 ! (http://www.gnu.org/copyleft/lesser.html).
00021 !-----------------------------------------------------------------------
00022 !#include <os.h>
00023 #if defined(_CRAYT3E) || defined(_CRAYT3D) || defined(sgi_mipspro)
00024 #define SGICRAY_MPP
00025 #endif
00026 !shmalloc is used on MPP SGI/Cray systems for shmem
00027 #if defined(use_libSMA) && defined(SGICRAY_MPP)
00028 #define use_shmalloc
00029 #endif
00030 
00031 module mpp_domains_mod_oa
00032   use mod_kinds_mpp
00033 !a generalized domain decomposition package for use with mpp_mod_oa
00034 !Balaji (vb@gfdl.gov) 15 March 1999
00035   use mpp_mod_oa
00036 #include <os.h>
00037   implicit none
00038   private
00039   character(len=128), private :: version= 
00040        '$Id: mpp_domains_mod_oa.F90 1732 2008-09-04 09:33:50Z valcke $'
00041   character(len=128), private :: tagname= 
00042        '$Name$'
00043   character(len=128), private :: version_update_domains2D, version_global_reduce, version_global_sum, version_global_field
00044 
00045 !parameters used to define domains: these are passed to the flags argument of mpp_define_domains
00046 !  if data domain is to have global extent, set GLOBAL_DATA_DOMAIN
00047 !  if global domain has periodic boundaries, set CYCLIC_GLOBAL_DOMAIN
00048 !  sum flags together if more than one of the above conditions is to be met.
00049   integer, parameter, private :: GLOBAL=0, CYCLIC=1
00050   integer, parameter, private :: WEST=2, EAST=3, SOUTH=4, NORTH=5
00051   integer, parameter, private :: SEND=1, RECV=2
00052   integer, parameter, public :: GLOBAL_DATA_DOMAIN=2**GLOBAL, CYCLIC_GLOBAL_DOMAIN=2**CYCLIC
00053 !gridtypes
00054   integer, parameter, private :: AGRID=0, BGRID=1, CGRID=2
00055   integer, parameter, public :: BGRID_NE=BGRID+2**NORTH+2**EAST
00056   integer, parameter, public :: BGRID_SW=BGRID+2**SOUTH+2**WEST
00057   integer, parameter, public :: CGRID_NE=CGRID+2**NORTH+2**EAST
00058   integer, parameter, public :: CGRID_SW=CGRID+2**SOUTH+2**WEST
00059   integer, private :: grid_offset_type=AGRID
00060 !folds
00061   integer, parameter, public :: FOLD_WEST_EDGE = 2**WEST, FOLD_EAST_EDGE = 2**EAST
00062   integer, parameter, public :: FOLD_SOUTH_EDGE=2**SOUTH, FOLD_NORTH_EDGE=2**NORTH
00063 !update
00064   integer, parameter, public :: WUPDATE=2**WEST, EUPDATE=2**EAST, SUPDATE=2**SOUTH, NUPDATE=2**NORTH
00065   integer, parameter, public :: XUPDATE=WUPDATE+EUPDATE, YUPDATE=SUPDATE+NUPDATE
00066 !used by mpp_global_sum
00067   integer, parameter, public :: BITWISE_EXACT_SUM=1
00068 
00069   type, public :: domain_axis_spec        !type used to specify index limits along an axis of a domain
00070      private
00071      integer :: begin, end, size, max_size      !start, end of domain axis, size, max size in set
00072      logical :: is_global       !TRUE if domain axis extent covers global domain
00073   end type domain_axis_spec
00074   type, public :: domain1D
00075      private
00076      type(domain_axis_spec) :: compute, data, global
00077      logical :: cyclic
00078      type(domain1D), pointer :: list(:)
00079      integer :: pe              !PE to which this domain is assigned
00080      integer :: pos             !position of this PE within link list, i.e domain%list(pos)%pe = pe
00081   end type domain1D
00082 !domaintypes of higher rank can be constructed from type domain1D
00083 !typically we only need 1 and 2D, but could need higher (e.g 3D LES)
00084 !some elements are repeated below if they are needed once per domain, not once per axis
00085   type, private :: rectangle
00086      integer :: is, ie, js, je
00087      logical :: overlap, folded
00088   end type rectangle
00089   type, public :: domain2D
00090      private
00091      type(domain1D) :: x
00092      type(domain1D) :: y
00093      type(domain2D), pointer :: list(:)
00094      integer :: pe              !PE to which this domain is assigned
00095      integer :: pos             !position of this PE within link list, i.e domain%list(pos)%pe = pe
00096      integer :: fold, gridtype
00097      logical :: overlap
00098      type(rectangle) :: recv_e, recv_se, recv_s, recv_sw, 
00099                         recv_w, recv_nw, recv_n, recv_ne
00100      type(rectangle) :: send_e, send_se, send_s, send_sw, 
00101                         send_w, send_nw, send_n, send_ne
00102      logical :: remote_domains_initialized
00103      type(rectangle) :: recv_e_off, recv_se_off, recv_s_off, recv_sw_off, 
00104                         recv_w_off, recv_nw_off, recv_n_off, recv_ne_off
00105      type(rectangle) :: send_e_off, send_se_off, send_s_off, send_sw_off, 
00106                         send_w_off, send_nw_off, send_n_off, send_ne_off
00107      logical :: remote_off_domains_initialized
00108   end type domain2D
00109   type(domain1D), public :: NULL_DOMAIN1D
00110   type(domain2D), public :: NULL_DOMAIN2D
00111 
00112   integer, private :: pe
00113 
00114   integer, private :: tk
00115   logical, private :: verbose=.FALSE., debug=.FALSE., domain_clocks_on=.FALSE.
00116   logical, private :: module_is_initialized=.FALSE.
00117   integer, parameter, public :: MPP_DOMAIN_TIME=MPP_DEBUG+1
00118   integer :: send_clock=0, recv_clock=0, unpk_clock=0, wait_clock=0, pack_clock=0, pack_loop_clock=0
00119 
00120 !stack for internal buffers
00121 !allocated differently if use_shmalloc
00122 #ifdef use_shmalloc
00123   real(DOUBLE_KIND), private :: mpp_domains_stack(1)
00124   pointer( ptr_stack, mpp_domains_stack )
00125 #else
00126   real(DOUBLE_KIND), private, allocatable :: mpp_domains_stack(:)
00127 #endif
00128   integer, private :: mpp_domains_stack_size=0, mpp_domains_stack_hwm=0
00129 
00130 !used by mpp_define_domains2D_new to transmit data
00131   integer :: domain_info_buf(16)
00132 #ifdef use_shmalloc
00133   pointer( ptr_info, domain_info_buf )
00134 #endif
00135 
00136 !public interfaces
00137 
00138 ! this interface can add halo to a no-halo domain and copy everything else.
00139 
00140   interface mpp_copy_domains
00141      module procedure mpp_copy_domains1D
00142      module procedure mpp_copy_domains2D
00143   end interface
00144 
00145   interface mpp_define_domains
00146      module procedure mpp_define_domains1D
00147      module procedure mpp_define_domains2D
00148   end interface
00149 
00150   interface mpp_update_domains
00151      module procedure mpp_update_domain2D_r8_2d
00152      module procedure mpp_update_domain2D_r8_3d
00153      module procedure mpp_update_domain2D_r8_4d
00154      module procedure mpp_update_domain2D_r8_5d
00155      module procedure mpp_update_domain2D_r8_2dv
00156      module procedure mpp_update_domain2D_r8_3dv
00157      module procedure mpp_update_domain2D_r8_4dv
00158      module procedure mpp_update_domain2D_r8_5dv
00159      module procedure mpp_update_domain2D_c8_2d
00160      module procedure mpp_update_domain2D_c8_3d
00161      module procedure mpp_update_domain2D_c8_4d
00162      module procedure mpp_update_domain2D_c8_5d
00163 #ifndef no_8byte_integers
00164      module procedure mpp_update_domain2D_i8_2d
00165      module procedure mpp_update_domain2D_i8_3d
00166      module procedure mpp_update_domain2D_i8_4d
00167      module procedure mpp_update_domain2D_i8_5d
00168      module procedure mpp_update_domain2D_l8_2d
00169      module procedure mpp_update_domain2D_l8_3d
00170      module procedure mpp_update_domain2D_l8_4d
00171      module procedure mpp_update_domain2D_l8_5d
00172 #endif
00173 #ifndef no_4byte_reals
00174      module procedure mpp_update_domain2D_r4_2d
00175      module procedure mpp_update_domain2D_r4_3d
00176      module procedure mpp_update_domain2D_r4_4d
00177      module procedure mpp_update_domain2D_r4_5d
00178 #endif
00179 #ifndef no_4byte_cmplx
00180      module procedure mpp_update_domain2D_c4_2d
00181      module procedure mpp_update_domain2D_c4_3d
00182      module procedure mpp_update_domain2D_c4_4d
00183      module procedure mpp_update_domain2D_c4_5d
00184 #endif
00185      module procedure mpp_update_domain2D_i4_2d
00186      module procedure mpp_update_domain2D_i4_3d
00187      module procedure mpp_update_domain2D_i4_4d
00188      module procedure mpp_update_domain2D_i4_5d
00189      module procedure mpp_update_domain2D_l4_2d
00190      module procedure mpp_update_domain2D_l4_3d
00191      module procedure mpp_update_domain2D_l4_4d
00192      module procedure mpp_update_domain2D_l4_5d
00193 #ifndef no_4byte_reals
00194      module procedure mpp_update_domain2D_r4_2dv
00195      module procedure mpp_update_domain2D_r4_3dv
00196      module procedure mpp_update_domain2D_r4_4dv
00197      module procedure mpp_update_domain2D_r4_5dv
00198 #endif
00199 
00200 !     module procedure mpp_update_domain1D_r8_2d
00201 !     module procedure mpp_update_domain1D_r8_3d
00202 !     module procedure mpp_update_domain1D_r8_4d
00203 !     module procedure mpp_update_domain1D_r8_5d
00204 !     module procedure mpp_update_domain1D_c8_2d
00205 !     module procedure mpp_update_domain1D_c8_3d
00206 !     module procedure mpp_update_domain1D_c8_4d
00207 !     module procedure mpp_update_domain1D_c8_5d
00208 !#ifndef no_8byte_integers
00209 !     module procedure mpp_update_domain1D_i8_2d
00210 !     module procedure mpp_update_domain1D_i8_3d
00211 !     module procedure mpp_update_domain1D_i8_4d
00212 !     module procedure mpp_update_domain1D_i8_5d
00213 !     module procedure mpp_update_domain1D_l8_2d
00214 !     module procedure mpp_update_domain1D_l8_3d
00215 !     module procedure mpp_update_domain1D_l8_4d
00216 !     module procedure mpp_update_domain1D_l8_5d
00217 !#endif
00218 !     module procedure mpp_update_domain1D_r4_2d
00219 !     module procedure mpp_update_domain1D_r4_3d
00220 !     module procedure mpp_update_domain1D_r4_4d
00221 !     module procedure mpp_update_domain1D_r4_5d
00222 !     module procedure mpp_update_domain1D_c4_2d
00223 !     module procedure mpp_update_domain1D_c4_3d
00224 !     module procedure mpp_update_domain1D_c4_4d
00225 !     module procedure mpp_update_domain1D_c4_5d
00226 !     module procedure mpp_update_domain1D_i4_2d
00227 !     module procedure mpp_update_domain1D_i4_3d
00228 !     module procedure mpp_update_domain1D_i4_4d
00229 !     module procedure mpp_update_domain1D_i4_5d
00230 !     module procedure mpp_update_domain1D_l4_2d
00231 !     module procedure mpp_update_domain1D_l4_3d
00232 !     module procedure mpp_update_domain1D_l4_4d
00233 !     module procedure mpp_update_domain1D_l4_5d
00234   end interface
00235 
00236   interface mpp_redistribute
00237      module procedure mpp_redistribute_r8_2D
00238      module procedure mpp_redistribute_r8_3D
00239      module procedure mpp_redistribute_r8_4D
00240      module procedure mpp_redistribute_r8_5D
00241      module procedure mpp_redistribute_c8_2D
00242      module procedure mpp_redistribute_c8_3D
00243      module procedure mpp_redistribute_c8_4D
00244      module procedure mpp_redistribute_c8_5D
00245 #ifndef no_8byte_integers
00246      module procedure mpp_redistribute_i8_2D
00247      module procedure mpp_redistribute_i8_3D
00248      module procedure mpp_redistribute_i8_4D
00249      module procedure mpp_redistribute_i8_5D
00250      module procedure mpp_redistribute_l8_2D
00251      module procedure mpp_redistribute_l8_3D
00252      module procedure mpp_redistribute_l8_4D
00253      module procedure mpp_redistribute_l8_5D
00254 #endif
00255 #ifndef no_4byte_reals
00256      module procedure mpp_redistribute_r4_2D
00257      module procedure mpp_redistribute_r4_3D
00258      module procedure mpp_redistribute_r4_4D
00259      module procedure mpp_redistribute_r4_5D
00260 #endif
00261 #ifndef no_4byte_cmplx
00262      module procedure mpp_redistribute_c4_2D
00263      module procedure mpp_redistribute_c4_3D
00264      module procedure mpp_redistribute_c4_4D
00265      module procedure mpp_redistribute_c4_5D
00266 #endif
00267      module procedure mpp_redistribute_i4_2D
00268      module procedure mpp_redistribute_i4_3D
00269      module procedure mpp_redistribute_i4_4D
00270      module procedure mpp_redistribute_i4_5D
00271      module procedure mpp_redistribute_l4_2D
00272      module procedure mpp_redistribute_l4_3D
00273      module procedure mpp_redistribute_l4_4D
00274      module procedure mpp_redistribute_l4_5D
00275   end interface
00276 
00277   interface mpp_global_field
00278      module procedure mpp_global_field2D_r8_2d
00279      module procedure mpp_global_field2D_r8_3d
00280      module procedure mpp_global_field2D_r8_4d
00281      module procedure mpp_global_field2D_r8_5d
00282      module procedure mpp_global_field2D_c8_2d
00283      module procedure mpp_global_field2D_c8_3d
00284      module procedure mpp_global_field2D_c8_4d
00285      module procedure mpp_global_field2D_c8_5d
00286 #ifndef no_8byte_integers
00287      module procedure mpp_global_field2D_i8_2d
00288      module procedure mpp_global_field2D_i8_3d
00289      module procedure mpp_global_field2D_i8_4d
00290      module procedure mpp_global_field2D_i8_5d
00291      module procedure mpp_global_field2D_l8_2d
00292      module procedure mpp_global_field2D_l8_3d
00293      module procedure mpp_global_field2D_l8_4d
00294      module procedure mpp_global_field2D_l8_5d
00295 #endif
00296 #ifndef no_4byte_reals
00297      module procedure mpp_global_field2D_r4_2d
00298      module procedure mpp_global_field2D_r4_3d
00299      module procedure mpp_global_field2D_r4_4d
00300      module procedure mpp_global_field2D_r4_5d
00301 #endif
00302 #ifndef no_4byte_cmplx
00303      module procedure mpp_global_field2D_c4_2d
00304      module procedure mpp_global_field2D_c4_3d
00305      module procedure mpp_global_field2D_c4_4d
00306      module procedure mpp_global_field2D_c4_5d
00307 #endif
00308      module procedure mpp_global_field2D_i4_2d
00309      module procedure mpp_global_field2D_i4_3d
00310      module procedure mpp_global_field2D_i4_4d
00311      module procedure mpp_global_field2D_i4_5d
00312      module procedure mpp_global_field2D_l4_2d
00313      module procedure mpp_global_field2D_l4_3d
00314      module procedure mpp_global_field2D_l4_4d
00315      module procedure mpp_global_field2D_l4_5d
00316      module procedure mpp_global_field1D_r8_2d
00317      module procedure mpp_global_field1D_c8_2d
00318 #ifndef no_8byte_integers
00319      module procedure mpp_global_field1D_i8_2d
00320      module procedure mpp_global_field1D_l8_2d
00321 #endif
00322 #ifndef no_4byte_reals
00323      module procedure mpp_global_field1D_r4_2d
00324 #endif
00325 #ifndef no_4byte_cmplx
00326      module procedure mpp_global_field1D_c4_2d
00327 #endif
00328      module procedure mpp_global_field1D_i4_2d
00329      module procedure mpp_global_field1D_l4_2d
00330   end interface
00331 
00332   interface mpp_global_max
00333      module procedure mpp_global_max_r8_2d
00334      module procedure mpp_global_max_r8_3d
00335      module procedure mpp_global_max_r8_4d
00336      module procedure mpp_global_max_r8_5d
00337 #ifndef no_4byte_reals
00338      module procedure mpp_global_max_r4_2d
00339      module procedure mpp_global_max_r4_3d
00340      module procedure mpp_global_max_r4_4d
00341      module procedure mpp_global_max_r4_5d
00342 #endif
00343 #ifndef no_8byte_integers
00344      module procedure mpp_global_max_i8_2d
00345      module procedure mpp_global_max_i8_3d
00346      module procedure mpp_global_max_i8_4d
00347      module procedure mpp_global_max_i8_5d
00348 #endif
00349      module procedure mpp_global_max_i4_2d
00350      module procedure mpp_global_max_i4_3d
00351      module procedure mpp_global_max_i4_4d
00352      module procedure mpp_global_max_i4_5d
00353   end interface
00354 
00355   interface mpp_global_min
00356      module procedure mpp_global_min_r8_2d
00357      module procedure mpp_global_min_r8_3d
00358      module procedure mpp_global_min_r8_4d
00359      module procedure mpp_global_min_r8_5d
00360 #ifndef no_4byte_reals
00361      module procedure mpp_global_min_r4_2d
00362      module procedure mpp_global_min_r4_3d
00363      module procedure mpp_global_min_r4_4d
00364      module procedure mpp_global_min_r4_5d
00365 #endif
00366 #ifndef no_8byte_integers
00367      module procedure mpp_global_min_i8_2d
00368      module procedure mpp_global_min_i8_3d
00369      module procedure mpp_global_min_i8_4d
00370      module procedure mpp_global_min_i8_5d
00371 #endif
00372      module procedure mpp_global_min_i4_2d
00373      module procedure mpp_global_min_i4_3d
00374      module procedure mpp_global_min_i4_4d
00375      module procedure mpp_global_min_i4_5d
00376   end interface
00377 
00378   interface mpp_global_sum
00379      module procedure mpp_global_sum_r8_2d
00380      module procedure mpp_global_sum_r8_3d
00381      module procedure mpp_global_sum_r8_4d
00382      module procedure mpp_global_sum_r8_5d
00383 #ifndef no_4byte_reals
00384      module procedure mpp_global_sum_r4_2d
00385      module procedure mpp_global_sum_r4_3d
00386      module procedure mpp_global_sum_r4_4d
00387      module procedure mpp_global_sum_r4_5d
00388 #endif
00389      module procedure mpp_global_sum_c8_2d
00390      module procedure mpp_global_sum_c8_3d
00391      module procedure mpp_global_sum_c8_4d
00392      module procedure mpp_global_sum_c8_5d
00393 #ifndef no_4byte_cmplx
00394      module procedure mpp_global_sum_c4_2d
00395      module procedure mpp_global_sum_c4_3d
00396      module procedure mpp_global_sum_c4_4d
00397      module procedure mpp_global_sum_c4_5d
00398 #endif
00399 #ifndef no_8byte_integers
00400      module procedure mpp_global_sum_i8_2d
00401      module procedure mpp_global_sum_i8_3d
00402      module procedure mpp_global_sum_i8_4d
00403      module procedure mpp_global_sum_i8_5d
00404 #endif
00405      module procedure mpp_global_sum_i4_2d
00406      module procedure mpp_global_sum_i4_3d
00407      module procedure mpp_global_sum_i4_4d
00408      module procedure mpp_global_sum_i4_5d
00409   end interface
00410 
00411   interface operator(.EQ.)
00412      module procedure mpp_domain1D_eq
00413      module procedure mpp_domain2D_eq
00414   end interface
00415 
00416   interface operator(.NE.)
00417      module procedure mpp_domain1D_ne
00418      module procedure mpp_domain2D_ne
00419   end interface
00420 
00421   interface mpp_get_compute_domain
00422      module procedure mpp_get_compute_domain1D
00423      module procedure mpp_get_compute_domain2D
00424   end interface
00425 
00426   interface mpp_get_compute_domains
00427      module procedure mpp_get_compute_domains1D
00428      module procedure mpp_get_compute_domains2D
00429   end interface
00430 
00431   interface mpp_get_data_domain
00432      module procedure mpp_get_data_domain1D
00433      module procedure mpp_get_data_domain2D
00434   end interface
00435 
00436   interface mpp_get_global_domain
00437      module procedure mpp_get_global_domain1D
00438      module procedure mpp_get_global_domain2D
00439   end interface
00440 
00441   interface mpp_define_layout
00442      module procedure mpp_define_layout2D
00443   end interface
00444 
00445   interface mpp_get_pelist
00446      module procedure mpp_get_pelist1D
00447      module procedure mpp_get_pelist2D
00448   end interface
00449 
00450   interface mpp_get_layout
00451      module procedure mpp_get_layout1D
00452      module procedure mpp_get_layout2D
00453   end interface
00454 
00455   public :: mpp_broadcast_domain, mpp_define_layout, mpp_define_domains, mpp_domains_init, mpp_domains_set_stack_size, &
00456             mpp_domains_exit, mpp_get_compute_domain, mpp_get_compute_domains, mpp_get_data_domain, mpp_get_global_domain, &
00457             mpp_get_domain_components, mpp_get_layout, mpp_get_pelist, mpp_redistribute, mpp_update_domains, &
00458             mpp_global_field, mpp_global_max, mpp_global_min, mpp_global_sum, operator(.EQ.), operator(.NE.), &
00459             mpp_copy_domains
00460 
00461   contains
00462 
00463 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00464 !                                                                             !
00465 !                 MPP_DOMAINS: initialization and termination                 !
00466 !                                                                             !
00467 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00468 
00469     subroutine mpp_domains_init(flags)
00470 !initialize domain decomp package
00471       integer, intent(in), optional :: flags
00472       integer :: l=0
00473 
00474       if( module_is_initialized )return
00475       call mpp_init(flags)           !this is a no-op if already initialized
00476       pe = mpp_pe()
00477       module_is_initialized = .TRUE.
00478       if( pe.EQ.mpp_root_pe() )then
00479           write( stdout(),'(/a)' )'MPP_DOMAINS module '//trim(version) &
00480                //trim(tagname)
00481 !          write( stdout(),'(a)' )trim(version_update_domains2D)
00482       end if
00483 
00484       if( PRESENT(flags) )then
00485           debug   = flags.EQ.MPP_DEBUG
00486           verbose = flags.EQ.MPP_VERBOSE .OR. debug
00487           domain_clocks_on = flags.EQ.MPP_DOMAIN_TIME
00488       end if
00489 
00490       call mpp_domains_set_stack_size(983040) !default, pretty arbitrary
00491 #ifdef use_shmalloc
00492       call mpp_malloc( ptr_info, 16, l )
00493 #endif
00494 
00495 !NULL_DOMAIN is a domaintype that can be used to initialize to undef
00496       NULL_DOMAIN1D%global%begin  = -1; NULL_DOMAIN1D%global%end  = -1; NULL_DOMAIN1D%global%size = 0
00497       NULL_DOMAIN1D%data%begin    = -1; NULL_DOMAIN1D%data%end    = -1; NULL_DOMAIN1D%data%size = 0
00498       NULL_DOMAIN1D%compute%begin = -1; NULL_DOMAIN1D%compute%end = -1; NULL_DOMAIN1D%compute%size = 0
00499       NULL_DOMAIN1D%pe = ANY_PE
00500       NULL_DOMAIN2D%x = NULL_DOMAIN1D
00501       NULL_DOMAIN2D%y = NULL_DOMAIN1D
00502       NULL_DOMAIN2D%pe = ANY_PE
00503 
00504       if( domain_clocks_on )then
00505           pack_clock = mpp_clock_id( 'Halo pack' )
00506           pack_loop_clock = mpp_clock_id( 'Halo pack loop' )
00507           send_clock = mpp_clock_id( 'Halo send' )
00508           recv_clock = mpp_clock_id( 'Halo recv' )
00509           unpk_clock = mpp_clock_id( 'Halo unpk' )
00510           wait_clock = mpp_clock_id( 'Halo wait' )
00511       end if
00512       return
00513     end subroutine mpp_domains_init
00514 
00515     subroutine mpp_domains_set_stack_size(n)
00516 !set the mpp_domains_stack variable to be at least n LONG words long
00517       integer, intent(in) :: n
00518       character(len=8) :: text
00519 
00520       if( n.LE.mpp_domains_stack_size )return
00521 #ifdef use_shmalloc
00522       call mpp_malloc( ptr_stack, n, mpp_domains_stack_size )
00523 #else
00524       if( allocated(mpp_domains_stack) )deallocate(mpp_domains_stack)
00525       allocate( mpp_domains_stack(n) )
00526       mpp_domains_stack_size = n
00527 #endif
00528       write( text,'(i8)' )n
00529       if( pe.EQ.mpp_root_pe() )call mpp_error( NOTE, 'MPP_DOMAINS_SET_STACK_SIZE: stack size set to '//text//'.' )
00530 
00531       return
00532     end subroutine mpp_domains_set_stack_size
00533 
00534     subroutine mpp_domains_exit()
00535 !currently does not have much to do, but provides the possibility of re-initialization
00536       if( .NOT.module_is_initialized )return
00537       call mpp_max(mpp_domains_stack_hwm)
00538       if( pe.EQ.mpp_root_pe() )write( stdout(),* )'MPP_DOMAINS_STACK high water mark=', mpp_domains_stack_hwm
00539       module_is_initialized = .FALSE.
00540       return
00541     end subroutine mpp_domains_exit
00542 
00543 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00544 !                                                                             !
00545 !                MPP_DOMAINS: overloaded operators (==, /=)                   !
00546 !                                                                             !
00547 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00548 
00549     function mpp_domain1D_eq( a, b )
00550       logical :: mpp_domain1D_eq
00551       type(domain1D), intent(in) :: a, b
00552 
00553       mpp_domain1D_eq = ( a%compute%begin.EQ.b%compute%begin .AND. &
00554                           a%compute%end  .EQ.b%compute%end   .AND. &
00555                           a%data%begin   .EQ.b%data%begin    .AND. &
00556                           a%data%end     .EQ.b%data%end      .AND. & 
00557                           a%global%begin .EQ.b%global%begin  .AND. &
00558                           a%global%end   .EQ.b%global%end    )
00559 !compare pelists
00560 !      if( mpp_domain1D_eq )mpp_domain1D_eq = ASSOCIATED(a%list) .AND. ASSOCIATED(b%list)
00561 !      if( mpp_domain1D_eq )mpp_domain1D_eq = size(a%list).EQ.size(b%list)
00562 !      if( mpp_domain1D_eq )mpp_domain1D_eq = ALL(a%list%pe.EQ.b%list%pe)
00563       
00564       return
00565     end function mpp_domain1D_eq
00566 
00567     function mpp_domain1D_ne( a, b )
00568       logical :: mpp_domain1D_ne
00569       type(domain1D), intent(in) :: a, b
00570 
00571       mpp_domain1D_ne = .NOT. ( a.EQ.b )
00572       return
00573     end function mpp_domain1D_ne
00574 
00575     function mpp_domain2D_eq( a, b )
00576       logical :: mpp_domain2D_eq
00577       type(domain2D), intent(in) :: a, b
00578 
00579       mpp_domain2D_eq = a%x.EQ.b%x .AND. a%y.EQ.b%y
00580       if( mpp_domain2D_eq .AND. ((a%pe.EQ.ANY_PE).OR.(b%pe.EQ.ANY_PE)) )return !NULL_DOMAIN2D
00581 !compare pelists
00582       if( mpp_domain2D_eq )mpp_domain2D_eq = ASSOCIATED(a%list) .AND. ASSOCIATED(b%list)
00583       if( mpp_domain2D_eq )mpp_domain2D_eq = size(a%list).EQ.size(b%list)
00584       if( mpp_domain2D_eq )mpp_domain2D_eq = ALL(a%list%pe.EQ.b%list%pe)
00585       return
00586     end function mpp_domain2D_eq
00587 
00588     function mpp_domain2D_ne( a, b )
00589       logical :: mpp_domain2D_ne
00590       type(domain2D), intent(in) :: a, b
00591 
00592       mpp_domain2D_ne = .NOT. ( a.EQ.b )
00593       return
00594     end function mpp_domain2D_ne
00595 
00596 
00597 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00598 !                                                                             !
00599 !              MPP_COPY_DOMAINS: Copy domain and add halo                     !
00600 !                                                                             !
00601 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00602 
00603     subroutine mpp_copy_domains1D(domain_in, domain_out, halo)
00604 ! ARGUMENTS
00605 ! domain_in is the input domain
00606 ! domain_out is the returned domain
00607 ! halo (optional) defines halo width (currently the same on both sides)
00608 
00609       type(domain1D), intent(in)    :: domain_in
00610       type(domain1D), intent(out)   :: domain_out
00611       integer, intent(in), optional :: halo
00612 
00613       integer, dimension(:), allocatable :: pelist, extent
00614       integer :: ndivs, global_indices(2) !(/ isg, ieg /)
00615       integer :: isg, ieg, halosz
00616 
00617       
00618 ! get the global indices of the input domain
00619       call mpp_get_global_domain(domain_in, isg, ieg )
00620       global_indices(1) = isg;       global_indices(2) = ieg
00621 
00622 ! get the number of divisions of domain
00623       call mpp_get_layout(domain_in, ndivs)
00624 
00625       allocate(pelist(0:ndivs-1),extent(0:ndivs-1))
00626 
00627 ! get the pe list of the input domain
00628       call mpp_get_pelist( domain_in, pelist)
00629 
00630 ! get the halo
00631       halosz = 0
00632       if(present(halo)) halosz = halo
00633 
00634 ! get the extent
00635       call mpp_get_compute_domains(Domain_in, size = extent(0:ndivs-1))      
00636 
00637       call mpp_define_domains( global_indices, ndivs, domain_out, pelist = pelist, &
00638                                  halo = halosz, extent = extent )
00639 
00640     end subroutine mpp_copy_domains1D
00641 
00642 
00643 !----------------------------------------------------------------------------------
00644 
00645 
00646     subroutine mpp_copy_domains2D(domain_in, domain_out, xhalo, yhalo)
00647 ! ARGUMENTS
00648 ! domain_in is the input domain
00649 ! domain_out is the returned domain
00650 ! xhalo, yhalo (optional) defines halo width. 
00651 
00652       type(domain2D), intent(in)    :: domain_in
00653       type(domain2D), intent(out)   :: domain_out
00654       integer, intent(in), optional :: xhalo, yhalo
00655 
00656       integer, dimension(:), allocatable :: pelist, xextent, yextent, xbegin, xend, 
00657                                             xsize, ybegin, yend, ysize
00658       integer :: ndivx, ndivy, ndivs, npes, global_indices(4), layout(2)
00659       integer :: isg, ieg, jsg, jeg, xhalosz, yhalosz, i, j, m, n, pe
00660       
00661 ! get the global indices of the input domain
00662       call mpp_get_global_domain(domain_in, isg, ieg, jsg, jeg )
00663       global_indices(1) = isg;       global_indices(2) = ieg
00664       global_indices(3) = jsg;       global_indices(4) = jeg
00665 
00666 ! get the number of divisions of domain
00667       call mpp_get_layout(domain_in, layout)
00668       ndivx = layout(1); ndivy = layout(2)
00669       ndivs = ndivx * ndivy
00670       npes = mpp_npes()
00671 
00672       if( ndivs.NE.npes )call mpp_error( 'mpp_domains_mod_oa', &
00673                  'mpp_copy_domains: number of PEs is not consistent with the layout', FATAL )
00674       allocate(pelist(0:npes-1), xsize(0:npes-1), ysize(0:npes-1), &
00675                xbegin(0:npes-1), xend(0:npes-1),                   &
00676                ybegin(0:npes-1), yend(0:npes-1),                   &
00677                xextent(0:ndivx), yextent(0:ndivy))
00678 
00679 ! get the pe list of the input domain
00680       call mpp_get_pelist2D( domain_in, pelist)
00681 
00682 ! get the halo
00683       xhalosz = 0; yhalosz = 0
00684       if(present(xhalo)) xhalosz = xhalo
00685       if(present(yhalo)) yhalosz = yhalo
00686 
00687 ! get the extent
00688       call mpp_get_compute_domains(Domain_in, xbegin, xend, xsize, &
00689                                           ybegin, yend, ysize  )
00690             
00691 !  compute the exact x-axis decomposition
00692       i = isg
00693       m = 0
00694       xextent = 0
00695       do pe = 0, npes-1
00696         if ( xbegin(pe) == i ) then
00697           m = m+1
00698           xextent (m) = xsize (pe)
00699           i = i + xsize(pe)
00700           if ( m == size(xextent) .or. i > ieg ) exit
00701         endif
00702       enddo
00703 
00704 !  compute the exact y-axis decomposition
00705       j = jsg 
00706       n = 0   
00707       yextent = 0
00708       do pe = 0, npes-1
00709         if ( ybegin(pe) == j ) then
00710           n = n+1 
00711           yextent (n) = ysize (pe)
00712           j = j + ysize(pe)
00713           if ( n == size(yextent) .or. j > jeg ) exit
00714         endif   
00715       enddo   
00716 
00717       call mpp_define_domains( global_indices, layout, domain_out, pelist = pelist, &
00718                                xhalo = xhalosz, yhalo = yhalosz, xextent = xextent, & 
00719                                yextent = yextent)
00720 
00721     end subroutine mpp_copy_domains2D
00722 
00723 
00724 
00725 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00726 !                                                                             !
00727 !              MPP_DEFINE_DOMAINS: define layout and decomposition            !
00728 !                                                                             !
00729 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00730 
00731     subroutine mpp_define_domains1D( global_indices, ndivs, domain, pelist, &
00732                                      flags, halo, extent, maskmap,offset)
00733 !routine to divide global array indices among domains, and assign domains to PEs
00734 !domain is of type domain1D
00735 !ARGUMENTS:
00736 !      global_indices(2)=(isg,ieg) gives the extent of global domain
00737 !      ndivs is number of divisions of domain: even divisions unless extent is present.
00738 !      domain is the returned domain1D
00739 !      pelist (optional) list of PEs to which domains are to be assigned (default 0...npes-1)
00740 !                 size of pelist must correspond to number of mask=.TRUE. divisions
00741 !      flags define whether compute and data domains are global (undecomposed) and whether global domain has periodic boundaries
00742 !      halo (optional) defines halo width (currently the same on both sides)
00743 !      extent (optional) array defines width of each division (used for non-uniform domain decomp, for e.g load-balancing)
00744 !      maskmap (optional) a division whose maskmap=.FALSE. is not assigned to any domain
00745 !  By default we assume decomposition of compute and data domains, non-periodic boundaries, no halo, as close to uniform extents
00746 !  as the input parameters permit
00747       integer, intent(in) :: global_indices(2) !(/ isg, ieg /)
00748       integer, intent(in) :: ndivs
00749       type(domain1D), intent(inout) :: domain !declared inout so that existing links, if any, can be nullified
00750       integer, intent(in), optional :: pelist(0:)
00751       integer, intent(in), optional :: flags, halo
00752       integer, intent(in), optional :: extent(0:)
00753       logical, intent(in), optional :: maskmap(0:)
00754       integer, intent(in), optional :: offset(0:)
00755 
00756       logical :: compute_domain_is_global, data_domain_is_global
00757       integer :: ndiv, n, isg, ieg, is, ie, i, off, pos, hs, he
00758       integer, allocatable :: pes(:)
00759       logical, allocatable :: mask(:)
00760 !rv
00761       logical ::blocks
00762       integer :: lastie,il_compute_max_size
00763 !rv
00764       integer :: halosz
00765 !used by symmetry algorithm
00766       integer :: imax, ndmax, ndmirror
00767       logical :: symmetrize
00768 !statement functions
00769       logical :: even, odd
00770       even(n) = (mod(n,2).EQ.0)
00771       odd (n) = (mod(n,2).EQ.1)
00772       
00773       if( .NOT.module_is_initialized )call mpp_error( FATAL, 'MPP_DEFINE_DOMAINS1D: You must first call mpp_domains_init.' )
00774 !get global indices
00775 !RV
00776       is=0
00777       ie=0
00778 !RV
00779       isg = global_indices(1)
00780       ieg = global_indices(2)
00781       if( ndivs.GT.ieg-isg+1 )call mpp_error( WARNING, 'MPP_DEFINE_DOMAINS1D: more divisions requested than rows available.' )
00782 !get the list of PEs on which to assign domains; if pelist is absent use 0..npes-1
00783       if( PRESENT(pelist) )then
00784           if( .NOT.any(pelist.EQ.pe) )then
00785               write( stderr(),* )'pe=', pe, ' pelist=', pelist
00786               call mpp_error( FATAL, 'MPP_DEFINE_DOMAINS1D: pe must be in pelist.' )
00787           end if
00788           allocate( pes(0:size(pelist)-1) )
00789           pes(:) = pelist(:)
00790       else
00791           allocate( pes(0:mpp_npes()-1) )
00792           pes(:) = (/ (i,i=0,mpp_npes()-1) /)
00793       end if
00794 
00795 !rv Block distribution ?
00796       blocks=.false.
00797       if(present(offset)) blocks=.true.
00798       if(blocks) then
00799        if((.not.present(maskmap)).and.(.not.present(extent))) &
00800          call mpp_error(FATAL, 'MPP_DEFINE_DOMAINS1D: you have to define maskmap and extent!')
00801         if(size(offset).ne.ndivs) &
00802           call mpp_error( FATAL, 'MPP_DEFINE_DOMAINS1D: offset array size must equal number of domain divisions.' )
00803       endif
00804 !rv
00805 !get number of real domains: 1 mask domain per PE in pes
00806       allocate( mask(0:ndivs-1) )
00807       mask = .TRUE.                 !default mask
00808       if( PRESENT(maskmap) )then
00809           if( size(maskmap).NE.ndivs ) &
00810                call mpp_error( FATAL, 'MPP_DEFINE_DOMAINS1D: maskmap array size must equal number of domain divisions.' )
00811           mask(:) = maskmap(:)
00812       end if
00813       if( count(mask).NE.size(pes) ) &
00814            call mpp_error( FATAL, 'MPP_DEFINE_DOMAINS1D: number of TRUEs in maskmap array must match PE count.' )
00815         
00816       if( PRESENT(extent) )then
00817           if( size(extent).NE.ndivs ) &
00818                call mpp_error( FATAL, 'MPP_DEFINE_DOMAINS1D: extent array size must equal number of domain divisions.' )
00819       end if
00820 !get halosize
00821       halosz = 0
00822       if( PRESENT(halo) )halosz = halo
00823 
00824 !get flags
00825       compute_domain_is_global = .FALSE.
00826       data_domain_is_global    = .FALSE.
00827       domain%cyclic = .FALSE.
00828       if( PRESENT(flags) )then
00829 !NEW: obsolete flag global_compute_domain, since ndivs is non-optional and you cannot have global compute and ndivs.NE.1 
00830           compute_domain_is_global = ndivs.EQ.1
00831 !if compute domain is global, data domain must also be
00832           data_domain_is_global    = BTEST(flags,GLOBAL) .OR. compute_domain_is_global
00833           domain%cyclic  = BTEST(flags,CYCLIC) .AND. halosz.NE.0
00834       end if
00835 
00836 !set up links list
00837       allocate( domain%list(0:ndivs-1) )
00838 
00839 !set global domain
00840       domain%list(:)%global%begin     = isg
00841       domain%list(:)%global%end       = ieg
00842       domain%list(:)%global%size      = ieg-isg+1
00843       domain%list(:)%global%max_size  = ieg-isg+1
00844       domain%list(:)%global%is_global = .TRUE. !always
00845 
00846 !get compute domain
00847       if( compute_domain_is_global )then
00848           domain%list(:)%compute%begin = isg
00849           domain%list(:)%compute%end   = ieg
00850           domain%list(:)%compute%is_global = .TRUE.
00851           domain%list(:)%pe = pes(:)
00852           domain%pos = 0
00853       else
00854           domain%list(:)%compute%is_global = .FALSE.
00855           is = isg
00856           lastie=-1
00857           n = 0
00858 !RV
00859           il_compute_max_size=0
00860 !RV
00861           do ndiv=0,ndivs-1
00862              if( PRESENT(extent) )then
00863 !rv build the grid by individual block sizes
00864                if(blocks) then
00865                  if(mask(ndiv)) then
00866                    is=isg+offset(ndiv)
00867                    ie = is + extent(ndiv) - 1
00868 !                 print*,'MPP_DEFINE_DOMAINS: ',pe,':',ndiv,blocks,is,ie,ieg,offset
00869                  endif
00870 !                 if( ndiv.EQ.ndivs-1 .AND. ie.NE.ieg ) &
00871 !                      call mpp_error( FATAL, 'MPP_DEFINE_DOMAINS: extent array limits do not match global domain.' )
00872                else
00873                  ie = is + extent(ndiv) - 1
00874                  if( ndiv.EQ.ndivs-1 .AND. ie.NE.ieg ) &
00875                       call mpp_error( FATAL, 'MPP_DEFINE_DOMAINS: extent array limits do not match global domain.' )
00876                endif
00877              else
00878 !modified for mirror-symmetry
00879 !original line
00880 !                 ie = is + CEILING( float(ieg-is+1)/(ndivs-ndiv) ) - 1
00881 
00882 !problem of dividing nx points into n domains maintaining symmetry
00883 !i.e nx=18 n=4 4554 and 5445 are solutions but 4455 is not.
00884 !this will always work for nx even n even or odd
00885 !this will always work for nx odd, n odd
00886 !this will never  work for nx odd, n even: for this case we supersede the mirror calculation
00887 !                 symmetrize = .NOT. ( mod(ndivs,2).EQ.0 .AND. mod(ieg-isg+1,2).EQ.1 )
00888 !nx even n odd fails if n>nx/2
00889                  symmetrize = ( even(ndivs) .AND. even(ieg-isg+1) ) .OR. &
00890                               (  odd(ndivs) .AND.  odd(ieg-isg+1) ) .OR. &
00891                               (  odd(ndivs) .AND. even(ieg-isg+1) .AND. ndivs.LT.(ieg-isg+1)/2 )
00892 
00893 !mirror domains are stored in the list and retrieved if required.
00894                  if( ndiv.EQ.0 )then
00895 !initialize max points and max domains
00896                      imax = ieg
00897                      ndmax = ndivs
00898                  end if
00899 !do bottom half of decomposition, going over the midpoint for odd ndivs
00900                  if( ndiv.LT.(ndivs-1)/2+1 )then
00901 !domain is sized by dividing remaining points by remaining domains
00902                      ie = is + CEILING( REAL(imax-is+1)/(ndmax-ndiv) ) - 1
00903                      ndmirror = (ndivs-1) - ndiv !mirror domain
00904                      if( ndmirror.GT.ndiv .AND. symmetrize )then !only for domains over the midpoint
00905 !mirror extents, the max(,) is to eliminate overlaps
00906                          domain%list(ndmirror)%compute%begin = max( isg+ieg-ie, ie+1 )
00907                          domain%list(ndmirror)%compute%end   = max( isg+ieg-is, ie+1 )
00908                          imax = domain%list(ndmirror)%compute%begin - 1
00909                          ndmax = ndmax - 1
00910                      end if
00911                  else
00912                      if( symmetrize )then
00913 !do top half of decomposition by retrieving saved values
00914                          is = domain%list(ndiv)%compute%begin
00915                          ie = domain%list(ndiv)%compute%end
00916                      else
00917                          ie = is + CEILING( REAL(imax-is+1)/(ndmax-ndiv) ) - 1
00918                      end if
00919                  end if
00920              end if
00921              if(blocks) then
00922                if(mask(ndiv))then
00923                  if( ie.LT.is )call mpp_error( FATAL, 'MPP_DEFINE_DOMAINS: domain extents must be positive definite.' )
00924                  domain%list(ndiv)%compute%begin = is
00925                  domain%list(ndiv)%compute%end   = ie
00926 !                 if(lastie.gt.0.and.is.ne.lastie+1) &
00927 !                   call mpp_error( FATAL, 'MPP_DEFINE_DOMAINS: block extents do not span space completely.' )
00928                  lastie=ie
00929                  domain%list(ndiv)%pe = pes(n)
00930                  if( pe.EQ.pes(n) )domain%pos = ndiv
00931                  n = n + 1
00932                  is = ie + 1
00933                else
00934 !rv for Arnaud
00935                  domain%list(ndiv)%compute%begin = 0
00936                  domain%list(ndiv)%compute%end   = 0
00937                endif
00938                if(ndiv.eq.ndivs-1.and.lastie.gt.ieg) &
00939                    call mpp_error( FATAL, 'MPP_DEFINE_DOMAINS: block extents exceed max. space.' )
00940              else
00941              if( ie.LT.is )call mpp_error( FATAL, 'MPP_DEFINE_DOMAINS: domain extents must be positive definite.' )
00942              domain%list(ndiv)%compute%begin = is
00943              domain%list(ndiv)%compute%end   = ie
00944 !rr 2005-07-20, Luis Kornblueh, MPIMet
00945              if( ndiv.GT.0 ) THEN
00946                if( is.NE.domain%list(ndiv-1)%compute%end+1 ) &
00947                     call mpp_error( FATAL, 'MPP_DEFINE_DOMAINS: domain extents do not span space completely.' )
00948              end if
00949              if( ndiv.EQ.ndivs-1 .AND. domain%list(ndiv)%compute%end.NE.ieg ) &
00950                   call mpp_error( FATAL, 'MPP_DEFINE_DOMAINS: domain extents do not span space completely.' )
00951              if( mask(ndiv) )then
00952                  domain%list(ndiv)%pe = pes(n)
00953                  if( pe.EQ.pes(n) )domain%pos = ndiv
00954                  n = n + 1
00955              end if
00956              is = ie + 1
00957              endif
00958           end do
00959       end if
00960           
00961       domain%list(:)%compute%size  = domain%list(:)%compute%end - domain%list(:)%compute%begin + 1
00962 !get data domain
00963 !data domain is at least equal to compute domain
00964       domain%list(:)%data%begin = domain%list(:)%compute%begin
00965       domain%list(:)%data%end   = domain%list(:)%compute%end
00966       domain%list(:)%data%is_global = .FALSE.
00967 !apply global flags
00968       if( data_domain_is_global )then
00969           domain%list(:)%data%begin  = isg
00970           domain%list(:)%data%end    = ieg
00971           domain%list(:)%data%is_global = .TRUE.
00972       end if
00973 !apply margins
00974       domain%list(:)%data%begin = domain%list(:)%data%begin - halosz
00975       domain%list(:)%data%end   = domain%list(:)%data%end   + halosz  
00976       domain%list(:)%data%size  = domain%list(:)%data%end - domain%list(:)%data%begin + 1
00977 
00978 !      domain = domain%list(pos) !load domain from domain%list(pos)
00979       domain%compute = domain%list(domain%pos)%compute
00980       domain%data = domain%list(domain%pos)%data
00981       domain%global = domain%list(domain%pos)%global
00982       domain%compute%max_size = MAXVAL( domain%list(:)%compute%size )
00983 !RV
00984       if(blocks) then
00985        call mpp_max(domain%compute%max_size)
00986       endif
00987 !RV
00988       domain%data%max_size    = MAXVAL( domain%list(:)%data%size )
00989       domain%global%max_size  = domain%global%size
00990 
00991 !PV786667: the deallocate stmts can be removed when fixed (7.3.1.3m)
00992       deallocate( pes, mask )
00993       return
00994 
00995       contains
00996 
00997         function if_overlap( hs, he, cs, ce, os, oe )
00998 !function to look if a portion of the halo [hs,he] lies with in the compute region [cs,ce]
00999 !if yes, if_overlap returns true, and the overlap region is returned in [os,oe]
01000           logical :: if_overlap
01001           integer, intent(in) :: hs, he, cs, ce
01002           integer, intent(out) :: os, oe
01003           os = max(hs,cs)
01004           oe = min(he,ce)
01005           if( debug )write( stderr(),'(a,7i4)' ) &
01006                'MPP_DEFINE_DOMAINS1D: pe, hs, he, cs, ce, os, oe=', pe, hs, he, cs, ce, os, oe
01007           if_overlap = oe.GE.os
01008           return
01009         end function if_overlap
01010           
01011     end subroutine mpp_define_domains1D
01012 
01013     subroutine mpp_define_domains2D( global_indices, layout, domain, pelist, &
01014                                                      xflags, yflags, &
01015                                      xhalo, yhalo, xextent, yextent, maskmap,offsetx,offsety, name )
01016 !define 2D data and computational domain on global rectilinear cartesian domain (isg:ieg,jsg:jeg) and assign them to PEs
01017       integer, intent(in) :: global_indices(4) !(/ isg, ieg, jsg, jeg /)
01018       integer, intent(in) :: layout(2)
01019       type(domain2D), intent(inout) :: domain
01020       integer, intent(in), optional :: pelist(0:)
01021       integer, intent(in), optional :: xflags, yflags, xhalo, yhalo
01022       integer, intent(in), optional :: xextent(0:), yextent(0:)
01023       logical, intent(in), optional :: maskmap(0:,0:)
01024       integer, intent(in), optional :: offsetx(0:), offsety(0:)
01025       character(len=*), intent(in), optional :: name
01026       integer :: i, j, m, n
01027       integer :: ipos, jpos, pos
01028       integer :: ndivx, ndivy, isg, ieg, jsg, jeg, isd, ied, jsd, jed
01029       
01030       logical, allocatable :: mask(:,:)
01031 !rv
01032       logical :: blocks
01033 !rv
01034       integer, allocatable :: pes(:), pearray(:,:)
01035       character(len=8) :: text
01036 
01037       if( .NOT.module_is_initialized )call mpp_error( FATAL, 'MPP_DEFINE_DOMAINS2D: You must first call mpp_domains_init.' )
01038       ndivx = layout(1); ndivy = layout(2)
01039       isg = global_indices(1); ieg = global_indices(2); jsg = global_indices(3); jeg = global_indices(4)
01040 
01041       if( PRESENT(pelist) )then
01042           allocate( pes(0:size(pelist)-1) )
01043           pes = pelist
01044       else
01045           allocate( pes(0:mpp_npes()-1) )
01046           call mpp_get_current_pelist(pes)
01047 !          pes = (/ (i,i=0,mpp_npes()-1) /)
01048       end if
01049 !rv Block distribution ?
01050       blocks=.false.
01051       if(present(offsetx).and.present(offsety)) blocks=.true.
01052       if(present(offsetx).and.(.not.present(offsety))) then
01053          call mpp_error(FATAL,'MPP_DEFINE_DOMAINS1D: you have to define offsetx AND offsety!')
01054       endif
01055       if((.not.present(offsetx)).and.present(offsety)) then
01056          call mpp_error(FATAL,'MPP_DEFINE_DOMAINS1D: you have to define offsetx AND offsety!')
01057       endif
01058       if(blocks) then
01059        if((.not.present(maskmap)).and.(.not.present(xextent))) &
01060          call mpp_error(FATAL, 'MPP_DEFINE_DOMAINS1D: you have to define maskmap and xextent!')
01061        if((.not.present(maskmap)).and.(.not.present(yextent))) &
01062          call mpp_error(FATAL, 'MPP_DEFINE_DOMAINS1D: you have to define maskmap and yextent!')
01063        if(size(offsetx).ne.ndivx) &
01064          call mpp_error(FATAL,'MPP_DEFINE_DOMAINS2D: offsetx array does not match layout!')
01065        if(size(offsety).ne.ndivy) &
01066          call mpp_error(FATAL,'MPP_DEFINE_DOMAINS2D: offsety array does not match layout!')
01067       endif
01068 !rv
01069 
01070       allocate( mask(0:ndivx-1,0:ndivy-1) )
01071       mask = .TRUE.
01072       if( PRESENT(maskmap) )then
01073           if( size(maskmap,1).NE.ndivx .OR. size(maskmap,2).NE.ndivy ) &
01074                call mpp_error( FATAL, 'MPP_DEFINE_DOMAINS2D: maskmap array does not match layout.' )
01075           mask(:,:) = maskmap(:,:)
01076       end if
01077 !number of unmask domains in layout must equal number of PEs assigned
01078       n = count(mask)
01079       if( n.NE.size(pes) )then
01080           write( text,'(i8)' )n
01081           call mpp_error( FATAL, 'MPP_DEFINE_DOMAINS2D: incorrect number of PEs assigned for this layout and maskmap. Use ' &
01082                //text//' PEs for this domain decomposition.' )
01083       end if
01084 
01085 !place on PE array; need flag to assign them to j first and then i
01086       allocate( pearray(0:ndivx-1,0:ndivy-1) )
01087       pearray(:,:) = NULL_PE
01088       ipos = NULL_PE; jpos = NULL_PE; pos = NULL_PE
01089       n = 0
01090       do j = 0,ndivy-1
01091          do i = 0,ndivx-1
01092             if( mask(i,j) )then
01093                 pearray(i,j) = pes(n)
01094                 if( pes(n).EQ.pe )then
01095                     pos = n
01096                     ipos = i
01097                     jpos = j
01098                 end if
01099                 n = n + 1
01100             end if
01101          end do
01102       end do
01103       if( ipos.EQ.NULL_PE .OR. jpos.EQ.NULL_PE .or. pos.EQ.NULL_PE ) &
01104            call mpp_error( FATAL, 'MPP_DEFINE_DOMAINS2D: pelist must include this PE.' )
01105       if( debug )write( stderr(), * )'pe, ipos, jpos=', pe, ipos, jpos, ' pearray(:,jpos)=', pearray(:,jpos), &
01106                                                                         ' pearray(ipos,:)=', pearray(ipos,:)
01107       
01108       if(blocks) then
01109 !do domain decomposition using 1D versions in X and Y
01110       call mpp_define_domains( global_indices(1:2), ndivx, domain%x, &
01111            pack(pearray(:,jpos),mask(:,jpos)), xflags, xhalo, xextent, mask(:,jpos),offset=offsetx )
01112       call mpp_define_domains( global_indices(3:4), ndivy, domain%y, &
01113            pack(pearray(ipos,:),mask(ipos,:)), yflags, yhalo, yextent, mask(ipos,:),offset=offsety )
01114       else
01115 !do domain decomposition using 1D versions in X and Y
01116       call mpp_define_domains( global_indices(1:2), ndivx, domain%x, &
01117            pack(pearray(:,jpos),mask(:,jpos)), xflags, xhalo, xextent, mask(:,jpos))
01118       call mpp_define_domains( global_indices(3:4), ndivy, domain%y, &
01119            pack(pearray(ipos,:),mask(ipos,:)), yflags, yhalo, yextent, mask(ipos,:))
01120       endif
01121       if( domain%x%list(domain%x%pos)%pe.NE.domain%y%list(domain%y%pos)%pe ) &
01122            call mpp_error( FATAL, 'MPP_DEFINE_DOMAINS2D: domain%x%list(ipos)%pe.NE.domain%y%list(jpos)%pe.' ) 
01123       domain%pos = pos
01124       domain%pe  = pe
01125 
01126 !set up fold
01127       domain%fold = 0
01128       if( PRESENT(xflags) )then
01129           if( BTEST(xflags,WEST) )domain%fold = domain%fold + FOLD_WEST_EDGE
01130           if( BTEST(xflags,EAST) )domain%fold = domain%fold + FOLD_EAST_EDGE
01131       end if
01132       if( PRESENT(yflags) )then
01133           if( BTEST(yflags,SOUTH) )domain%fold = domain%fold + FOLD_SOUTH_EDGE
01134           if( BTEST(yflags,NORTH) )domain%fold = domain%fold + FOLD_NORTH_EDGE
01135       end if
01136           
01137       if( BTEST(domain%fold,SOUTH) .OR. BTEST(domain%fold,NORTH) )then
01138           if( domain%y%cyclic )call mpp_error( FATAL, 'MPP_DEFINE_DOMAINS: an axis cannot be both folded and cyclic.' )
01139           if( modulo(domain%x%global%size,2).NE.0 ) &
01140                call mpp_error( FATAL, 'MPP_DEFINE_DOMAINS: number of points in X must be even when there is a fold in Y.' )
01141 !check if folded domain boundaries line up in X: compute domains lining up is a sufficient condition for symmetry
01142           n = ndivx - 1
01143           do i = 0,n/2
01144              if( domain%x%list(i)%compute%size.NE.domain%x%list(n-i)%compute%size ) &
01145                   call mpp_error( FATAL, 'MPP_DEFINE_DOMAINS: Folded domain boundaries must line up (mirror-symmetric extents).' )
01146           end do
01147       end if
01148       if( BTEST(domain%fold,WEST) .OR. BTEST(domain%fold,EAST) )then
01149           if( domain%x%cyclic )call mpp_error( FATAL, 'MPP_DEFINE_DOMAINS: an axis cannot be both folded and cyclic.' )
01150           if( modulo(domain%y%global%size,2).NE.0 ) &
01151                call mpp_error( FATAL, 'MPP_DEFINE_DOMAINS: number of points in Y must be even when there is a fold in X.' )
01152 !check if folded domain boundaries line up in Y: compute domains lining up is a sufficient condition for symmetry
01153           n = ndivy - 1
01154           do i = 0,n/2
01155              if( domain%y%list(i)%compute%size.NE.domain%y%list(n-i)%compute%size ) &
01156                   call mpp_error( FATAL, 'MPP_DEFINE_DOMAINS: Folded domain boundaries must line up (mirror-symmetric extents).' )
01157           end do
01158       end if
01159 
01160 !set up domain%list
01161       if( debug )write( stderr(),'(a,9i4)' )'pe, domain=', pe, domain_info_buf(1:8)
01162       if( pe.EQ.mpp_root_pe() .AND. PRESENT(name) )then
01163           write( stdout(), '(/a,i3,a,i3)' )trim(name)//' domain decomposition: ', ndivx, ' X', ndivy
01164           write( stdout(), '(3x,a)' )'pe,   is,  ie,  js,  je,    isd, ied, jsd, jed'
01165       end if
01166       call mpp_sync()
01167       call mpp_get_compute_domain( domain, domain_info_buf(1), domain_info_buf(2), domain_info_buf(3), domain_info_buf(4) )
01168       call mpp_get_data_domain   ( domain, domain_info_buf(5), domain_info_buf(6), domain_info_buf(7), domain_info_buf(8) )
01169       n = size(pes)
01170       allocate( domain%list(0:n-1) ) !this is only used for storage of remote compute and data domain info
01171       do i = 0,n-1
01172          m = mod(pos+i,n)
01173          domain%list(m)%pe = pes(m)
01174          call mpp_transmit( domain_info_buf(1:8), 8, pes(mod(pos+n-i,n)), domain_info_buf(9:16), 8, pes(m) )
01175          domain%list(m)%x%compute%begin = domain_info_buf(9)
01176          domain%list(m)%x%compute%end   = domain_info_buf(10)
01177          domain%list(m)%y%compute%begin = domain_info_buf(11)
01178          domain%list(m)%y%compute%end   = domain_info_buf(12)
01179          domain%list(m)%x%data%begin = domain_info_buf(13)
01180          domain%list(m)%x%data%end   = domain_info_buf(14)
01181          domain%list(m)%y%data%begin = domain_info_buf(15)
01182          domain%list(m)%y%data%end   = domain_info_buf(16)
01183          if( pe.EQ.mpp_root_pe() .AND. PRESENT(name) )write( stdout(), '(2x,i3,1x,4i5,3x,4i5)' )pes(m), domain_info_buf(9:)
01184       end do
01185       call mpp_sync_self(pes)
01186       domain%list(:)%x%compute%size = domain%list(:)%x%compute%end - domain%list(:)%x%compute%begin + 1
01187       domain%list(:)%y%compute%size = domain%list(:)%y%compute%end - domain%list(:)%y%compute%begin + 1
01188       domain%list(:)%x%data%size = domain%list(:)%x%data%end - domain%list(:)%x%data%begin + 1
01189       domain%list(:)%y%data%size = domain%list(:)%y%data%end - domain%list(:)%y%data%begin + 1
01190 
01191       domain%remote_domains_initialized = .FALSE.
01192       domain%remote_off_domains_initialized = .FALSE.
01193       call compute_overlaps(domain)
01194 !PV786667: the deallocate stmts can be removed when fixed (7.3.1.3m)
01195       deallocate( pes, mask, pearray )
01196           
01197       return
01198     end subroutine mpp_define_domains2D
01199 
01200     subroutine mpp_broadcast_domain( domain )
01201 !broadcast domain (useful only outside the context of its own pelist)
01202       type(domain2D), intent(inout) :: domain
01203       integer, allocatable :: pes(:)
01204       logical :: native         !true if I'm on the pelist of this domain
01205       integer :: listsize, listpos
01206       integer :: n
01207       integer, dimension(5) :: msg, info         !pe and compute domain of each item in list
01208 
01209       if( .NOT.module_is_initialized )call mpp_error( FATAL, 'MPP_BROADCAST_DOMAIN: You must first call mpp_domains_init.' )
01210 
01211 !get the current pelist
01212       allocate( pes(0:mpp_npes()-1) )
01213       call mpp_get_current_pelist(pes)
01214 
01215 !am I part of this domain?
01216       native = ASSOCIATED(domain%list)
01217 
01218 !set local list size
01219       if( native )then
01220           listsize = size(domain%list)
01221       else
01222           listsize = 0
01223       end if
01224       call mpp_max(listsize)
01225 
01226       if( .NOT.native )then
01227 !initialize domain%list and set null values in message
01228           allocate( domain%list(0:listsize-1) )
01229           domain%pe = NULL_PE
01230           domain%pos = -1
01231           domain%x%compute%begin =  HUGE(1)
01232           domain%x%compute%end   = -HUGE(1)
01233           domain%y%compute%begin =  HUGE(1)
01234           domain%y%compute%end   = -HUGE(1)
01235       end if
01236 !initialize values in info
01237       info(1) = domain%pe
01238       call mpp_get_compute_domain( domain, info(2), info(3), info(4), info(5) )
01239 
01240 !broadcast your info across current pelist and unpack if needed
01241       listpos = 0
01242       do n = 0,mpp_npes()-1
01243          msg = info
01244          if( pe.EQ.pes(n) .AND. debug )write( stderr(),* )'PE ', pe, 'broadcasting msg ', msg
01245          call mpp_broadcast( msg, 5, pes(n) )
01246 !no need to unpack message if native
01247 !no need to unpack message from non-native PE
01248          if( .NOT.native .AND. msg(1).NE.NULL_PE )then
01249              domain%list(listpos)%pe = msg(1)
01250              domain%list(listpos)%x%compute%begin = msg(2)
01251              domain%list(listpos)%x%compute%end   = msg(3)
01252              domain%list(listpos)%y%compute%begin = msg(4)
01253              domain%list(listpos)%y%compute%end   = msg(5)
01254              listpos = listpos + 1
01255              if( debug )write( stderr(),* )'PE ', pe, 'received domain from PE ', msg(1), 'is,ie,js,je=', msg(2:5)
01256          end if
01257       end do
01258     end subroutine mpp_broadcast_domain
01259 
01260     subroutine compute_overlaps( domain )
01261 !computes remote domain overlaps
01262 !assumes only one in each direction
01263       type(domain2D), intent(inout) :: domain
01264       integer :: i, j, k, m, n
01265       integer :: is, ie, js, je, isc, iec, jsc, jec, isd, ied, jsd, jed, isg, ieg, jsg, jeg, ioff, joff
01266       integer :: list
01267 
01268       if( grid_offset_type.EQ.AGRID .AND. domain%remote_domains_initialized     )return
01269       if( grid_offset_type.NE.AGRID .AND. domain%remote_off_domains_initialized )return
01270       domain%gridtype = grid_offset_type
01271       n = size(domain%list)
01272 !send
01273       call mpp_get_compute_domain( domain, isc, iec, jsc, jec )
01274       call mpp_get_global_domain ( domain, isg, ieg, jsg, jeg, xsize=ioff, ysize=joff ) !cyclic offsets
01275       domain%list(:)%overlap = .FALSE.
01276       do list = 0,n-1
01277          m = mod( domain%pos+list, n )
01278 !to_pe's eastern halo
01279          is = domain%list(m)%x%compute%end+1; ie = domain%list(m)%x%data%end
01280          js = domain%list(m)%y%compute%begin; je = domain%list(m)%y%compute%end
01281          if( is.GT.ieg )then
01282              if( domain%x%cyclic )then !try cyclic offset
01283                  is = is-ioff; ie = ie-ioff
01284              else if( BTEST(domain%fold,EAST) )then
01285                  i=is; is = 2*ieg-ie+1; ie = 2*ieg-i+1
01286                  j=js; js = jsg+jeg-je; je = jsg+jeg-j
01287                  if( BTEST(grid_offset_type,EAST) )then
01288                      is = is - 1; ie = ie - 1
01289                  end if
01290              end if
01291          end if
01292          is = max(is,isc); ie = min(ie,iec)
01293          js = max(js,jsc); je = min(je,jec)
01294          if( ie.GE.is .AND. je.GE.js )then
01295              domain%list(m)%overlap = .TRUE.
01296              if( grid_offset_type.NE.AGRID )then
01297                  domain%list(m)%send_w_off%overlap = .TRUE.
01298                  domain%list(m)%send_w_off%is = is
01299                  domain%list(m)%send_w_off%ie = ie
01300                  domain%list(m)%send_w_off%js = js
01301                  domain%list(m)%send_w_off%je = je
01302              else
01303                  domain%list(m)%send_w%overlap = .TRUE.
01304                  domain%list(m)%send_w%is = is
01305                  domain%list(m)%send_w%ie = ie
01306                  domain%list(m)%send_w%js = js
01307                  domain%list(m)%send_w%je = je
01308              end if
01309          else
01310              domain%list(m)%send_w%overlap = .FALSE.
01311              domain%list(m)%send_w_off%overlap = .FALSE.
01312          end if
01313 !to_pe's SE halo
01314          is = domain%list(m)%x%compute%end+1; ie = domain%list(m)%x%data%end
01315          js = domain%list(m)%y%data%begin; je = domain%list(m)%y%compute%begin-1
01316          if( is.GT.ieg )then
01317              if( domain%x%cyclic )then !try cyclic offset
01318                  is = is-ioff; ie = ie-ioff
01319              else if( BTEST(domain%fold,EAST) )then
01320                  i=is; is = 2*ieg-ie+1; ie = 2*ieg-i+1
01321                  j=js; js = jsg+jeg-je; je = jsg+jeg-j
01322                  if( BTEST(grid_offset_type,EAST) )then
01323                      is = is - 1; ie = ie - 1
01324                  end if
01325              end if
01326          end if
01327          if( jsg.GT.je )then
01328              if( domain%y%cyclic )then !try cyclic offset
01329                  js = js+joff; je = je+joff
01330              else if( BTEST(domain%fold,SOUTH) )then
01331                  i=is; is = isg+ieg-ie; ie = isg+ieg-i
01332                  j=js; js = 2*jsg-je-1; je = 2*jsg-j-1
01333                  if( BTEST(grid_offset_type,SOUTH) )then
01334                      js = js + 1; je = je + 1
01335                  end if
01336              end if
01337          end if
01338          is = max(is,isc); ie = min(ie,iec)
01339          js = max(js,jsc); je = min(je,jec)
01340          if( ie.GE.is .AND. je.GE.js )then
01341              domain%list(m)%overlap = .TRUE.
01342              if( grid_offset_type.NE.AGRID )then
01343                  domain%list(m)%send_nw_off%overlap = .TRUE.
01344                  domain%list(m)%send_nw_off%is = is
01345                  domain%list(m)%send_nw_off%ie = ie
01346                  domain%list(m)%send_nw_off%js = js
01347                  domain%list(m)%send_nw_off%je = je
01348              else
01349                  domain%list(m)%send_nw%overlap = .TRUE.
01350                  domain%list(m)%send_nw%is = is
01351                  domain%list(m)%send_nw%ie = ie
01352                  domain%list(m)%send_nw%js = js
01353                  domain%list(m)%send_nw%je = je
01354              end if
01355          else
01356              domain%list(m)%send_nw%overlap = .FALSE.
01357              domain%list(m)%send_nw_off%overlap = .FALSE.
01358          end if
01359 !to_pe's southern halo
01360          is = domain%list(m)%x%compute%begin; ie = domain%list(m)%x%compute%end
01361          js = domain%list(m)%y%data%begin; je = domain%list(m)%y%compute%begin-1
01362          if( jsg.GT.je )then
01363              if( domain%y%cyclic )then !try cyclic offset
01364                  js = js+joff; je = je+joff
01365              else if( BTEST(domain%fold,SOUTH) )then
01366                  i=is; is = isg+ieg-ie; ie = isg+ieg-i
01367                  j=js; js = 2*jsg-je-1; je = 2*jsg-j-1
01368                  if( BTEST(grid_offset_type,SOUTH) )then
01369                      js = js + 1; je = je + 1
01370                  end if
01371              end if
01372          end if
01373          is = max(is,isc); ie = min(ie,iec)
01374          js = max(js,jsc); je = min(je,jec)
01375          if( ie.GE.is .AND. je.GE.js )then
01376              domain%list(m)%overlap = .TRUE.
01377              if( grid_offset_type.NE.AGRID )then
01378                  domain%list(m)%send_n_off%overlap = .TRUE.
01379                  domain%list(m)%send_n_off%is = is
01380                  domain%list(m)%send_n_off%ie = ie
01381                  domain%list(m)%send_n_off%js = js
01382                  domain%list(m)%send_n_off%je = je
01383              else
01384                  domain%list(m)%send_n%overlap = .TRUE.
01385                  domain%list(m)%send_n%is = is
01386                  domain%list(m)%send_n%ie = ie
01387                  domain%list(m)%send_n%js = js
01388                  domain%list(m)%send_n%je = je
01389              end if
01390          else
01391              domain%list(m)%send_n%overlap = .FALSE.
01392              domain%list(m)%send_n_off%overlap = .FALSE.
01393          end if
01394 !to_pe's SW halo
01395          is = domain%list(m)%x%data%begin; ie = domain%list(m)%x%compute%begin-1
01396          js = domain%list(m)%y%data%begin; je = domain%list(m)%y%compute%begin-1
01397          if( isg.GT.ie )then
01398              if( domain%x%cyclic )then !try cyclic offset
01399                  is = is+ioff; ie = ie+ioff
01400              else if( BTEST(domain%fold,WEST) )then
01401                  i=is; is = 2*isg-ie-1; ie = 2*isg-i-1
01402                  j=js; js = jsg+jeg-je; je = jsg+jeg-j
01403                  if( BTEST(grid_offset_type,WEST) )then
01404                      is = is + 1; ie = ie + 1
01405                  end if
01406              end if
01407          end if
01408          if( jsg.GT.je )then
01409              if( domain%y%cyclic )then !try cyclic offset
01410                  js = js+joff; je = je+joff
01411              else if( BTEST(domain%fold,SOUTH) )then
01412                  i=is; is = isg+ieg-ie; ie = isg+ieg-i
01413                  j=js; js = 2*jsg-je-1; je = 2*jsg-j-1
01414                  if( BTEST(grid_offset_type,SOUTH) )then
01415                      js = js + 1; je = je + 1
01416                  end if
01417              end if
01418          end if
01419          is = max(is,isc); ie = min(ie,iec)
01420          js = max(js,jsc); je = min(je,jec)
01421          if( ie.GE.is .AND. je.GE.js )then
01422              domain%list(m)%overlap = .TRUE.
01423              if( grid_offset_type.NE.AGRID )then
01424                  domain%list(m)%send_ne_off%overlap = .TRUE.
01425                  domain%list(m)%send_ne_off%is = is
01426                  domain%list(m)%send_ne_off%ie = ie
01427                  domain%list(m)%send_ne_off%js = js
01428                  domain%list(m)%send_ne_off%je = je
01429              else
01430                  domain%list(m)%send_ne%overlap = .TRUE.
01431                  domain%list(m)%send_ne%is = is
01432                  domain%list(m)%send_ne%ie = ie
01433                  domain%list(m)%send_ne%js = js
01434                  domain%list(m)%send_ne%je = je
01435              end if
01436          else
01437              domain%list(m)%send_ne%overlap = .FALSE.
01438              domain%list(m)%send_ne_off%overlap = .FALSE.
01439          end if
01440 !to_pe's western halo
01441          is = domain%list(m)%x%data%begin; ie = domain%list(m)%x%compute%begin-1
01442          js = domain%list(m)%y%compute%begin; je = domain%list(m)%y%compute%end
01443          if( isg.GT.ie )then
01444              if( domain%x%cyclic )then !try cyclic offset
01445                  is = is+ioff; ie = ie+ioff
01446              else if( BTEST(domain%fold,WEST) )then
01447                  i=is; is = 2*isg-ie-1; ie = 2*isg-i-1
01448                  j=js; js = jsg+jeg-je; je = jsg+jeg-j
01449                  if( BTEST(grid_offset_type,WEST) )then
01450                      is = is + 1; ie = ie + 1
01451                  end if
01452              end if
01453          end if
01454          is = max(is,isc); ie = min(ie,iec)
01455          js = max(js,jsc); je = min(je,jec)
01456          if( ie.GE.is .AND. je.GE.js )then
01457              domain%list(m)%overlap = .TRUE.
01458              if( grid_offset_type.NE.AGRID )then
01459                  domain%list(m)%send_e_off%overlap = .TRUE.
01460                  domain%list(m)%send_e_off%is = is
01461                  domain%list(m)%send_e_off%ie = ie
01462                  domain%list(m)%send_e_off%js = js
01463                  domain%list(m)%send_e_off%je = je
01464              else
01465                  domain%list(m)%send_e%overlap = .TRUE.
01466                  domain%list(m)%send_e%is = is
01467                  domain%list(m)%send_e%ie = ie
01468                  domain%list(m)%send_e%js = js
01469                  domain%list(m)%send_e%je = je
01470              end if
01471          else
01472              domain%list(m)%send_e%overlap = .FALSE.
01473              domain%list(m)%send_e_off%overlap = .FALSE.
01474          end if
01475 !to_pe's NW halo
01476          is = domain%list(m)%x%data%begin; ie = domain%list(m)%x%compute%begin-1
01477          js = domain%list(m)%y%compute%end+1; je = domain%list(m)%y%data%end
01478          if( isg.GT.ie )then
01479              if( domain%x%cyclic )then !try cyclic offset
01480                  is = is+ioff; ie = ie+ioff
01481              else if( BTEST(domain%fold,WEST) )then
01482                  i=is; is = 2*isg-ie-1; ie = 2*isg-i-1
01483                  j=js; js = jsg+jeg-je; je = jsg+jeg-j
01484                  if( BTEST(grid_offset_type,WEST) )then
01485                      is = is + 1; ie = ie + 1
01486                  end if
01487              end if
01488          end if
01489          if( js.GT.jeg )then
01490              if( domain%y%cyclic )then !try cyclic offset
01491                  js = js-joff; je = je-joff
01492              else if( BTEST(domain%fold,NORTH) )then
01493                  i=is; is = isg+ieg-ie; ie = isg+ieg-i
01494                  j=js; js = 2*jeg-je+1; je = 2*jeg-j+1
01495                  if( BTEST(grid_offset_type,NORTH) )then
01496                      js = js - 1; je = je - 1
01497                  end if
01498              end if
01499          end if
01500          is = max(is,isc); ie = min(ie,iec)
01501          js = max(js,jsc); je = min(je,jec)
01502          if( ie.GE.is .AND. je.GE.js )then
01503              domain%list(m)%overlap = .TRUE.
01504              if( grid_offset_type.NE.AGRID )then
01505                  domain%list(m)%send_se_off%overlap = .TRUE.
01506                  domain%list(m)%send_se_off%is = is
01507                  domain%list(m)%send_se_off%ie = ie
01508                  domain%list(m)%send_se_off%js = js
01509                  domain%list(m)%send_se_off%je = je
01510              else
01511                  domain%list(m)%send_se%overlap = .TRUE.
01512                  domain%list(m)%send_se%is = is
01513                  domain%list(m)%send_se%ie = ie
01514                  domain%list(m)%send_se%js = js
01515                  domain%list(m)%send_se%je = je
01516              end if
01517          else
01518              domain%list(m)%send_se%overlap = .FALSE.
01519              domain%list(m)%send_se_off%overlap = .FALSE.
01520          end if
01521 !to_pe's northern halo
01522          is = domain%list(m)%x%compute%begin; ie = domain%list(m)%x%compute%end
01523          js = domain%list(m)%y%compute%end+1; je = domain%list(m)%y%data%end
01524          if( js.GT.jeg )then
01525              if( domain%y%cyclic )then !try cyclic offset
01526                  js = js-joff; je = je-joff
01527              else if( BTEST(domain%fold,NORTH) )then
01528                  i=is; is = isg+ieg-ie; ie = isg+ieg-i
01529                  j=js; js = 2*jeg-je+1; je = 2*jeg-j+1
01530                  if( BTEST(grid_offset_type,NORTH) )then
01531                      js = js - 1; je = je - 1
01532                  end if
01533              end if
01534          end if
01535          is = max(is,isc); ie = min(ie,iec)
01536          js = max(js,jsc); je = min(je,jec)
01537          if( ie.GE.is .AND. je.GE.js )then
01538              domain%list(m)%overlap = .TRUE.
01539              if( grid_offset_type.NE.AGRID )then
01540                  domain%list(m)%send_s_off%overlap = .TRUE.
01541                  domain%list(m)%send_s_off%is = is
01542                  domain%list(m)%send_s_off%ie = ie
01543                  domain%list(m)%send_s_off%js = js
01544                  domain%list(m)%send_s_off%je = je
01545              else
01546                  domain%list(m)%send_s%overlap = .TRUE.
01547                  domain%list(m)%send_s%is = is
01548                  domain%list(m)%send_s%ie = ie
01549                  domain%list(m)%send_s%js = js
01550                  domain%list(m)%send_s%je = je
01551              end if
01552          else
01553              domain%list(m)%send_s%overlap = .FALSE.
01554              domain%list(m)%send_s_off%overlap = .FALSE.
01555          end if
01556 !to_pe's NE halo
01557          is = domain%list(m)%x%compute%end+1; ie = domain%list(m)%x%data%end
01558          js = domain%list(m)%y%compute%end+1; je = domain%list(m)%y%data%end
01559          if( is.GT.ieg )then
01560              if( domain%x%cyclic )then !try cyclic offset
01561                  is = is-ioff; ie = ie-ioff
01562              else if( BTEST(domain%fold,EAST) )then
01563                  i=is; is = 2*ieg-ie+1; ie = 2*ieg-i+1
01564                  j=js; js = jsg+jeg-je; je = jsg+jeg-j
01565              end if
01566          end if
01567          if( js.GT.jeg )then
01568              if( domain%y%cyclic )then !try cyclic offset
01569                  js = js-joff; je = je-joff
01570              else if( BTEST(domain%fold,NORTH) )then
01571                  i=is; is = isg+ieg-ie; ie = isg+ieg-i
01572                  j=js; js = 2*jeg-je+1; je = 2*jeg-j+1
01573                  if( BTEST(grid_offset_type,NORTH) )then
01574                      js = js - 1; je = je - 1
01575                  end if
01576              end if
01577          end if
01578          is = max(is,isc); ie = min(ie,iec)
01579          js = max(js,jsc); je = min(je,jec)
01580          if( ie.GE.is .AND. je.GE.js )then
01581              domain%list(m)%overlap = .TRUE.
01582              if( grid_offset_type.NE.AGRID )then
01583                  domain%list(m)%send_sw_off%overlap = .TRUE.
01584                  domain%list(m)%send_sw_off%is = is
01585                  domain%list(m)%send_sw_off%ie = ie
01586                  domain%list(m)%send_sw_off%js = js
01587                  domain%list(m)%send_sw_off%je = je
01588              else
01589                  domain%list(m)%send_sw%overlap = .TRUE.
01590                  domain%list(m)%send_sw%is = is
01591                  domain%list(m)%send_sw%ie = ie
01592                  domain%list(m)%send_sw%js = js
01593                  domain%list(m)%send_sw%je = je
01594              end if
01595          else
01596              domain%list(m)%send_sw%overlap = .FALSE.
01597              domain%list(m)%send_sw_off%overlap = .FALSE.
01598          end if
01599       end do
01600              
01601 !recv
01602       do list = 0,n-1
01603          m = mod( domain%pos+n-list, n )
01604          call mpp_get_compute_domain( domain%list(m), isc, iec, jsc, jec )
01605 !recv_e
01606          isd = domain%x%compute%end+1; ied = domain%x%data%end
01607          jsd = domain%y%compute%begin; jed = domain%y%compute%end
01608          is=isc; ie=iec; js=jsc; je=jec
01609          domain%list(m)%recv_e%folded = .FALSE.
01610          if( isd.GT.ieg )then
01611              if( domain%x%cyclic )then !try cyclic offset
01612                  is = is+ioff; ie = ie+ioff
01613              else if( BTEST(domain%fold,EAST) )then
01614                  domain%list(m)%recv_e%folded = .TRUE.
01615                  i=is; is = 2*ieg-ie+1; ie = 2*ieg-i+1
01616                  j=js; js = jsg+jeg-je; je = jsg+jeg-j
01617                  if( BTEST(grid_offset_type,EAST) )then
01618                      is = is - 1; ie = ie - 1
01619                  end if
01620              end if
01621          end if
01622          is = max(isd,is); ie = min(ied,ie)
01623          js = max(jsd,js); je = min(jed,je)
01624          if( ie.GE.is .AND. je.GE.js )then
01625              domain%list(m)%overlap = .TRUE.
01626              if( grid_offset_type.NE.AGRID )then
01627                  domain%list(m)%recv_e_off%overlap = .TRUE.
01628                  domain%list(m)%recv_e_off%is = is
01629                  domain%list(m)%recv_e_off%ie = ie
01630                  domain%list(m)%recv_e_off%js = js
01631                  domain%list(m)%recv_e_off%je = je
01632              else
01633                  domain%list(m)%recv_e%overlap = .TRUE.
01634                  domain%list(m)%recv_e%is = is
01635                  domain%list(m)%recv_e%ie = ie
01636                  domain%list(m)%recv_e%js = js
01637                  domain%list(m)%recv_e%je = je
01638              endif
01639          else
01640              domain%list(m)%recv_e%overlap = .FALSE.
01641              domain%list(m)%recv_e_off%overlap = .FALSE.
01642          end if
01643 !recv_se
01644          isd = domain%x%compute%end+1; ied = domain%x%data%end
01645          jsd = domain%y%data%begin; jed = domain%y%compute%begin-1
01646          is=isc; ie=iec; js=jsc; je=jec
01647          domain%list(m)%recv_se%folded = .FALSE.
01648          if( jed.LT.jsg )then
01649              if( domain%y%cyclic )then !try cyclic offset
01650                  js = js-joff; je = je-joff
01651              else if( BTEST(domain%fold,SOUTH) )then
01652                  i=is; is = isg+ieg-ie; ie = isg+ieg-i
01653                  j=js; js = 2*jsg-je-1; je = 2*jsg-j-1
01654                  domain%list(m)%recv_se%folded = .TRUE.
01655                  if( BTEST(grid_offset_type,SOUTH) )then
01656                      js = js + 1; je = je + 1
01657                  end if
01658              end if
01659          end if
01660          if( isd.GT.ieg )then
01661              if( domain%x%cyclic )then !try cyclic offset
01662                  is = is+ioff; ie = ie+ioff
01663              else if( BTEST(domain%fold,EAST) )then
01664                  i=is; is = 2*ieg-ie+1; ie = 2*ieg-i+1
01665                  j=js; js = jsg+jeg-je; je = jsg+jeg-j
01666                  domain%list(m)%recv_se%folded = .TRUE.
01667                  if( BTEST(grid_offset_type,EAST) )then
01668                      is = is - 1; ie = ie - 1
01669                  end if
01670              end if
01671          end if
01672          is = max(isd,is); ie = min(ied,ie)
01673          js = max(jsd,js); je = min(jed,je)
01674          if( ie.GE.is .AND. je.GE.js )then
01675              domain%list(m)%overlap = .TRUE.
01676              if( grid_offset_type.NE.AGRID )then
01677                  domain%list(m)%recv_se_off%overlap = .TRUE.
01678                  domain%list(m)%recv_se_off%is = is
01679                  domain%list(m)%recv_se_off%ie = ie
01680                  domain%list(m)%recv_se_off%js = js
01681                  domain%list(m)%recv_se_off%je = je
01682              else
01683                  domain%list(m)%recv_se%overlap = .TRUE.
01684                  domain%list(m)%recv_se%is = is
01685                  domain%list(m)%recv_se%ie = ie
01686                  domain%list(m)%recv_se%js = js
01687                  domain%list(m)%recv_se%je = je
01688              endif
01689          else
01690              domain%list(m)%recv_se%overlap = .FALSE.
01691              domain%list(m)%recv_se_off%overlap = .FALSE.
01692          end if
01693 !recv_s
01694          isd = domain%x%compute%begin; ied = domain%x%compute%end
01695          jsd = domain%y%data%begin; jed = domain%y%compute%begin-1
01696          is=isc; ie=iec; js=jsc; je=jec
01697          domain%list(m)%recv_s%folded = .FALSE.
01698          if( jed.LT.jsg )then
01699              if( domain%y%cyclic )then !try cyclic offset
01700                  js = js-joff; je = je-joff
01701              else if( BTEST(domain%fold,SOUTH) )then
01702                  i=is; is = isg+ieg-ie; ie = isg+ieg-i
01703                  j=js; js = 2*jsg-je-1; je = 2*jsg-j-1
01704                  domain%list(m)%recv_s%folded = .TRUE.
01705                  if( BTEST(grid_offset_type,SOUTH) )then
01706                      js = js + 1; je = je + 1
01707                  end if
01708              end if
01709          end if
01710          is = max(isd,is); ie = min(ied,ie)
01711          js = max(jsd,js); je = min(jed,je)
01712          if( ie.GE.is .AND. je.GE.js )then
01713              domain%list(m)%overlap = .TRUE.
01714              if( grid_offset_type.NE.AGRID )then
01715                  domain%list(m)%recv_s_off%overlap = .TRUE.
01716                  domain%list(m)%recv_s_off%is = is
01717                  domain%list(m)%recv_s_off%ie = ie
01718                  domain%list(m)%recv_s_off%js = js
01719                  domain%list(m)%recv_s_off%je = je
01720              else
01721                  domain%list(m)%recv_s%overlap = .TRUE.
01722                  domain%list(m)%recv_s%is = is
01723                  domain%list(m)%recv_s%ie = ie
01724                  domain%list(m)%recv_s%js = js
01725                  domain%list(m)%recv_s%je = je
01726              endif
01727          else
01728              domain%list(m)%recv_s%overlap = .FALSE.
01729              domain%list(m)%recv_s_off%overlap = .FALSE.
01730 
01731          end if
01732 !recv_sw
01733          isd = domain%x%data%begin; ied = domain%x%compute%begin-1
01734          jsd = domain%y%data%begin; jed = domain%y%compute%begin-1
01735          is=isc; ie=iec; js=jsc; je=jec
01736          domain%list(m)%recv_sw%folded = .FALSE.
01737          if( jed.LT.jsg )then
01738              if( domain%y%cyclic )then !try cyclic offset
01739                  js = js-joff; je = je-joff
01740              else if( BTEST(domain%fold,SOUTH) )then
01741                  i=is; is = isg+ieg-ie; ie = isg+ieg-i
01742                  j=js; js = 2*jsg-je-1; je = 2*jsg-j-1
01743                  domain%list(m)%recv_sw%folded = .TRUE.
01744                  if( BTEST(grid_offset_type,SOUTH) )then
01745                      js = js + 1; je = je + 1
01746                  end if
01747              end if
01748          end if
01749          if( ied.LT.isg )then
01750              if( domain%x%cyclic )then !try cyclic offset
01751                  is = is-ioff; ie = ie-ioff
01752              else if( BTEST(domain%fold,WEST) )then
01753                  i=is; is = 2*isg-ie-1; ie = 2*isg-i-1
01754                  j=js; js = jsg+jeg-je; je = jsg+jeg-j
01755                  domain%list(m)%recv_sw%folded = .TRUE.
01756                  if( BTEST(grid_offset_type,WEST) )then
01757                      is = is + 1; ie = ie + 1
01758                  end if
01759              end if
01760          end if
01761          is = max(isd,is); ie = min(ied,ie)
01762          js = max(jsd,js); je = min(jed,je)
01763          if( ie.GE.is .AND. je.GE.js )then
01764              domain%list(m)%overlap = .TRUE.
01765              if( grid_offset_type.NE.AGRID )then
01766                  domain%list(m)%recv_sw_off%overlap = .TRUE.
01767                  domain%list(m)%recv_sw_off%is = is
01768                  domain%list(m)%recv_sw_off%ie = ie
01769                  domain%list(m)%recv_sw_off%js = js
01770                  domain%list(m)%recv_sw_off%je = je
01771              else
01772                  domain%list(m)%recv_sw%overlap = .TRUE.
01773                  domain%list(m)%recv_sw%is = is
01774                  domain%list(m)%recv_sw%ie = ie
01775                  domain%list(m)%recv_sw%js = js
01776                  domain%list(m)%recv_sw%je = je
01777              endif
01778          else
01779              domain%list(m)%recv_sw%overlap = .FALSE.
01780              domain%list(m)%recv_sw_off%overlap = .FALSE.
01781          end if
01782 !recv_w
01783          isd = domain%x%data%begin; ied = domain%x%compute%begin-1
01784          jsd = domain%y%compute%begin; jed = domain%y%compute%end
01785          is=isc; ie=iec; js=jsc; je=jec
01786          domain%list(m)%recv_w%folded = .FALSE.
01787          if( ied.LT.isg )then
01788              if( domain%x%cyclic )then !try cyclic offset
01789                  is = is-ioff; ie = ie-ioff
01790              else if( BTEST(domain%fold,WEST) )then
01791                  i=is; is = 2*isg-ie-1; ie = 2*isg-i-1
01792                  j=js; js = jsg+jeg-je; je = jsg+jeg-j
01793                  domain%list(m)%recv_w%folded = .TRUE.
01794                  if( BTEST(grid_offset_type,WEST) )then
01795                      is = is + 1; ie = ie + 1
01796                  end if
01797              end if
01798          end if
01799          is = max(isd,is); ie = min(ied,ie)
01800          js = max(jsd,js); je = min(jed,je)
01801          if( ie.GE.is .AND. je.GE.js )then
01802              domain%list(m)%overlap = .TRUE.
01803              if( grid_offset_type.NE.AGRID )then
01804                  domain%list(m)%recv_w_off%overlap = .TRUE.
01805                  domain%list(m)%recv_w_off%is = is
01806                  domain%list(m)%recv_w_off%ie = ie
01807                  domain%list(m)%recv_w_off%js = js
01808                  domain%list(m)%recv_w_off%je = je
01809              else
01810                  domain%list(m)%recv_w%overlap = .TRUE.
01811                  domain%list(m)%recv_w%is = is
01812                  domain%list(m)%recv_w%ie = ie
01813                  domain%list(m)%recv_w%js = js
01814                  domain%list(m)%recv_w%je = je
01815              endif
01816          else
01817              domain%list(m)%recv_w%overlap = .FALSE.
01818              domain%list(m)%recv_w_off%overlap = .FALSE.
01819          end if
01820 !recv_nw
01821          isd = domain%x%data%begin; ied = domain%x%compute%begin-1
01822          jsd = domain%y%compute%end+1; jed = domain%y%data%end
01823          is=isc; ie=iec; js=jsc; je=jec
01824          domain%list(m)%recv_nw%folded = .FALSE.
01825          if( jsd.GT.jeg )then
01826              if( domain%y%cyclic )then !try cyclic offset
01827                  js = js+joff; je = je+joff
01828              else if( BTEST(domain%fold,NORTH) )then
01829                  i=is; is = isg+ieg-ie; ie = isg+ieg-i
01830                  j=js; js = 2*jeg-je+1; je = 2*jeg-j+1
01831                  domain%list(m)%recv_nw%folded = .TRUE.
01832                  if( BTEST(grid_offset_type,NORTH) )then
01833                      js = js - 1; je = je - 1
01834                  end if
01835              end if
01836          end if
01837          if( ied.LT.isg )then
01838              if( domain%x%cyclic )then !try cyclic offset
01839                  is = is-ioff; ie = ie-ioff
01840              else if( BTEST(domain%fold,WEST) )then
01841                  i=is; is = 2*isg-ie-1; ie = 2*isg-i-1
01842                  j=js; js = jsg+jeg-je; je = jsg+jeg-j
01843                  domain%list(m)%recv_nw%folded = .TRUE.
01844                  if( BTEST(grid_offset_type,WEST) )then
01845                      is = is + 1; ie = ie + 1
01846                  end if
01847              end if
01848          end if
01849          is = max(isd,is); ie = min(ied,ie)
01850          js = max(jsd,js); je = min(jed,je)
01851          if( ie.GE.is .AND. je.GE.js )then
01852              domain%list(m)%overlap = .TRUE.
01853              if( grid_offset_type.NE.AGRID )then
01854                  domain%list(m)%recv_nw_off%overlap = .TRUE.
01855                  domain%list(m)%recv_nw_off%is = is
01856                  domain%list(m)%recv_nw_off%ie = ie
01857                  domain%list(m)%recv_nw_off%js = js
01858                  domain%list(m)%recv_nw_off%je = je
01859              else
01860                  domain%list(m)%recv_nw%overlap = .TRUE.
01861                  domain%list(m)%recv_nw%is = is
01862                  domain%list(m)%recv_nw%ie = ie
01863                  domain%list(m)%recv_nw%js = js
01864                  domain%list(m)%recv_nw%je = je
01865              endif
01866          else
01867              domain%list(m)%recv_nw%overlap = .FALSE.
01868              domain%list(m)%recv_nw_off%overlap = .FALSE.
01869          end if
01870 !recv_n
01871          isd = domain%x%compute%begin; ied = domain%x%compute%end
01872          jsd = domain%y%compute%end+1; jed = domain%y%data%end
01873          is=isc; ie=iec; js=jsc; je=jec
01874          domain%list(m)%recv_n%folded = .FALSE.
01875          if( jsd.GT.jeg )then
01876              if( domain%y%cyclic )then !try cyclic offset
01877                  js = js+joff; je = je+joff
01878              else if( BTEST(domain%fold,NORTH) )then
01879                  i=is; is = isg+ieg-ie; ie = isg+ieg-i
01880                  j=js; js = 2*jeg-je+1; je = 2*jeg-j+1
01881                  domain%list(m)%recv_n%folded = .TRUE.
01882                  if( BTEST(grid_offset_type,NORTH) )then
01883                      js = js - 1; je = je - 1
01884                  end if
01885              end if
01886          end if
01887          is = max(isd,is); ie = min(ied,ie)
01888          js = max(jsd,js); je = min(jed,je)
01889          if( ie.GE.is .AND. je.GE.js )then
01890              domain%list(m)%overlap = .TRUE.
01891              if( grid_offset_type.NE.AGRID )then
01892                  domain%list(m)%recv_n_off%overlap = .TRUE.
01893                  domain%list(m)%recv_n_off%is = is
01894                  domain%list(m)%recv_n_off%ie = ie
01895                  domain%list(m)%recv_n_off%js = js
01896                  domain%list(m)%recv_n_off%je = je
01897              else
01898                  domain%list(m)%recv_n%overlap = .TRUE.
01899                  domain%list(m)%recv_n%is = is
01900                  domain%list(m)%recv_n%ie = ie
01901                  domain%list(m)%recv_n%js = js
01902                  domain%list(m)%recv_n%je = je
01903              end if
01904          else
01905              domain%list(m)%recv_n%overlap = .FALSE.
01906              domain%list(m)%recv_n_off%overlap = .FALSE.
01907          end if
01908 !recv_ne
01909          isd = domain%x%compute%end+1; ied = domain%x%data%end
01910          jsd = domain%y%compute%end+1; jed = domain%y%data%end
01911          is=isc; ie=iec; js=jsc; je=jec
01912          domain%list(m)%recv_ne%folded = .FALSE.
01913          if( jsd.GT.jeg )then
01914              if( domain%y%cyclic )then !try cyclic offset
01915                  js = js+joff; je = je+joff
01916              else if( BTEST(domain%fold,NORTH) )then
01917                  i=is; is = isg+ieg-ie; ie = isg+ieg-i
01918                  j=js; js = 2*jeg-je+1; je = 2*jeg-j+1
01919                  domain%list(m)%recv_ne%folded = .TRUE.
01920                  if( BTEST(grid_offset_type,NORTH) )then
01921                      js = js - 1; je = je - 1
01922                  end if
01923              end if
01924          end if
01925          if( isd.GT.ieg )then
01926              if( domain%x%cyclic )then !try cyclic offset
01927                  is = is+ioff; ie = ie+ioff
01928              else if( BTEST(domain%fold,EAST) )then
01929                  i=is; is = 2*ieg-ie+1; ie = 2*ieg-i+1
01930                  j=js; js = jsg+jeg-je; je = jsg+jeg-j
01931                  domain%list(m)%recv_ne%folded = .TRUE.
01932                  if( BTEST(grid_offset_type,EAST) )then
01933                      is = is - 1; ie = ie - 1
01934                  end if
01935              end if
01936          end if
01937          is = max(isd,is); ie = min(ied,ie)
01938          js = max(jsd,js); je = min(jed,je)
01939          if( ie.GE.is .AND. je.GE.js )then
01940              domain%list(m)%overlap = .TRUE.
01941              if( grid_offset_type.NE.AGRID )then
01942                  domain%list(m)%recv_ne_off%overlap = .TRUE.
01943                  domain%list(m)%recv_ne_off%is = is
01944                  domain%list(m)%recv_ne_off%ie = ie
01945                  domain%list(m)%recv_ne_off%js = js
01946                  domain%list(m)%recv_ne_off%je = je
01947              else
01948                  domain%list(m)%recv_ne%overlap = .TRUE.
01949                  domain%list(m)%recv_ne%is = is
01950                  domain%list(m)%recv_ne%ie = ie
01951                  domain%list(m)%recv_ne%js = js
01952                  domain%list(m)%recv_ne%je = je
01953              end if
01954          else
01955              domain%list(m)%recv_ne%overlap = .FALSE.
01956              domain%list(m)%recv_ne_off%overlap = .FALSE.
01957          end if
01958       end do
01959       if( grid_offset_type.EQ.AGRID )domain%remote_domains_initialized = .TRUE.
01960       if( grid_offset_type.NE.AGRID )domain%remote_off_domains_initialized = .TRUE.
01961       return
01962     end subroutine compute_overlaps
01963 
01964     subroutine mpp_define_layout2D( global_indices, ndivs, layout )
01965       integer, intent(in) :: global_indices(4) !(/ isg, ieg, jsg, jeg /)
01966       integer, intent(in) :: ndivs !number of divisions to divide global domain
01967       integer, intent(out) :: layout(2)
01968 
01969       integer :: isg, ieg, jsg, jeg, isz, jsz, idiv, jdiv
01970 
01971       isg = global_indices(1)
01972       ieg = global_indices(2)
01973       jsg = global_indices(3)
01974       jeg = global_indices(4)
01975 
01976       isz = ieg - isg + 1
01977       jsz = jeg - jsg + 1
01978 !first try to divide ndivs in the domain aspect ratio: if imperfect aspect, reduce idiv till it divides ndivs
01979       idiv = nint( sqrt(float(ndivs*isz)/jsz) )
01980       idiv = max(idiv,1) !for isz=1 line above can give 0
01981       do while( mod(ndivs,idiv).NE.0 )
01982          idiv = idiv - 1
01983       end do                 !will terminate at idiv=1 if not before
01984       jdiv = ndivs/idiv
01985 
01986       layout = (/ idiv, jdiv /)
01987       return
01988     end subroutine mpp_define_layout2D
01989 
01990 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
01991 !                                                                             !
01992 !     MPP_GET and SET routiness: retrieve various components of domains       !
01993 !                                                                             !
01994 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
01995 
01996     subroutine mpp_get_compute_domain1D( domain, begin, end, size, max_size, is_global )
01997       type(domain1D), intent(in) :: domain
01998       integer, intent(out), optional :: begin, end, size, max_size
01999       logical, intent(out), optional :: is_global
02000 
02001       if( PRESENT(begin)     )begin     = domain%compute%begin
02002       if( PRESENT(end)       )end       = domain%compute%end
02003       if( PRESENT(size)      )size      = domain%compute%size
02004       if( PRESENT(max_size)  )max_size  = domain%compute%max_size
02005       if( PRESENT(is_global) )is_global = domain%compute%is_global
02006       return
02007     end subroutine mpp_get_compute_domain1D
02008 
02009     subroutine mpp_get_data_domain1D( domain, begin, end, size, max_size, is_global )
02010       type(domain1D), intent(in) :: domain
02011       integer, intent(out), optional :: begin, end, size, max_size
02012       logical, intent(out), optional :: is_global
02013 
02014       if( PRESENT(begin)     )begin     = domain%data%begin
02015       if( PRESENT(end)       )end       = domain%data%end
02016       if( PRESENT(size)      )size      = domain%data%size
02017       if( PRESENT(max_size)  )max_size  = domain%data%max_size
02018       if( PRESENT(is_global) )is_global = domain%data%is_global
02019       return
02020     end subroutine mpp_get_data_domain1D
02021 
02022     subroutine mpp_get_global_domain1D( domain, begin, end, size, max_size )
02023       type(domain1D), intent(in) :: domain
02024       integer, intent(out), optional :: begin, end, size, max_size
02025 
02026       if( PRESENT(begin)    )begin    = domain%global%begin
02027       if( PRESENT(end)      )end      = domain%global%end
02028       if( PRESENT(size)     )size     = domain%global%size
02029       if( PRESENT(max_size) )max_size = domain%global%max_size
02030       return
02031     end subroutine mpp_get_global_domain1D
02032 
02033     subroutine mpp_get_compute_domain2D( domain, xbegin, xend, ybegin, yend, xsize, xmax_size, ysize, ymax_size, &
02034          x_is_global, y_is_global )
02035       type(domain2D), intent(in) :: domain
02036       integer, intent(out), optional :: xbegin, xend, ybegin, yend, xsize, xmax_size, ysize, ymax_size
02037       logical, intent(out), optional :: x_is_global, y_is_global
02038       call mpp_get_compute_domain( domain%x, xbegin, xend, xsize, xmax_size, x_is_global )
02039       call mpp_get_compute_domain( domain%y, ybegin, yend, ysize, ymax_size, y_is_global )
02040       return
02041     end subroutine mpp_get_compute_domain2D
02042 
02043     subroutine mpp_get_data_domain2D( domain, xbegin, xend, ybegin, yend, xsize, xmax_size, ysize, ymax_size, &
02044          x_is_global, y_is_global )
02045       type(domain2D), intent(in) :: domain
02046       integer, intent(out), optional :: xbegin, xend, ybegin, yend, xsize, xmax_size, ysize, ymax_size
02047       logical, intent(out), optional :: x_is_global, y_is_global
02048       call mpp_get_data_domain( domain%x, xbegin, xend, xsize, xmax_size, x_is_global )
02049       call mpp_get_data_domain( domain%y, ybegin, yend, ysize, ymax_size, y_is_global )
02050       return
02051     end subroutine mpp_get_data_domain2D
02052 
02053     subroutine mpp_get_global_domain2D( domain, xbegin, xend, ybegin, yend, xsize, xmax_size, ysize, ymax_size )
02054       type(domain2D), intent(in) :: domain
02055       integer, intent(out), optional :: xbegin, xend, ybegin, yend, xsize, xmax_size, ysize, ymax_size
02056       call mpp_get_global_domain( domain%x, xbegin, xend, xsize, xmax_size )
02057       call mpp_get_global_domain( domain%y, ybegin, yend, ysize, ymax_size )
02058       return
02059     end subroutine mpp_get_global_domain2D
02060 
02061     subroutine mpp_get_domain_components( domain, x, y )
02062       type(domain2D), intent(in) :: domain
02063       type(domain1D), intent(out), optional :: x, y
02064       if( PRESENT(x) )x = domain%x
02065       if( PRESENT(y) )y = domain%y
02066       return
02067     end subroutine mpp_get_domain_components
02068 
02069     subroutine mpp_get_compute_domains1D( domain, begin, end, size )
02070       type(domain1D), intent(in) :: domain
02071       integer, intent(out), optional, dimension(:) :: begin, end, size 
02072 
02073       if( .NOT.module_is_initialized ) &
02074            call mpp_error( FATAL, 'MPP_GET_COMPUTE_DOMAINS: must first call mpp_domains_init.' )
02075 !we use shape instead of size for error checks because size is used as an argument
02076       if( PRESENT(begin) )then
02077           if( any(shape(begin).NE.shape(domain%list)) ) &
02078                call mpp_error( FATAL, 'MPP_GET_COMPUTE_DOMAINS: begin array size does not match domain.' )
02079           begin(:) = domain%list(:)%compute%begin
02080       end if
02081       if( PRESENT(end) )then
02082           if( any(shape(end).NE.shape(domain%list)) ) &
02083                call mpp_error( FATAL, 'MPP_GET_COMPUTE_DOMAINS: end array size does not match domain.' )
02084           end(:) = domain%list(:)%compute%end
02085       end if
02086       if( PRESENT(size) )then
02087           if( any(shape(size).NE.shape(domain%list)) ) &
02088                call mpp_error( FATAL, 'MPP_GET_COMPUTE_DOMAINS: size array size does not match domain.' )
02089           size(:) = domain%list(:)%compute%size
02090       end if
02091       return
02092     end subroutine mpp_get_compute_domains1D
02093 
02094     subroutine mpp_get_compute_domains2D( domain, xbegin, xend, xsize, ybegin, yend, ysize )
02095       type(domain2D), intent(in) :: domain
02096       integer, intent(out), optional, dimension(:) :: xbegin, xend, xsize, ybegin, yend, ysize
02097 
02098       if( .NOT.module_is_initialized ) &
02099            call mpp_error( FATAL, 'MPP_GET_COMPUTE_DOMAINS: must first call mpp_domains_init.' )
02100 
02101       if( PRESENT(xbegin) )then
02102           if( size(xbegin).NE.size(domain%list) ) &
02103                call mpp_error( FATAL, 'MPP_GET_COMPUTE_DOMAINS: xbegin array size does not match domain.' )
02104           xbegin(:) = domain%list(:)%x%compute%begin
02105       end if
02106       if( PRESENT(xend) )then
02107           if( size(xend).NE.size(domain%list) ) &
02108                call mpp_error( FATAL, 'MPP_GET_COMPUTE_DOMAINS: xend array size does not match domain.' )
02109           xend(:) = domain%list(:)%x%compute%end
02110       end if
02111       if( PRESENT(xsize) )then
02112           if( size(xsize).NE.size(domain%list) ) &
02113                call mpp_error( FATAL, 'MPP_GET_COMPUTE_DOMAINS: xsize array size does not match domain.' )
02114           xsize(:) = domain%list(:)%x%compute%size
02115       end if
02116       if( PRESENT(ybegin) )then
02117           if( size(ybegin).NE.size(domain%list) ) &
02118                call mpp_error( FATAL, 'MPP_GET_COMPUTE_DOMAINS: ybegin array size does not match domain.' )
02119           ybegin(:) = domain%list(:)%y%compute%begin
02120       end if
02121       if( PRESENT(yend) )then
02122           if( size(yend).NE.size(domain%list) ) &
02123                call mpp_error( FATAL, 'MPP_GET_COMPUTE_DOMAINS: yend array size does not match domain.' )
02124           yend(:) = domain%list(:)%y%compute%end
02125       end if
02126       if( PRESENT(ysize) )then
02127           if( size(ysize).NE.size(domain%list) ) &
02128                call mpp_error( FATAL, 'MPP_GET_COMPUTE_DOMAINS: ysize array size does not match domain.' )
02129           ysize(:) = domain%list(:)%y%compute%size
02130       end if
02131       return
02132     end subroutine mpp_get_compute_domains2D
02133 
02134     subroutine mpp_get_pelist1D( domain, pelist, pos )
02135       type(domain1D), intent(in) :: domain
02136       integer, intent(out) :: pelist(:)
02137       integer, intent(out), optional :: pos
02138       integer :: ndivs
02139 
02140       if( .NOT.module_is_initialized ) &
02141            call mpp_error( FATAL, 'MPP_GET_PELIST: must first call mpp_domains_init.' )
02142       ndivs = size(domain%list)
02143       
02144       if( size(pelist).NE.ndivs ) &
02145            call mpp_error( FATAL, 'MPP_GET_PELIST: pelist array size does not match domain.' )
02146 
02147       pelist(:) = domain%list(0:ndivs-1)%pe
02148       if( PRESENT(pos) )pos = domain%pos
02149       return
02150     end subroutine mpp_get_pelist1D
02151 
02152     subroutine mpp_get_pelist2D( domain, pelist, pos )
02153       type(domain2D), intent(in) :: domain
02154       integer, intent(out) :: pelist(:)
02155       integer, intent(out), optional :: pos
02156 
02157       if( .NOT.module_is_initialized ) &
02158            call mpp_error( FATAL, 'MPP_GET_PELIST: must first call mpp_domains_init.' )
02159       if( size(pelist).NE.size(domain%list) ) &
02160            call mpp_error( FATAL, 'MPP_GET_PELIST: pelist array size does not match domain.' )
02161 
02162       pelist(:) = domain%list(:)%pe
02163       if( PRESENT(pos) )pos = domain%pos
02164       return
02165     end subroutine mpp_get_pelist2D
02166 
02167     subroutine mpp_get_layout1D( domain, layout )
02168       type(domain1D), intent(in) :: domain
02169       integer, intent(out) :: layout
02170       
02171       if( .NOT.module_is_initialized ) &
02172            call mpp_error( FATAL, 'MPP_GET_LAYOUT: must first call mpp_domains_init.' )
02173 
02174       layout = size(domain%list)
02175       return
02176     end subroutine mpp_get_layout1D
02177 
02178     subroutine mpp_get_layout2D( domain, layout )
02179       type(domain2D), intent(in) :: domain
02180       integer, intent(out) :: layout(2)
02181       
02182       if( .NOT.module_is_initialized ) &
02183            call mpp_error( FATAL, 'MPP_GET_LAYOUT: must first call mpp_domains_init.' )
02184 
02185       layout(1) = size(domain%x%list)
02186       layout(2) = size(domain%y%list)
02187       return
02188     end subroutine mpp_get_layout2D
02189 
02190 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
02191 !                                                                             !
02192 !              MPP_UPDATE_DOMAINS: fill halos for 2D decomposition            !
02193 !                                                                             !
02194 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
02195 
02196 #define VECTOR_FIELD_
02197 #define MPP_TYPE_ real(DOUBLE_KIND)
02198 #define MPP_UPDATE_DOMAINS_2D_ mpp_update_domain2D_r8_2D
02199 #define MPP_UPDATE_DOMAINS_3D_ mpp_update_domain2D_r8_3D
02200 #define MPP_UPDATE_DOMAINS_4D_ mpp_update_domain2D_r8_4D
02201 #define MPP_UPDATE_DOMAINS_5D_ mpp_update_domain2D_r8_5D
02202 
02203 #ifdef  VECTOR_FIELD_
02204 #define MPP_UPDATE_DOMAINS_2D_V_ mpp_update_domain2D_r8_2Dv
02205 #define MPP_UPDATE_DOMAINS_3D_V_ mpp_update_domain2D_r8_3Dv
02206 #define MPP_UPDATE_DOMAINS_4D_V_ mpp_update_domain2D_r8_4Dv
02207 #define MPP_UPDATE_DOMAINS_5D_V_ mpp_update_domain2D_r8_5Dv
02208 #endif
02209 #define MPP_REDISTRIBUTE_2D_ mpp_redistribute_r8_2D
02210 #define MPP_REDISTRIBUTE_3D_ mpp_redistribute_r8_3D
02211 #define MPP_REDISTRIBUTE_4D_ mpp_redistribute_r8_4D
02212 #define MPP_REDISTRIBUTE_5D_ mpp_redistribute_r8_5D
02213 #include <mpp_update_domains2D.h>
02214 #undef  VECTOR_FIELD_
02215 
02216 #define MPP_TYPE_ complex(DOUBLE_KIND)
02217 #define MPP_UPDATE_DOMAINS_2D_ mpp_update_domain2D_c8_2D
02218 #define MPP_UPDATE_DOMAINS_3D_ mpp_update_domain2D_c8_3D
02219 #define MPP_UPDATE_DOMAINS_4D_ mpp_update_domain2D_c8_4D
02220 #define MPP_UPDATE_DOMAINS_5D_ mpp_update_domain2D_c8_5D
02221 #define MPP_REDISTRIBUTE_2D_ mpp_redistribute_c8_2D
02222 #define MPP_REDISTRIBUTE_3D_ mpp_redistribute_c8_3D
02223 #define MPP_REDISTRIBUTE_4D_ mpp_redistribute_c8_4D
02224 #define MPP_REDISTRIBUTE_5D_ mpp_redistribute_c8_5D
02225 #include <mpp_update_domains2D.h>
02226 
02227 #ifndef no_8byte_integers
02228 #define MPP_TYPE_ integer(LONG_KIND)
02229 #define MPP_UPDATE_DOMAINS_2D_ mpp_update_domain2D_i8_2D
02230 #define MPP_UPDATE_DOMAINS_3D_ mpp_update_domain2D_i8_3D
02231 #define MPP_UPDATE_DOMAINS_4D_ mpp_update_domain2D_i8_4D
02232 #define MPP_UPDATE_DOMAINS_5D_ mpp_update_domain2D_i8_5D
02233 #define MPP_REDISTRIBUTE_2D_ mpp_redistribute_i8_2D
02234 #define MPP_REDISTRIBUTE_3D_ mpp_redistribute_i8_3D
02235 #define MPP_REDISTRIBUTE_4D_ mpp_redistribute_i8_4D
02236 #define MPP_REDISTRIBUTE_5D_ mpp_redistribute_i8_5D
02237 #include <mpp_update_domains2D.h>
02238 
02239 #define MPP_TYPE_ logical(LONG_KIND)
02240 #define MPP_UPDATE_DOMAINS_2D_ mpp_update_domain2D_l8_2D
02241 #define MPP_UPDATE_DOMAINS_3D_ mpp_update_domain2D_l8_3D
02242 #define MPP_UPDATE_DOMAINS_4D_ mpp_update_domain2D_l8_4D
02243 #define MPP_UPDATE_DOMAINS_5D_ mpp_update_domain2D_l8_5D
02244 #define MPP_REDISTRIBUTE_2D_ mpp_redistribute_l8_2D
02245 #define MPP_REDISTRIBUTE_3D_ mpp_redistribute_l8_3D
02246 #define MPP_REDISTRIBUTE_4D_ mpp_redistribute_l8_4D
02247 #define MPP_REDISTRIBUTE_5D_ mpp_redistribute_l8_5D
02248 #include <mpp_update_domains2D.h>
02249 #endif
02250 
02251 #ifndef no_4byte_reals
02252 #define VECTOR_FIELD_
02253 #define MPP_TYPE_ real(FLOAT_KIND)
02254 #define MPP_UPDATE_DOMAINS_2D_ mpp_update_domain2D_r4_2D
02255 #define MPP_UPDATE_DOMAINS_3D_ mpp_update_domain2D_r4_3D
02256 #define MPP_UPDATE_DOMAINS_4D_ mpp_update_domain2D_r4_4D
02257 #define MPP_UPDATE_DOMAINS_5D_ mpp_update_domain2D_r4_5D
02258 #ifdef  VECTOR_FIELD_
02259 #define MPP_UPDATE_DOMAINS_2D_V_ mpp_update_domain2D_r4_2Dv
02260 #define MPP_UPDATE_DOMAINS_3D_V_ mpp_update_domain2D_r4_3Dv
02261 #define MPP_UPDATE_DOMAINS_4D_V_ mpp_update_domain2D_r4_4Dv
02262 #define MPP_UPDATE_DOMAINS_5D_V_ mpp_update_domain2D_r4_5Dv
02263 #endif
02264 #define MPP_REDISTRIBUTE_2D_ mpp_redistribute_r4_2D
02265 #define MPP_REDISTRIBUTE_3D_ mpp_redistribute_r4_3D
02266 #define MPP_REDISTRIBUTE_4D_ mpp_redistribute_r4_4D
02267 #define MPP_REDISTRIBUTE_5D_ mpp_redistribute_r4_5D
02268 #include <mpp_update_domains2D.h>
02269 #undef  VECTOR_FIELD_
02270 #endif
02271 
02272 #ifndef no_4byte_cmplx
02273 #define MPP_TYPE_ complex(FLOAT_KIND)
02274 #define MPP_UPDATE_DOMAINS_2D_ mpp_update_domain2D_c4_2D
02275 #define MPP_UPDATE_DOMAINS_3D_ mpp_update_domain2D_c4_3D
02276 #define MPP_UPDATE_DOMAINS_4D_ mpp_update_domain2D_c4_4D
02277 #define MPP_UPDATE_DOMAINS_5D_ mpp_update_domain2D_c4_5D
02278 #define MPP_REDISTRIBUTE_2D_ mpp_redistribute_c4_2D
02279 #define MPP_REDISTRIBUTE_3D_ mpp_redistribute_c4_3D
02280 #define MPP_REDISTRIBUTE_4D_ mpp_redistribute_c4_4D
02281 #define MPP_REDISTRIBUTE_5D_ mpp_redistribute_c4_5D
02282 #include <mpp_update_domains2D.h>
02283 #endif
02284 
02285 #define MPP_TYPE_ integer(INT_KIND)
02286 #define MPP_UPDATE_DOMAINS_2D_ mpp_update_domain2D_i4_2D
02287 #define MPP_UPDATE_DOMAINS_3D_ mpp_update_domain2D_i4_3D
02288 #define MPP_UPDATE_DOMAINS_4D_ mpp_update_domain2D_i4_4D
02289 #define MPP_UPDATE_DOMAINS_5D_ mpp_update_domain2D_i4_5D
02290 #define MPP_REDISTRIBUTE_2D_ mpp_redistribute_i4_2D
02291 #define MPP_REDISTRIBUTE_3D_ mpp_redistribute_i4_3D
02292 #define MPP_REDISTRIBUTE_4D_ mpp_redistribute_i4_4D
02293 #define MPP_REDISTRIBUTE_5D_ mpp_redistribute_i4_5D
02294 #include <mpp_update_domains2D.h>
02295 
02296 #define MPP_TYPE_ logical(INT_KIND)
02297 #define MPP_UPDATE_DOMAINS_2D_ mpp_update_domain2D_l4_2D
02298 #define MPP_UPDATE_DOMAINS_3D_ mpp_update_domain2D_l4_3D
02299 #define MPP_UPDATE_DOMAINS_4D_ mpp_update_domain2D_l4_4D
02300 #define MPP_UPDATE_DOMAINS_5D_ mpp_update_domain2D_l4_5D
02301 #define MPP_REDISTRIBUTE_2D_ mpp_redistribute_l4_2D
02302 #define MPP_REDISTRIBUTE_3D_ mpp_redistribute_l4_3D
02303 #define MPP_REDISTRIBUTE_4D_ mpp_redistribute_l4_4D
02304 #define MPP_REDISTRIBUTE_5D_ mpp_redistribute_l4_5D
02305 #include <mpp_update_domains2D.h>
02306 
02307 !#define MPP_UPDATE_DOMAINS_2D_ mpp_update_domain1D_r8_2D
02308 !#define MPP_UPDATE_DOMAINS_3D_ mpp_update_domain1D_r8_3D
02309 !#define MPP_UPDATE_DOMAINS_4D_ mpp_update_domain1D_r8_4D
02310 !#define MPP_UPDATE_DOMAINS_5D_ mpp_update_domain1D_r8_5D
02311 !#define MPP_TYPE_ real(DOUBLE_KIND)
02312 !#include <mpp_update_domains1D.h>
02313 !
02314 !#define MPP_UPDATE_DOMAINS_2D_ mpp_update_domain1D_c8_2D
02315 !#define MPP_UPDATE_DOMAINS_3D_ mpp_update_domain1D_c8_3D
02316 !#define MPP_UPDATE_DOMAINS_4D_ mpp_update_domain1D_c8_4D
02317 !#define MPP_UPDATE_DOMAINS_5D_ mpp_update_domain1D_c8_5D
02318 !#define MPP_TYPE_ complex(DOUBLE_KIND)
02319 !#include <mpp_update_domains1D.h>
02320 !
02321 !#ifndef no_8byte_integers
02322 !#define MPP_UPDATE_DOMAINS_2D_ mpp_update_domain1D_i8_2D
02323 !#define MPP_UPDATE_DOMAINS_3D_ mpp_update_domain1D_i8_3D
02324 !#define MPP_UPDATE_DOMAINS_4D_ mpp_update_domain1D_i8_4D
02325 !#define MPP_UPDATE_DOMAINS_5D_ mpp_update_domain1D_i8_5D
02326 !#define MPP_TYPE_ integer(LONG_KIND)
02327 !#include <mpp_update_domains1D.h>
02328 !
02329 !#define MPP_UPDATE_DOMAINS_2D_ mpp_update_domain1D_l8_2D
02330 !#define MPP_UPDATE_DOMAINS_3D_ mpp_update_domain1D_l8_3D
02331 !#define MPP_UPDATE_DOMAINS_4D_ mpp_update_domain1D_l8_4D
02332 !#define MPP_UPDATE_DOMAINS_5D_ mpp_update_domain1D_l8_5D
02333 !#define MPP_TYPE_ logical(LONG_KIND)
02334 !#include <mpp_update_domains1D.h>
02335 !#endif
02336 !
02337 !#define MPP_UPDATE_DOMAINS_2D_ mpp_update_domain1D_r4_2D
02338 !#define MPP_UPDATE_DOMAINS_3D_ mpp_update_domain1D_r4_3D
02339 !#define MPP_UPDATE_DOMAINS_4D_ mpp_update_domain1D_r4_4D
02340 !#define MPP_UPDATE_DOMAINS_5D_ mpp_update_domain1D_r4_5D
02341 !#define MPP_TYPE_ real(FLOAT_KIND)
02342 !#include <mpp_update_domains1D.h>
02343 !
02344 !#define MPP_UPDATE_DOMAINS_2D_ mpp_update_domain1D_c4_2D
02345 !#define MPP_UPDATE_DOMAINS_3D_ mpp_update_domain1D_c4_3D
02346 !#define MPP_UPDATE_DOMAINS_4D_ mpp_update_domain1D_c4_4D
02347 !#define MPP_UPDATE_DOMAINS_5D_ mpp_update_domain1D_c4_5D
02348 !#define MPP_TYPE_ complex(FLOAT_KIND)
02349 !#include <mpp_update_domains1D.h>
02350 !
02351 !#define MPP_UPDATE_DOMAINS_2D_ mpp_update_domain1D_i4_2D
02352 !#define MPP_UPDATE_DOMAINS_3D_ mpp_update_domain1D_i4_3D
02353 !#define MPP_UPDATE_DOMAINS_4D_ mpp_update_domain1D_i4_4D
02354 !#define MPP_UPDATE_DOMAINS_5D_ mpp_update_domain1D_i4_5D
02355 !#define MPP_TYPE_ integer(INT_KIND)
02356 !#include <mpp_update_domains1D.h>
02357 !
02358 !#define MPP_UPDATE_DOMAINS_2D_ mpp_update_domain1D_l4_2D
02359 !#define MPP_UPDATE_DOMAINS_3D_ mpp_update_domain1D_l4_3D
02360 !#define MPP_UPDATE_DOMAINS_4D_ mpp_update_domain1D_l4_4D
02361 !#define MPP_UPDATE_DOMAINS_5D_ mpp_update_domain1D_l4_5D
02362 !#define MPP_TYPE_ logical(INT_KIND)
02363 !#include <mpp_update_domains1D.h>
02364 
02365 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
02366 !                                                                             !
02367 !              MPP_GLOBAL_REDUCE: get global max/min of field                 !
02368 !                                                                             !
02369 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
02370 
02371 #define MPP_GLOBAL_REDUCE_2D_ mpp_global_max_r8_2d
02372 #define MPP_GLOBAL_REDUCE_3D_ mpp_global_max_r8_3d
02373 #define MPP_GLOBAL_REDUCE_4D_ mpp_global_max_r8_4d
02374 #define MPP_GLOBAL_REDUCE_5D_ mpp_global_max_r8_5d
02375 #define MPP_TYPE_ real(DOUBLE_KIND)
02376 #define REDUCE_VAL_ maxval
02377 #define REDUCE_LOC_ maxloc
02378 #define MPP_REDUCE_ mpp_max
02379 #include <mpp_global_reduce.h>
02380 
02381 #define MPP_GLOBAL_REDUCE_2D_ mpp_global_min_r8_2d
02382 #define MPP_GLOBAL_REDUCE_3D_ mpp_global_min_r8_3d
02383 #define MPP_GLOBAL_REDUCE_4D_ mpp_global_min_r8_4d
02384 #define MPP_GLOBAL_REDUCE_5D_ mpp_global_min_r8_5d
02385 #define MPP_TYPE_ real(DOUBLE_KIND)
02386 #define REDUCE_VAL_ minval
02387 #define REDUCE_LOC_ minloc
02388 #define MPP_REDUCE_ mpp_min
02389 #include <mpp_global_reduce.h>
02390 
02391 #ifndef no_4byte_reals
02392 #define MPP_GLOBAL_REDUCE_2D_ mpp_global_max_r4_2d
02393 #define MPP_GLOBAL_REDUCE_3D_ mpp_global_max_r4_3d
02394 #define MPP_GLOBAL_REDUCE_4D_ mpp_global_max_r4_4d
02395 #define MPP_GLOBAL_REDUCE_5D_ mpp_global_max_r4_5d
02396 #define MPP_TYPE_ real(FLOAT_KIND)
02397 #define REDUCE_VAL_ maxval
02398 #define REDUCE_LOC_ maxloc
02399 #define MPP_REDUCE_ mpp_max
02400 #include <mpp_global_reduce.h>
02401 
02402 #define MPP_GLOBAL_REDUCE_2D_ mpp_global_min_r4_2d
02403 #define MPP_GLOBAL_REDUCE_3D_ mpp_global_min_r4_3d
02404 #define MPP_GLOBAL_REDUCE_4D_ mpp_global_min_r4_4d
02405 #define MPP_GLOBAL_REDUCE_5D_ mpp_global_min_r4_5d
02406 #define MPP_TYPE_ real(FLOAT_KIND)
02407 #define REDUCE_VAL_ minval
02408 #define REDUCE_LOC_ minloc
02409 #define MPP_REDUCE_ mpp_min
02410 #include <mpp_global_reduce.h>
02411 #endif
02412 
02413 #ifndef no_8byte_integers
02414 #define MPP_GLOBAL_REDUCE_2D_ mpp_global_max_i8_2d
02415 #define MPP_GLOBAL_REDUCE_3D_ mpp_global_max_i8_3d
02416 #define MPP_GLOBAL_REDUCE_4D_ mpp_global_max_i8_4d
02417 #define MPP_GLOBAL_REDUCE_5D_ mpp_global_max_i8_5d
02418 #define MPP_TYPE_ integer(LONG_KIND)
02419 #define REDUCE_VAL_ maxval
02420 #define REDUCE_LOC_ maxloc
02421 #define MPP_REDUCE_ mpp_max
02422 #include <mpp_global_reduce.h>
02423 
02424 #define MPP_GLOBAL_REDUCE_2D_ mpp_global_min_i8_2d
02425 #define MPP_GLOBAL_REDUCE_3D_ mpp_global_min_i8_3d
02426 #define MPP_GLOBAL_REDUCE_4D_ mpp_global_min_i8_4d
02427 #define MPP_GLOBAL_REDUCE_5D_ mpp_global_min_i8_5d
02428 #define MPP_TYPE_ integer(LONG_KIND)
02429 #define REDUCE_VAL_ minval
02430 #define REDUCE_LOC_ minloc
02431 #define MPP_REDUCE_ mpp_min
02432 #include <mpp_global_reduce.h>
02433 #endif
02434 
02435 #define MPP_GLOBAL_REDUCE_2D_ mpp_global_max_i4_2d
02436 #define MPP_GLOBAL_REDUCE_3D_ mpp_global_max_i4_3d
02437 #define MPP_GLOBAL_REDUCE_4D_ mpp_global_max_i4_4d
02438 #define MPP_GLOBAL_REDUCE_5D_ mpp_global_max_i4_5d
02439 #define MPP_TYPE_ integer(INT_KIND)
02440 #define REDUCE_VAL_ maxval
02441 #define REDUCE_LOC_ maxloc
02442 #define MPP_REDUCE_ mpp_max
02443 #include <mpp_global_reduce.h>
02444 
02445 #define MPP_GLOBAL_REDUCE_2D_ mpp_global_min_i4_2d
02446 #define MPP_GLOBAL_REDUCE_3D_ mpp_global_min_i4_3d
02447 #define MPP_GLOBAL_REDUCE_4D_ mpp_global_min_i4_4d
02448 #define MPP_GLOBAL_REDUCE_5D_ mpp_global_min_i4_5d
02449 #define MPP_TYPE_ integer(INT_KIND)
02450 #define REDUCE_VAL_ minval
02451 #define REDUCE_LOC_ minloc
02452 #define MPP_REDUCE_ mpp_min
02453 #include <mpp_global_reduce.h>
02454 
02455 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
02456 !                                                                             !
02457 !                   MPP_GLOBAL_SUM: global sum of field                       !
02458 !                                                                             !
02459 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
02460 
02461 #define MPP_GLOBAL_SUM_ mpp_global_sum_r8_2d
02462 #define MPP_EXTRA_INDICES_
02463 #define MPP_TYPE_ real(DOUBLE_KIND)
02464 #include <mpp_global_sum.h>
02465 
02466 #define MPP_GLOBAL_SUM_ mpp_global_sum_r8_3d
02467 #define MPP_EXTRA_INDICES_ ,:
02468 #define MPP_TYPE_ real(DOUBLE_KIND)
02469 #include <mpp_global_sum.h>
02470 
02471 #define MPP_GLOBAL_SUM_ mpp_global_sum_r8_4d
02472 #define MPP_EXTRA_INDICES_ ,:,:
02473 #define MPP_TYPE_ real(DOUBLE_KIND)
02474 #include <mpp_global_sum.h>
02475 
02476 #define MPP_GLOBAL_SUM_ mpp_global_sum_r8_5d
02477 #define MPP_EXTRA_INDICES_ ,:,:,:
02478 #define MPP_TYPE_ real(DOUBLE_KIND)
02479 #include <mpp_global_sum.h>
02480 
02481 #ifndef no_4byte_reals
02482 #define MPP_GLOBAL_SUM_ mpp_global_sum_r4_2d
02483 #define MPP_EXTRA_INDICES_
02484 #define MPP_TYPE_ real(FLOAT_KIND)
02485 #include <mpp_global_sum.h>
02486 
02487 #define MPP_GLOBAL_SUM_ mpp_global_sum_r4_3d
02488 #define MPP_EXTRA_INDICES_ ,:
02489 #define MPP_TYPE_ real(FLOAT_KIND)
02490 #include <mpp_global_sum.h>
02491 
02492 #define MPP_GLOBAL_SUM_ mpp_global_sum_r4_4d
02493 #define MPP_EXTRA_INDICES_ ,:,:
02494 #define MPP_TYPE_ real(FLOAT_KIND)
02495 #include <mpp_global_sum.h>
02496 
02497 #define MPP_GLOBAL_SUM_ mpp_global_sum_r4_5d
02498 #define MPP_EXTRA_INDICES_ ,:,:,:
02499 #define MPP_TYPE_ real(FLOAT_KIND)
02500 #include <mpp_global_sum.h>
02501 #endif
02502 
02503 #define MPP_GLOBAL_SUM_ mpp_global_sum_c8_2d
02504 #define MPP_EXTRA_INDICES_
02505 #define MPP_TYPE_ complex(DOUBLE_KIND)
02506 #include <mpp_global_sum.h>
02507 
02508 #define MPP_GLOBAL_SUM_ mpp_global_sum_c8_3d
02509 #define MPP_EXTRA_INDICES_ ,:
02510 #define MPP_TYPE_ complex(DOUBLE_KIND)
02511 #include <mpp_global_sum.h>
02512 
02513 #define MPP_GLOBAL_SUM_ mpp_global_sum_c8_4d
02514 #define MPP_EXTRA_INDICES_ ,:,:
02515 #define MPP_TYPE_ complex(DOUBLE_KIND)
02516 #include <mpp_global_sum.h>
02517 
02518 #define MPP_GLOBAL_SUM_ mpp_global_sum_c8_5d
02519 #define MPP_EXTRA_INDICES_ ,:,:,:
02520 #define MPP_TYPE_ complex(DOUBLE_KIND)
02521 #include <mpp_global_sum.h>
02522 
02523 #ifndef no_4byte_cmplx
02524 #define MPP_GLOBAL_SUM_ mpp_global_sum_c4_2d
02525 #define MPP_EXTRA_INDICES_
02526 #define MPP_TYPE_ complex(FLOAT_KIND)
02527 #include <mpp_global_sum.h>
02528 
02529 #define MPP_GLOBAL_SUM_ mpp_global_sum_c4_3d
02530 #define MPP_EXTRA_INDICES_ ,:
02531 #define MPP_TYPE_ complex(FLOAT_KIND)
02532 #include <mpp_global_sum.h>
02533 
02534 #define MPP_GLOBAL_SUM_ mpp_global_sum_c4_4d
02535 #define MPP_EXTRA_INDICES_ ,:,:
02536 #define MPP_TYPE_ complex(FLOAT_KIND)
02537 #include <mpp_global_sum.h>
02538 
02539 #define MPP_GLOBAL_SUM_ mpp_global_sum_c4_5d
02540 #define MPP_EXTRA_INDICES_ ,:,:,:
02541 #define MPP_TYPE_ complex(FLOAT_KIND)
02542 #include <mpp_global_sum.h>
02543 #endif
02544 
02545 #ifndef no_8byte_integers
02546 #define MPP_GLOBAL_SUM_ mpp_global_sum_i8_2d
02547 #define MPP_EXTRA_INDICES_
02548 #define MPP_TYPE_ integer(LONG_KIND)
02549 #include <mpp_global_sum.h>
02550 
02551 #define MPP_GLOBAL_SUM_ mpp_global_sum_i8_3d
02552 #define MPP_EXTRA_INDICES_ ,:
02553 #define MPP_TYPE_ integer(LONG_KIND)
02554 #include <mpp_global_sum.h>
02555 
02556 #define MPP_GLOBAL_SUM_ mpp_global_sum_i8_4d
02557 #define MPP_EXTRA_INDICES_ ,:,:
02558 #define MPP_TYPE_ integer(LONG_KIND)
02559 #include <mpp_global_sum.h>
02560 
02561 #define MPP_GLOBAL_SUM_ mpp_global_sum_i8_5d
02562 #define MPP_EXTRA_INDICES_ ,:,:,:
02563 #define MPP_TYPE_ integer(LONG_KIND)
02564 #include <mpp_global_sum.h>
02565 #endif
02566 
02567 #define MPP_GLOBAL_SUM_ mpp_global_sum_i4_2d
02568 #define MPP_EXTRA_INDICES_
02569 #define MPP_TYPE_ integer(INT_KIND)
02570 #include <mpp_global_sum.h>
02571 
02572 #define MPP_GLOBAL_SUM_ mpp_global_sum_i4_3d
02573 #define MPP_EXTRA_INDICES_ ,:
02574 #define MPP_TYPE_ integer(INT_KIND)
02575 #include <mpp_global_sum.h>
02576 
02577 #define MPP_GLOBAL_SUM_ mpp_global_sum_i4_4d
02578 #define MPP_EXTRA_INDICES_ ,:,:
02579 #define MPP_TYPE_ integer(INT_KIND)
02580 #include <mpp_global_sum.h>
02581 
02582 #define MPP_GLOBAL_SUM_ mpp_global_sum_i4_5d
02583 #define MPP_EXTRA_INDICES_ ,:,:,:
02584 #define MPP_TYPE_ integer(INT_KIND)
02585 #include <mpp_global_sum.h>
02586     
02587 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
02588 !                                                                             !
02589 !              MPP_GLOBAL_FIELD: get global field from domain field           !
02590 !                                                                             !
02591 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
02592 
02593 #define MPP_GLOBAL_FIELD_2D_ mpp_global_field2D_r8_2d
02594 #define MPP_GLOBAL_FIELD_3D_ mpp_global_field2D_r8_3d
02595 #define MPP_GLOBAL_FIELD_4D_ mpp_global_field2D_r8_4d
02596 #define MPP_GLOBAL_FIELD_5D_ mpp_global_field2D_r8_5d
02597 #define MPP_GLOBAL1D_FIELD_2D_ mpp_global_field1D_r8_2d
02598 #define MPP_TYPE_ real(DOUBLE_KIND)
02599 #include <mpp_global_field.h>
02600 
02601 #define MPP_GLOBAL_FIELD_2D_ mpp_global_field2D_c8_2d
02602 #define MPP_GLOBAL_FIELD_3D_ mpp_global_field2D_c8_3d
02603 #define MPP_GLOBAL_FIELD_4D_ mpp_global_field2D_c8_4d
02604 #define MPP_GLOBAL_FIELD_5D_ mpp_global_field2D_c8_5d
02605 #define MPP_GLOBAL1D_FIELD_2D_ mpp_global_field1D_c8_2d
02606 #define MPP_TYPE_ complex(DOUBLE_KIND)
02607 #include <mpp_global_field.h>
02608 
02609 #ifndef no_8byte_integers
02610 #define MPP_GLOBAL_FIELD_2D_ mpp_global_field2D_i8_2d
02611 #define MPP_GLOBAL_FIELD_3D_ mpp_global_field2D_i8_3d
02612 #define MPP_GLOBAL_FIELD_4D_ mpp_global_field2D_i8_4d
02613 #define MPP_GLOBAL_FIELD_5D_ mpp_global_field2D_i8_5d
02614 #define MPP_GLOBAL1D_FIELD_2D_ mpp_global_field1D_i8_2d
02615 #define MPP_TYPE_ integer(LONG_KIND)
02616 #include <mpp_global_field.h>
02617 
02618 #define MPP_GLOBAL_FIELD_2D_ mpp_global_field2D_l8_2d
02619 #define MPP_GLOBAL_FIELD_3D_ mpp_global_field2D_l8_3d
02620 #define MPP_GLOBAL_FIELD_4D_ mpp_global_field2D_l8_4d
02621 #define MPP_GLOBAL_FIELD_5D_ mpp_global_field2D_l8_5d
02622 #define MPP_GLOBAL1D_FIELD_2D_ mpp_global_field1D_l8_2d
02623 #define MPP_TYPE_ logical(LONG_KIND)
02624 #include <mpp_global_field.h>
02625 #endif
02626 
02627 #ifndef no_4byte_reals
02628 #define MPP_GLOBAL_FIELD_2D_ mpp_global_field2D_r4_2d
02629 #define MPP_GLOBAL_FIELD_3D_ mpp_global_field2D_r4_3d
02630 #define MPP_GLOBAL_FIELD_4D_ mpp_global_field2D_r4_4d
02631 #define MPP_GLOBAL_FIELD_5D_ mpp_global_field2D_r4_5d
02632 #define MPP_GLOBAL1D_FIELD_2D_ mpp_global_field1D_r4_2d
02633 #define MPP_TYPE_ real(FLOAT_KIND)
02634 #include <mpp_global_field.h>
02635 #endif
02636 
02637 #ifndef no_4byte_cmplx
02638 #define MPP_GLOBAL_FIELD_2D_ mpp_global_field2D_c4_2d
02639 #define MPP_GLOBAL_FIELD_3D_ mpp_global_field2D_c4_3d
02640 #define MPP_GLOBAL_FIELD_4D_ mpp_global_field2D_c4_4d
02641 #define MPP_GLOBAL_FIELD_5D_ mpp_global_field2D_c4_5d
02642 #define MPP_GLOBAL1D_FIELD_2D_ mpp_global_field1D_c4_2d
02643 #define MPP_TYPE_ complex(FLOAT_KIND)
02644 #include <mpp_global_field.h>
02645 #endif
02646 
02647 #define MPP_GLOBAL_FIELD_2D_ mpp_global_field2D_i4_2d
02648 #define MPP_GLOBAL_FIELD_3D_ mpp_global_field2D_i4_3d
02649 #define MPP_GLOBAL_FIELD_4D_ mpp_global_field2D_i4_4d
02650 #define MPP_GLOBAL_FIELD_5D_ mpp_global_field2D_i4_5d
02651 #define MPP_GLOBAL1D_FIELD_2D_ mpp_global_field1D_i4_2d
02652 #define MPP_TYPE_ integer(INT_KIND)
02653 #include <mpp_global_field.h>
02654 
02655 #define MPP_GLOBAL_FIELD_2D_ mpp_global_field2D_l4_2d
02656 #define MPP_GLOBAL_FIELD_3D_ mpp_global_field2D_l4_3d
02657 #define MPP_GLOBAL_FIELD_4D_ mpp_global_field2D_l4_4d
02658 #define MPP_GLOBAL_FIELD_5D_ mpp_global_field2D_l4_5d
02659 #define MPP_GLOBAL1D_FIELD_2D_ mpp_global_field1D_l4_2d
02660 #define MPP_TYPE_ logical(INT_KIND)
02661 #include <mpp_global_field.h>
02662 
02663 end module mpp_domains_mod_oa
02664 
02665 #endif
02666 

Generated on 18 Mar 2011 for Oasis4 by  doxygen 1.6.1