Oasis3-MCT
mod_oasis_part.F90
Go to the documentation of this file.
1 
2 !> OASIS partition data and methods
3 
5 
9  USE mod_oasis_sys
10  USE mod_oasis_mpi
11  USE mod_oasis_timer
12  USE mct_mod
13 
14  implicit none
15 
16  private
17 
18  !--- interfaces ---
19  public :: oasis_def_partition
20  public :: oasis_part_setup
21  public :: oasis_part_create
22 
23  !--- datatypes ---
24  public :: prism_part_type
25 
26  integer(kind=ip_intwp_p),parameter :: mpart = 100 !< maximum number of partitions allowed
27 
28  !> Partition (decomposition) data for variables
30  character(len=ic_lvar2):: partname !< partition name
31  type(mct_gsmap) :: gsmap !< gsmap on mpi_comm_local
32  integer(kind=ip_i4_p) :: gsize !< global size of grid
33  integer(kind=ip_i4_p) :: lsize !< local size of grid
34  integer(kind=ip_i4_p) :: nx !< global nx size
35  integer(kind=ip_i4_p) :: ny !< global ny size
36  character(len=ic_lvar) :: gridname !< grid name
37  integer(kind=ip_i4_p) :: mpicom !< mpicom for partition tasks only
38  integer(kind=ip_i4_p) :: npes !< tasks count associated with partition
39  integer(kind=ip_i4_p) :: rank !< rank of each task
40  type(mct_gsmap) :: pgsmap !< same gsmap but on partition mpicom
41  !--- temporary storage from def_part inputs ---
42  integer(kind=ip_i4_p) :: ig_size !< def_part setting
43  integer(kind=ip_i4_p),pointer :: kparal(:) !< def_part setting
44  end type prism_part_type
45 
46  integer(kind=ip_intwp_p),public :: prism_npart = 0 !< number of partitions defined
47  type(prism_part_type) ,public :: prism_part(mpart) !< list of defined partitions
48 
49  !--- for automatic naming of partname
50  !--- better than prism_npart, counts only unnamed parts
51  integer(kind=ip_intwp_p) :: part_name_cnt = 0 !< used to define partition names internally
52 
53 CONTAINS
54 
55 !--------------------------------------------------------------------
56 
57 !> The OASIS user interface to define partitions
58 
59  SUBROUTINE oasis_def_partition (id_part, kparal, kinfo, ig_size, name)
60 
61 !* *** Def_partition *** PRISM 1.0
62 !
63 ! purpose:
64 ! --------
65 ! define a decomposition
66 !
67 ! interface:
68 ! ----------
69 ! id_part : field decomposition id
70 ! kparal : type of parallel decomposition
71 ! kinfo : output status
72 !
73 ! author:
74 ! -------
75 ! Arnaud Caubel - FECIT
76 !
77 ! ----------------------------------------------------------------
78  INTEGER(kind=ip_intwp_p) ,intent(out) :: id_part !< partition id
79  INTEGER(kind=ip_intwp_p), DIMENSION(:),intent(in) :: kparal !< decomposition information
80  INTEGER(kind=ip_intwp_p), optional ,intent(out) :: kinfo !< return code
81  INTEGER(kind=ip_intwp_p), optional ,intent(in) :: ig_size !< total size of partition
82  character(len=*) , optional ,intent(in) :: name !< name of partition
83 ! ----------------------------------------------------------------
84  integer(kind=ip_intwp_p) :: n
85  character(len=*),parameter :: subname = '(oasis_def_partition)'
86 ! ----------------------------------------------------------------
87 
88  call oasis_debug_enter(subname)
89 
90  if (.not. oasis_coupled) then
91  call oasis_debug_exit(subname)
92  return
93  endif
94 
95  kinfo = oasis_ok
96 
97  !-----------------------------------------------
98  !> * Increment partition number and store user values
99  !-----------------------------------------------
100 
101  call oasis_timer_start('part_definition')
102 
104  if (prism_npart > mpart) then
105  write(nulprt,*) subname,estr,'prism_npart too large = ',prism_npart,mpart
106  write(nulprt,*) subname,estr,'increase mpart in mod_oasis_part.F90'
107  call oasis_abort(file=__file__,line=__line__)
108  endif
110  id_part = prism_npart
111 
112  if (present(name)) then
113  if (len_trim(name) > len(prism_part(prism_npart)%partname)) then
114  write(nulprt,*) subname,estr,'part name too long = ',trim(name)
115  write(nulprt,*) subname,estr,'part name max length = ',len(prism_part(prism_npart)%partname)
116  call oasis_abort(file=__file__,line=__line__)
117  endif
118  prism_part(prism_npart)%partname = trim(name)
119  else
121  write(prism_part(prism_npart)%partname,'(a,i6.6)') trim(compnm)//'_part',part_name_cnt
122  endif
123 
124  if (present(ig_size)) then
125  prism_part(prism_npart)%ig_size = ig_size
126  endif
127 
128  allocate(prism_part(prism_npart)%kparal(size(kparal)))
129  prism_part(prism_npart)%kparal = kparal
130 
131  call oasis_timer_stop('part_definition')
132 
133  call oasis_debug_exit(subname)
134 
135  END SUBROUTINE oasis_def_partition
136 
137 !------------------------------------------------------------
138 
139 !> Synchronize partitions across all tasks, called at oasis enddef.
140 
141  SUBROUTINE oasis_part_setup()
142  IMPLICIT NONE
143 
144  !--------------------------------------------------------
145  integer(kind=ip_intwp_p) :: m,n,k,p,nsegs,numel,taskid
146  INTEGER(kind=ip_intwp_p) :: icpl,ierr,ilen
147  integer(kind=ip_intwp_p),pointer :: start(:),length(:)
148  integer(kind=ip_intwp_p),pointer :: kparal(:)
149  integer(kind=ip_intwp_p) :: ig_size
150  integer(kind=ip_intwp_p) :: pcnt
151  logical :: found
152  character(len=ic_lvar2), pointer :: pname0(:),pname(:)
153  logical, parameter :: local_timers_on = .false.
154  character(len=*),parameter :: subname = '(oasis_part_setup)'
155  !--------------------------------------------------------
156 
157  call oasis_debug_enter(subname)
158 
159  if (local_timers_on) then
160  call oasis_timer_start('part_setup_barrier')
161  if (mpi_comm_local /= mpi_comm_null) &
162  call mpi_barrier(mpi_comm_local, ierr)
163  call oasis_timer_stop('part_setup_barrier')
164  endif
165  if (local_timers_on) call oasis_timer_start('part_setup')
166 
167  !-----------------------------------------------
168  !> * Generate reduced partname list
169  !-----------------------------------------------
170  IF (local_timers_on) CALL oasis_timer_start('part_setup_reducelists')
171  allocate(pname0(prism_npart))
172  do n = 1,prism_npart
173  pname0(n) = prism_part(n)%partname
174  enddo
175  call oasis_mpi_reducelists(pname0,mpi_comm_local,pcnt,pname,'part_setup',fastcheck=.true.)
176  deallocate(pname0)
177  IF (local_timers_on) CALL oasis_timer_stop('part_setup_reducelists')
178 
179  !-------------------------------------------------
180  !> * Define all partitions on all tasks
181  !-------------------------------------------------
182 
183  if (local_timers_on) then
184  call oasis_timer_start('part_setup_initgsm_barrier')
185  if (mpi_comm_local /= mpi_comm_null) &
186  call mpi_barrier(mpi_comm_local, ierr)
187  call oasis_timer_stop('part_setup_initgsm_barrier')
188  endif
189  IF (local_timers_on) CALL oasis_timer_start('part_setup_initgsm')
190  do p = 1,pcnt
191 
192  if (local_timers_on) call oasis_timer_start('part_setup_initgsm_A')
193  !--- set m, either a prism_part that already exists
194  found = .false.
195  n = 0
196  do while (n < prism_npart .and. .not.found)
197  n = n + 1
198  if (prism_part(n)%partname == pname(p)) then
199  m = n
200  found = .true.
201  endif
202  enddo
203  if (local_timers_on) call oasis_timer_stop('part_setup_initgsm_A')
204 
205  if (local_timers_on) call oasis_timer_start('part_setup_initgsm_B')
206  !--- or m is a new prism_part that must be instantiated
207  !--- and set to have no data
208  if (.not.found) then
210  m = prism_npart
212  prism_part(prism_npart)%partname = pname(p)
213  allocate(prism_part(prism_npart)%kparal(3))
214  prism_part(prism_npart)%kparal = 0
215  endif
216  if (local_timers_on) call oasis_timer_stop('part_setup_initgsm_B')
217 
218  !-------------------------------------------------
219  !> * Convert kparal information to data for the gsmap
220  !-------------------------------------------------
221 
222  if (local_timers_on) call oasis_timer_start('part_setup_initgsm_C')
223  allocate(kparal(size(prism_part(m)%kparal)))
224  kparal = prism_part(m)%kparal
225  ig_size = prism_part(m)%ig_size
226 
227  if (kparal(clim_strategy) == clim_serial) then
228  nsegs = 1
229  allocate(start(nsegs),length(nsegs))
230  start(1) = 1
231  length(1) = kparal(clim_length)
232  numel = nsegs
233  if (length(1) == 0) numel = 0
234  elseif (kparal(clim_strategy) == clim_apple) then
235  nsegs = 1
236  allocate(start(nsegs),length(nsegs))
237  start(1) = kparal(clim_offset) + 1
238  length(1) = kparal(clim_length)
239  numel = nsegs
240  if (length(1) == 0) numel = 0
241  elseif (kparal(clim_strategy) == clim_box) then
242  nsegs = kparal(clim_sizey)
243  allocate(start(nsegs),length(nsegs))
244  do n = 1,nsegs
245  start(n) = kparal(clim_offset) + (n-1)*kparal(clim_ldx) + 1
246  length(n) = kparal(clim_sizex)
247  enddo
248  numel = nsegs
249  if (kparal(clim_sizey)*kparal(clim_sizex) == 0) numel = 0
250  elseif (kparal(clim_strategy) == clim_orange) then
251  nsegs = kparal(clim_segments)
252  allocate(start(nsegs),length(nsegs))
253  numel = 0
254  DO n = 1,nsegs
255  ilen = kparal((n-1)*2 + 4)
256  IF (ilen > 0) THEN
257  numel = numel + 1
258  start(numel) = kparal((n-1)*2 + 3) + 1
259  length(numel) = ilen
260  ENDIF
261  ENDDO
262  elseif (kparal(clim_strategy) == clim_points) then
263  nsegs = kparal(clim_segments)
264  allocate(start(nsegs),length(nsegs))
265  !--- initialize first segment, nsegs=1,n=1,k=3
266  nsegs = 1
267  n = 1
268  k = n+2
269  start(nsegs) = kparal(k)
270  length(nsegs) = 1
271  !--- compute rest of segments from n=2,k=4
272  do n = 2,kparal(clim_segments)
273  k = n+2
274  if (kparal(k)-kparal(k-1) == 1) then
275  length(nsegs) = length(nsegs) + 1
276  else
277  nsegs = nsegs + 1
278  start(nsegs) = kparal(k)
279  length(nsegs) = 1
280  endif
281  enddo
282  numel = nsegs
283  else
284  write(nulprt,*) subname,estr,'part strategy unknown in def_part = ',kparal(clim_strategy)
285  write(nulprt,*) subname,estr,'strategy set in kparal array index ',clim_strategy
286  call oasis_abort(file=__file__,line=__line__)
287  endif
288 
289  IF (oasis_debug >= 30) THEN
290  WRITE(nulprt,*) subname, ' Nsegs before calling mct_gsmap_init :',nsegs
291  WRITE(nulprt,*) subname, ' Numel before calling mct_gsmap_init :',numel
292  CALL oasis_flush(nulprt)
293  ENDIF
294 
295  if (local_timers_on) call oasis_timer_stop('part_setup_initgsm_C')
296 
297  !-------------------------------------------------
298  !> * Initialize the local gsmap and partition gsmap
299  !-------------------------------------------------
300 
301  if (local_timers_on) call oasis_timer_start('part_setup_initgsm_D')
302  if (mpi_comm_local /= mpi_comm_null) then
303  if (ig_size > 0) then
304  call mct_gsmap_init(prism_part(m)%gsmap,start,length,mpi_root_local,&
305  mpi_comm_local,compid,numel=numel,gsize=ig_size)
306  else
307  call mct_gsmap_init(prism_part(m)%gsmap,start,length,mpi_root_local,&
308  mpi_comm_local,compid,numel=numel)
309  endif
310  prism_part(m)%gsize = mct_gsmap_gsize(prism_part(m)%gsmap)
311  prism_part(m)%lsize = mct_gsmap_lsize(prism_part(m)%gsmap,mpi_comm_local)
312  icpl = mpi_undefined
313  if (numel > 0) icpl = 1
314  CALL mpi_comm_split(mpi_comm_local,icpl,1,prism_part(m)%mpicom,ierr)
315  if (numel > 0) then
316  CALL mpi_comm_size ( prism_part(m)%mpicom, prism_part(m)%npes, ierr )
317  CALL mpi_comm_rank ( prism_part(m)%mpicom, prism_part(m)%rank, ierr )
318  if (ig_size > 0) then
319  call mct_gsmap_init(prism_part(m)%pgsmap,start,length,0, &
320  prism_part(m)%mpicom,compid,numel=numel,gsize=ig_size)
321  else
322  call mct_gsmap_init(prism_part(m)%pgsmap,start,length,0, &
323  prism_part(m)%mpicom,compid,numel=numel)
324  endif
325  else
326  ! override mpicom created by split with null
327  prism_part(m)%mpicom = mpi_comm_null
328  endif
329  !else
330  !! set by default
331  ! prism_part(m)%gsize = -1
332  ! prism_part(m)%mpicom = MPI_COMM_NULL
333  endif
334  if (local_timers_on) call oasis_timer_stop('part_setup_initgsm_D')
335 
336  if (local_timers_on) call oasis_timer_start('part_setup_initgsm_E')
337  deallocate(start,length)
338  deallocate(kparal)
339  deallocate(prism_part(m)%kparal)
340 
341  if (oasis_debug >= 2) then
342  call oasis_part_write(prism_part(m),m)
343  endif
344  if (local_timers_on) call oasis_timer_stop('part_setup_initgsm_E')
345 
346  enddo ! p = 1,pcnt
347 
348  deallocate(pname)
349 
350  if (local_timers_on) call oasis_timer_stop ('part_setup_initgsm')
351  if (local_timers_on) call oasis_timer_stop('part_setup')
352 
353  call oasis_debug_exit(subname)
354 
355  END SUBROUTINE oasis_part_setup
356 !------------------------------------------------------------
357 
358 !> Zero partition information
359 
360  SUBROUTINE oasis_part_zero(s_prism_part)
362  IMPLICIT NONE
363 
364  type(prism_part_type),intent(inout) :: s_prism_part
365  !--------------------------------------------------------
366  character(len=*),parameter :: subname = '(oasis_part_zero)'
367  !--------------------------------------------------------
368 
369  call oasis_debug_enter(subname)
370 
371  s_prism_part%partname = trim(cspval)
372  s_prism_part%gsize = -1
373  s_prism_part%lsize = -1
374  s_prism_part%nx = -1
375  s_prism_part%ny = -1
376  s_prism_part%gridname = trim(cspval)
377  s_prism_part%mpicom = mpi_comm_null
378  s_prism_part%npes = -1
379  s_prism_part%rank = -1
380  s_prism_part%ig_size = -1
381 
382  call oasis_debug_exit(subname)
383 
384  END SUBROUTINE oasis_part_zero
385 !------------------------------------------------------------
386 
387 !> Print parition information
388 
389  SUBROUTINE oasis_part_write(s_prism_part,npart)
391  IMPLICIT NONE
392 
393  type(prism_part_type),intent(in) :: s_prism_part
394  integer(ip_i4_p) ,intent(in) :: npart
395  !--------------------------------------------------------
396  character(len=*),parameter :: subname = '(oasis_part_write)'
397  !--------------------------------------------------------
398 
399  call oasis_debug_enter(subname)
400 
401  write(nulprt,*) ' '
402  write(nulprt,*) subname,' partnm = ',trim(s_prism_part%partname)
403  write(nulprt,*) subname,' npart = ',npart
404  write(nulprt,*) subname,' mpicom = ',s_prism_part%mpicom
405  write(nulprt,*) subname,' npes = ',s_prism_part%npes
406  write(nulprt,*) subname,' rank = ',s_prism_part%rank
407  write(nulprt,*) subname,' compid = ',s_prism_part%gsmap%comp_id
408  write(nulprt,*) subname,' ngseg = ',s_prism_part%gsmap%ngseg
409  write(nulprt,*) subname,' gsize = ',s_prism_part%gsmap%gsize
410  if (s_prism_part%gsmap%ngseg > 10) then
411  IF (mpi_comm_local /= mpi_comm_null) THEN
412  WRITE(nulprt,*) subname,' start = ',s_prism_part%gsmap%start(1:10)
413  WRITE(nulprt,*) subname,' length = ',s_prism_part%gsmap%length(1:10)
414  WRITE(nulprt,*) subname,' pe_loc = ',s_prism_part%gsmap%pe_loc(1:10)
415  ENDIF
416  IF (s_prism_part%mpicom /= mpi_comm_null) THEN
417  WRITE(nulprt,*) subname,' pstart = ',s_prism_part%pgsmap%start(1:10)
418  WRITE(nulprt,*) subname,' plength= ',s_prism_part%pgsmap%length(1:10)
419  WRITE(nulprt,*) subname,' ppe_loc= ',s_prism_part%pgsmap%pe_loc(1:10)
420  ENDIF
421  else
422  IF (mpi_comm_local /= mpi_comm_null) THEN
423  WRITE(nulprt,*) subname,' start = ',s_prism_part%gsmap%start
424  WRITE(nulprt,*) subname,' length = ',s_prism_part%gsmap%length
425  WRITE(nulprt,*) subname,' pe_loc = ',s_prism_part%gsmap%pe_loc
426  ENDIF
427  IF (s_prism_part%mpicom /= mpi_comm_null) THEN
428  WRITE(nulprt,*) subname,' pstart = ',s_prism_part%pgsmap%start
429  WRITE(nulprt,*) subname,' plength= ',s_prism_part%pgsmap%length
430  WRITE(nulprt,*) subname,' ppe_loc= ',s_prism_part%pgsmap%pe_loc
431  ENDIF
432  endif
433  write(nulprt,*) ' '
434  CALL oasis_flush(nulprt)
435 
436  call oasis_debug_exit(subname)
437 
438  END SUBROUTINE oasis_part_write
439 !------------------------------------------------------------
440 
441 !> Create a new partition internally, needed for mapping
442 
443  SUBROUTINE oasis_part_create(id_part,TYPE,gsize,nx,ny,gridname,gscomm,mpicom,gridID)
445  IMPLICIT NONE
446 
447  integer(ip_i4_p),intent(out) :: id_part !< partition id
448  character(len=*),intent(in) :: type !< type of decomposition specified
449  integer(ip_i4_p),intent(in) :: gsize !< global size of grid
450  integer(ip_i4_p),intent(in) :: nx !< global nx size
451  integer(ip_i4_p),intent(in) :: ny !< global ny size
452  character(len=*),intent(in) :: gridname !< grid name
453  integer(ip_i4_p),intent(in) :: gscomm !< global seg map communicator
454  integer(ip_i4_p),intent(in) :: mpicom !< local mpi comm
455  integer(ip_i4_p), optional :: gridID(:)!< gridcell ID
456  !--------------------------------------------------------
457  integer(ip_i4_p) :: gsrank
458  integer(ip_i4_p) :: gssize
459  integer(ip_i4_p) :: numel
460  integer(ip_i4_p),pointer :: start(:),length(:)
461  integer(ip_i4_p),pointer :: llist(:),glist(:)
462  integer(ip_i4_p) :: pts
463  integer(ip_i4_p) :: found,foundall
464  integer(ip_i4_p) :: n
465  integer(ip_i4_p) :: ierr
466  character(len=*),parameter :: subname = '(oasis_part_create)'
467  !--------------------------------------------------------
468 
469  call oasis_debug_enter(subname)
470 
471  if (gscomm /= mpi_comm_null) then
472  call mpi_comm_rank(gscomm,gsrank,ierr)
473  call mpi_comm_size(gscomm,gssize,ierr)
474  else
475  gsrank = -1
476  gssize = -1
477  endif
478 
479  if (oasis_debug >= 15) then
480  write(nulprt,*) subname,' called with ',gsize,nx,ny,trim(gridname)
481  write(nulprt,*) subname,' local ',gsrank,gssize
482  endif
483 
484  if ((type == 'decomp_wghtfile' .and. .not.present(gridid)) .or. &
485  (type /= 'decomp_wghtfile' .and. present(gridid))) then
486  write(nulprt,*) subname,estr,'decomp_wghtfile and gridID arguments inconsistent ',trim(type)
487  call oasis_abort(file=__file__,line=__line__)
488  endif
489 
490  !-----------------------------------------------
491  !> * Check if an existing gsmap can be reused
492  !-----------------------------------------------
493 
494  id_part = -1
495  found = 0
496  n = 0
497  do while (found == 0 .and. n < prism_npart)
498  n = n + 1
499  if (prism_part(n)%gsize == gsize .and. &
500  trim(prism_part(n)%gridname) == trim(gridname) .and. &
501  prism_part(n)%mpicom == gscomm .and. &
502  prism_part(n)%nx == nx .and. &
503  prism_part(n)%ny == ny) then
504  id_part = n
505  found = 1
506  endif
507  enddo
508 
509  !-----------------------------------------------
510  !> * Check that all tasks agree and if so, return with that partition id
511  !-----------------------------------------------
512 
513  foundall = -1
514  call oasis_mpi_min(found,foundall,mpicom,string=subname//' found',all=.true.)
515  if (foundall == 1) then
516  if (oasis_debug >= 2) then
517  write(nulprt,*) subname,' reuse part ',prism_npart,gsize
518  endif
519  call oasis_debug_exit(subname)
520  return
521  endif
522 
523  !-----------------------------------------------
524  !> * Instantiate a decomposition based on gsize and type
525  !-----------------------------------------------
526 
529 
530  !-----------------------------------------------
531  !> * Create a new partition and set values
532  !-----------------------------------------------
533 
535  write(prism_part(prism_npart)%partname,'(a,i6.6)') trim(compnm)//'_part',part_name_cnt
536  prism_part(prism_npart)%gsize = gsize
537  prism_part(prism_npart)%nx = nx
538  prism_part(prism_npart)%ny = ny
539  prism_part(prism_npart)%gridname = trim(gridname)
540  prism_part(prism_npart)%mpicom = gscomm
541  prism_part(prism_npart)%npes = gssize
542  prism_part(prism_npart)%rank = gsrank
543 
544  allocate(start(1),length(1))
545  start = 1
546  length = 0
547  numel = 0
548 
549  if (trim(type) == 'decomp_1d') then
550  pts = 0
551  if (gsrank >= 0) then
552  numel = 1
553  length(1) = gsize/gssize
554  pts = gsize - length(1)*gssize
555  if (gsrank < pts) length(1) = length(1) + 1
556  start(1) = gsize/gssize*(gsrank) + min(gsrank,pts) + 1
557  endif
558 
559  if (oasis_debug >= 15) then
560  write(nulprt,*) subname,trim(type),numel,start,length,pts
561  endif
562 
563  elseif (trim(type) == 'decomp_wghtfile') then
564  allocate(llist(gsize),glist(gsize))
565  llist = -1
566  numel = 0
567  if (gsrank >= 0) then
568  if (oasis_debug >= 15) then
569  write(nulprt,*) subname,' wgts1 ',size(gridid)
570  write(nulprt,*) subname,' gridID ',minval(gridid),maxval(gridid)
571  endif
572  do n = 1,size(gridid)
573  if (gridid(n) > 0 .and. gridid(n) <= gsize) then
574  numel = numel + 1
575  llist(gridid(n)) = gsrank
576 ! elseif (gridID(n) > gsize) then
577 ! tcraig, allow > gsize and ignore it, errors trapped/ignored in map read
578 ! write(nulprt,*) subname,estr,'gridID > gsize',gridID(n),gsize
579 ! call oasis_abort(file=__FILE__,line=__LINE__)
580 ! else
581 ! tcraig, allow <= 0 and ignore it, errors trapped/ignored in map read
582 ! write(nulprt,*) subname,estr,'gridID <= 0',gridID(n),gsize
583 ! call oasis_abort(file=__FILE__,line=__LINE__)
584  endif
585  enddo
586 
587  ! this computes the max MPI rank that includes the gridcell
588  ! max is arbitrary but this forces each gridcell to be associated with just one rank
589  call oasis_mpi_max(llist,glist,gscomm,string=trim(subname)//' glist',all=.true.)
590 
591  deallocate(llist)
592  deallocate(start,length)
593  allocate(start(numel),length(numel))
594  start = -1
595  length = -1
596  numel = 0
597  do n = 1,gsize
598  if (glist(n) == gsrank) then
599  numel = numel + 1
600  if (numel > size(gridid)) then
601  write(nulprt,*) subname,estr,'numel error ',numel,size(gridid)
602  call oasis_abort(file=__file__,line=__line__)
603  endif
604  start(numel) = n
605  length(numel) = 1
606  endif
607  enddo
608  deallocate(glist)
609  endif ! gsrank >= 0
610 
611  if (oasis_debug >= 15) then
612  write(nulprt,*) subname,trim(type),numel
613  call oasis_flush(nulprt)
614  endif
615 
616  else
617  write(nulprt,*) subname,estr,'type argument unknown = ',trim(type)
618  call oasis_abort(file=__file__,line=__line__)
619  endif
620 
621  !-----------------------------------------------
622  !> * Initialize the partition gsmap and pgsmap
623  !-----------------------------------------------
624 
625  call mct_gsmap_init(prism_part(prism_npart)%gsmap,start,length,0,mpicom,compid,gsize=gsize,numel=numel)
626  if (gsrank >= 0) then
627  call mct_gsmap_init(prism_part(prism_npart)%pgsmap,start,length,0, &
628  prism_part(prism_npart)%mpicom,compid,gsize=gsize,numel=numel)
629  endif
630  deallocate(start,length)
631  if (oasis_debug >= 2) then
632  write(nulprt,*) subname,' create new part ',prism_npart,gsize
634  endif
635 
636  id_part = prism_npart
637 
638  call oasis_debug_exit(subname)
639 
640 END SUBROUTINE oasis_part_create
641 !------------------------------------------------------------
642 
643 END MODULE mod_oasis_part
integer(kind=ip_intwp_p), parameter clim_box
integer(kind=ip_intwp_p), parameter clim_sizex
System type methods.
Provides a common location for several OASIS variables.
integer(kind=ip_intwp_p), parameter clim_offset
integer(kind=ip_intwp_p), parameter oasis_ok
subroutine, public oasis_part_create(id_part, TYPE, gsize, nx, ny, gridname, gscomm, mpicom, gridID)
Create a new partition internally, needed for mapping.
Generic overloaded interface into MPI max reduction.
type(prism_part_type), dimension(mpart), public prism_part
list of defined partitions
integer(kind=ip_intwp_p) nulprt
subroutine oasis_part_write(s_prism_part, npart)
Print parition information.
subroutine, public oasis_abort(id_compid, cd_routine, cd_message, file, line, rcode)
OASIS abort method, publically available to users.
subroutine, public oasis_def_partition(id_part, kparal, kinfo, ig_size, name)
The OASIS user interface to define partitions.
integer(kind=ip_i4_p) compid
character(len= *), parameter cspval
integer(kind=ip_intwp_p) part_name_cnt
used to define partition names internally
Defines kinds for OASIS.
integer(kind=ip_intwp_p), parameter clim_orange
Provides a generic and simpler interface into MPI calls for OASIS.
integer(kind=ip_intwp_p), parameter clim_points
integer(kind=ip_intwp_p), parameter mpart
maximum number of partitions allowed
integer(kind=ip_i4_p) mpi_root_local
subroutine, public oasis_debug_enter(string)
Used when a subroutine is entered, write info to log file at some debug level.
Generic overloaded interface into MPI min reduction.
subroutine, public oasis_mpi_reducelists(linp1, comm, cntout, lout1, callstr, fastcheck, fastcheckout, linp2, lout2, spval2, linp3, lout3, spval3, linp4, lout4, spval4)
Custom method for reducing MPI lists across pes for OASIS.
OASIS partition data and methods.
integer(kind=ip_intwp_p), parameter clim_strategy
Defines parameters for OASIS.
character(len=ic_lvar) compnm
subroutine, public oasis_timer_start(timer_label, barrier)
Start a timer.
integer(kind=ip_i4_p) oasis_debug
subroutine, public oasis_timer_stop(timer_label)
Stop a timer.
character(len= *), parameter, public estr
integer(kind=ip_i4_p) mpi_comm_local
integer(kind=ip_intwp_p), parameter clim_ldx
subroutine, public oasis_part_setup()
Synchronize partitions across all tasks, called at oasis enddef.
integer(kind=ip_intwp_p), parameter clim_sizey
integer(kind=ip_intwp_p), parameter clim_segments
integer(kind=ip_intwp_p), parameter clim_serial
integer(kind=ip_intwp_p), public prism_npart
number of partitions defined
integer(kind=ip_intwp_p), parameter clim_apple
subroutine, public oasis_flush(nu)
Flushes output to file.
Performance timer methods.
integer(kind=ip_intwp_p), parameter clim_length
subroutine oasis_part_zero(s_prism_part)
Zero partition information.
subroutine, public oasis_debug_exit(string)
Used when a subroutine is exited, write info to log file at some debug level.
Partition (decomposition) data for variables.