Oasis3-MCT
mod_oasis_coupler.F90
Go to the documentation of this file.
1 
2 !> Initialize the OASIS coupler infrastructure
3 
5 ! - - - - - - - - - - - - - - - - - - - - - - - - - - -
6 !
11  USE mod_oasis_sys
12  USE mod_oasis_map
13  USE mod_oasis_part
14  USE mod_oasis_var
15  USE mod_oasis_mpi
17  USE mod_oasis_io
18  USE mod_oasis_timer
19  USE mct_mod
20  USE grids ! scrip
21  USE netcdf
22 
23  IMPLICIT NONE
24 
25  private
26 
27  public oasis_coupler_setup
30 
31 ! Type of data
32 
33  public prism_router_type
34  public prism_coupler_type
35 
36 ! COUPLING INFO
37 
38  !> Router information for rearranging data on tasks
40  !--- fixed at initialization ---
41  type(mct_router) :: router !< router
42  end type prism_router_type
43 
44  integer(kind=ip_i4_p),public,parameter :: prism_coupler_avsmax=5 !< maximum number of higher order terms in mapping
45 
46  !> Coupler data for managing all aspects of coupling in OASIS
48  !--- fixed at initialization ---
49  type(mct_avect) :: avect1 !< primary aVect
50  type(mct_avect) :: avect1m !< extra aVect needed for mapping
51  type(mct_avect) :: avect2 !< higher order mapping data
52  type(mct_avect) :: avect3 !< higher order mapping data
53  type(mct_avect) :: avect4 !< higher order mapping data
54  type(mct_avect) :: avect5 !< higher order mapping data
55  logical :: avon(prism_coupler_avsmax) !< flags indicating whether aVects 2-5 are active
56  character(len=ic_xl) :: rstfile !< restart file
57  logical :: writrest !< flag to write a restart file
58  character(len=ic_xl) :: inpfile !< input file if data is read
59  character(len=ic_xxl) :: fldlist !< field list
60  integer(kind=ip_i4_p) :: nflds !< number of fields
61  integer(kind=ip_i4_p),pointer :: varid(:) !< varid for each field
62  logical :: valid !< is this coupler valid
63  integer(kind=ip_i4_p) :: namid !< namcouple ID
64  integer(kind=ip_i4_p) :: partid !< local variable partition ID
65  integer(kind=ip_i4_p) :: rpartid !< router partition ID
66  integer(kind=ip_i4_p) :: routerid !< router ID
67  integer(kind=ip_i4_p) :: mapperid !< mapper ID
68  character(len=ic_med) :: maploc !< map location setting, src or dst
69  integer(kind=ip_i4_p) :: ops !< namcouple operation (ip_exported,...)
70  integer(kind=ip_i4_p) :: comp !< other model compid to couple
71  integer(kind=ip_i4_p) :: tag !< communcation tag
72  integer(kind=ip_i4_p) :: seq !< sequence number
73  integer(kind=ip_i4_p) :: dt !< coupling period (secs)
74  integer(kind=ip_i4_p) :: lag !< put lag positive is put sooner (secs)
75  integer(kind=ip_i4_p) :: maxtime !< max time for the coupler
76  integer(kind=ip_i4_p) :: trans !< transformation (ip_average,...)
77  integer(kind=ip_i4_p) :: conserv !< conserve operation (ip_cnone,ip_cglobal,...)
78  character(len=ic_med) :: consopt !< conserve option (bfb, opt)
79  integer(kind=ip_i4_p) :: getput !< get/put flag
80  logical :: sndrcv !< send recv flag
81  logical :: output !< output flag
82  logical :: input !< input flag
83  logical :: snddiag !< diagnose src fields as part of coupling
84  logical :: rcvdiag !< diagnose rcv fields as part of coupling
85  real(kind=ip_double_p):: sndmult !< send field multiplier term
86  real(kind=ip_double_p):: sndadd !< send field addition term
87  real(kind=ip_double_p):: rcvmult !< receive field multiplier term
88  real(kind=ip_double_p):: rcvadd !< receive field addition term
89  !--- time varying info ---
90  integer(kind=ip_i4_p) :: ltime !< time at last coupling
91  integer(kind=ip_i4_p) :: ctime !< time at last call
92  integer(kind=ip_i4_p),pointer :: avcnt(:) !< counter for averaging
93  integer(kind=ip_i4_p),pointer :: status(:) !< status of variables in coupler
94  end type prism_coupler_type
95 
96  integer(kind=ip_i4_p) :: prism_mrouter !< max routers
97  integer(kind=ip_i4_p) :: prism_nrouter = 0 !< router counter
98  type(prism_router_type) ,public, pointer:: prism_router(:) !< prism_router array
99 
100  integer(kind=ip_i4_p) ,public :: prism_mcoupler !< max couplers
101  type(prism_coupler_type),public, pointer :: prism_coupler_put(:) !< prism_coupler put array
102  type(prism_coupler_type),public, pointer :: prism_coupler_get(:) !< prism_coupler get array
103 
104  integer(kind=ip_i4_p) ,public :: lastseq !< last coupler sequence
105  integer(kind=ip_i4_p) ,public :: lastseqtime !< last coupler sequence time
106  logical ,public :: allow_no_restart !< flag to allow no restart files at startup
107 
108 !#include <netcdf.inc>
109 
110 !------------------------------------------------------------
111 CONTAINS
112 !------------------------------------------------------------
113 
114 !> Main routine to setup couplers
115 
116 !> This routine initializes all the coupler data based on the namcouple
117 !> inputs and the calls into the OASIS initialization interfaces from models.
118 !> It reconciles everything. This is called from oasis_enddef.
119 
120  SUBROUTINE oasis_coupler_setup()
122  !----------------------------------------------------------
123  ! This routine reconciles the coupling stuff
124  !----------------------------------------------------------
125 
126  IMPLICIT none
127 
128  integer(kind=ip_i4_p) :: n,n1,n2,nn,nv,nm,nv1,nv1a,nns,lnn,nc,nf,nvf,npc,r1,ierr
129  integer(kind=ip_i4_p) :: pe,nflds1,nflds2,ncnt
130  integer(kind=ip_i4_p) :: part1, part2
131  integer(kind=ip_i4_p) :: spart,dpart ! src, dst partitions for mapping
132  ! part1 = my local part, partID
133  ! part2 = other partition for mapping
134  ! spart = src part for mapping; put=part1, get=part2
135  ! dpart = dst part for mapping; put=part2, get=part1
136  integer(kind=ip_i4_p) :: mapID,namID
137  type(mct_smat),pointer :: sMati(:)
138  integer(kind=ip_i4_p) :: ncid,dimid,status
139  integer(kind=ip_i4_p) :: lsize,gsize
140  integer(kind=ip_i4_p) :: svarid
141  integer(kind=ip_i4_p),allocatable :: varidtmp(:)
142  integer(kind=ip_i4_p) :: part
143  integer(kind=ip_i4_p),pointer :: varid1(:)
144  character(len=ic_med) :: cstring,delim,vname,mapopt,mapopt1
145  character(len=ic_lvar):: myfld
146  integer(kind=ip_i4_p) :: myfldi
147  character(len=ic_xxl) :: myfldlist ! field list for my model
148  character(len=ic_lvar):: otfld
149  character(len=ic_xxl) :: otfldlist ! field list for other model
150  integer(kind=ip_i4_p) :: nx,ny
151  character(len=ic_lvar):: gridname
152  character(len=ic_long):: tmp_mapfile
153  integer(kind=ip_i4_p) :: flag
154  logical :: found, exists, found2
155  integer(kind=ip_i4_p) :: mynvar
156  integer(kind=ip_i4_p) :: nwgts, arrlen
157  character(len=ic_lvar):: tmpfld
158  type(prism_coupler_type),pointer :: pcpointer
159  type(prism_coupler_type),pointer :: pcpntpair
160  integer(kind=ip_i4_p) :: ifind,nfind
161  integer(kind=ip_i4_p) ,pointer :: gridID(:)
162  character(len=ic_lvar),pointer :: myvar(:)
163  integer(kind=ip_i4_p) ,pointer :: myops(:)
164  integer(kind=ip_i4_p) ,pointer :: mynum(:)
165  integer(kind=ip_i4_p) ,pointer :: nallvar(:)
166  character(len=ic_lvar),pointer :: allvar(:,:)
167  integer(kind=ip_i4_p) ,pointer :: allops(:,:)
168  integer(kind=ip_i4_p) ,pointer :: allnum(:,:)
169  integer(kind=ip_i4_p) ,pointer :: namsrc_checkused(:) ! 0 = not used
170  integer(kind=ip_i4_p) ,pointer :: namsrc_checkused_g(:) ! 0 = not used
171  type sortnamfld_type
172  integer(kind=ip_i4_p) :: num ! total number of namcouple fields
173  integer(kind=ip_i4_p) ,pointer :: namnum(:) ! namcouple number
174  integer(kind=ip_i4_p) ,pointer :: fldnum(:) ! namcouple field number in namcouple
175  character(len=ic_lvar),pointer :: fld(:) ! namcouple field name
176  end type sortnamfld_type
177  type(sortnamfld_type) :: sortnsrc
178  type(sortnamfld_type) :: sortndst
179  type sortvarfld_type
180  integer(kind=ip_i4_p) :: num ! total number of var fields
181  integer(kind=ip_i4_p) ,pointer :: modnum(:) ! model number
182  integer(kind=ip_i4_p) ,pointer :: varnum(:) ! var field number in model
183  character(len=ic_lvar),pointer :: fld(:) ! variable field name
184  end type sortvarfld_type
185  type(sortvarfld_type) :: sortvars
186  type(sortvarfld_type) :: sorttest
187  integer(kind=ip_i4_p) ,pointer :: sortkey(:)
188  character(len=ic_med) :: part2decomp ! decomp_1d or decomp_wghtfile
189  character(len=ic_med) :: smatread_method ! orig or ceg
190  integer, parameter :: local_timers_on = 0 ! 0=min, 1=few, 2=med, 3=max
191 
192  character(len=*),parameter :: subname = '(oasis_coupler_setup)'
193 
194  !----------------------------------------------------------
195 
196  call oasis_debug_enter(subname)
197 ! call oasis_mpi_barrier(mpi_comm_global)
198  IF (local_timers_on >= 1) then
199  call oasis_timer_start('cpl_setup_barrier')
200  call oasis_mpi_barrier(mpi_comm_global, 'cpl_setup')
201  call oasis_timer_stop('cpl_setup_barrier')
202  call oasis_timer_start('cpl_setup')
203  endif
204 
205  if (local_timers_on >= 2) call oasis_timer_start('cpl_setup_n1')
206 
207  part2decomp = nammapdec
208  smatread_method = nammatxrd
209  if (oasis_debug >= 2) then
210  write(nulprt,*) subname,' part2decomp = ',trim(part2decomp)
211  write(nulprt,*) subname,' smatread_method = ',trim(smatread_method)
212  endif
213 
214  !-----------------------------------------
215  !> * Allocate and zero prism_router, prism_mapper, prism_coupler based on nnamcpl
216  ! there cannot be more than that needed
217  !-----------------------------------------
218 
219  call oasis_debug_note(subname//' set defaults for datatypes')
220 
221  prism_mrouter = nnamcpl * 2 ! multiply by 2 for coupling to self
222  allocate(prism_router(prism_mrouter))
223  prism_nrouter = 0
224 
226  allocate(prism_mapper(prism_mmapper))
227  prism_nmapper = 0
228  prism_mapper(:)%nwgts = 0
229  prism_mapper(:)%file = ""
230  prism_mapper(:)%loc = ""
231  prism_mapper(:)%opt = ""
232  prism_mapper(:)%optval= ""
233  prism_mapper(:)%init = .false.
234  prism_mapper(:)%spart = ispval
235  prism_mapper(:)%dpart = ispval
236  prism_mapper(:)%AVred = .false.
237 
241 
242  do nc = 1,prism_mcoupler
243  do npc = 1,2
244  if (npc == 1) then
245  pcpointer => prism_coupler_put(nc)
246  pcpntpair => prism_coupler_get(nc)
247  endif
248  if (npc == 2) then
249  pcpointer => prism_coupler_get(nc)
250  pcpntpair => prism_coupler_put(nc)
251  endif
252  pcpointer%rstfile = ""
253  pcpointer%writrest= .false.
254  pcpointer%inpfile = ""
255  pcpointer%fldlist = ""
256  pcpointer%nflds = 0
257  pcpointer%namID = 0
258  pcpointer%valid = .false.
259 !tcx is this alloc pcpointer or prism_coupler_*
260  allocate(pcpointer%varid(1))
261  pcpointer%varid(:) = ispval
262  pcpointer%aVon(:) = .false.
263  pcpointer%ops = ispval
264  pcpointer%comp = ispval
265  pcpointer%routerID = ispval
266  pcpointer%mapperID = ispval
267  pcpointer%maploc = ""
268  pcpointer%tag = ispval
269  pcpointer%dt = ispval
270  pcpointer%lag = 0
271  pcpointer%maxtime = 0
272  pcpointer%getput = ispval
273  pcpointer%sndrcv = .false.
274  pcpointer%output = .false.
275  pcpointer%input = .false.
276  pcpointer%trans = ip_instant
277  pcpointer%conserv = ip_cnone
278  pcpointer%ltime = ispval
279  pcpointer%ctime = ispval
280  pcpointer%snddiag = .false.
281  pcpointer%rcvdiag = .false.
282  pcpointer%sndmult = 1.0_ip_double_p
283  pcpointer%sndadd = 0.0_ip_double_p
284  pcpointer%rcvmult = 1.0_ip_double_p
285  pcpointer%rcvadd = 0.0_ip_double_p
286  enddo ! npc
287  enddo ! nc
288 
289  lastseq = ispval
291 
292  !----------------------------------------------------------
293  !> * Generate model variable lists across all models based on def_var calls.
294  !> These will be reconciled with the namcouple input. These are sorted
295  !> to improve search performance later.
296  !----------------------------------------------------------
297 
298  call oasis_debug_note(subname//' share var info between models')
299 
300  allocate(allvar(maxvar,prism_amodels))
301  allocate(nallvar(prism_amodels))
302  allocate(allops(maxvar,prism_amodels))
303  allocate(allnum(maxvar,prism_amodels))
304  allocate(myvar(maxvar))
305  allocate(myops(maxvar))
306  allocate(mynum(maxvar))
307 
308  allvar = " "
309  nallvar = 0
310  allops = -1
311  allnum = -1
312  if (local_timers_on >= 3) call oasis_timer_start('cpl_setup_n1_bcast')
313  do n = 1,prism_amodels
314  if (n == compid) then
315  myvar = " "
316  myops = 0
317  mynum = 0
318  mynvar = prism_nvar
319  do n1 = 1, prism_nvar
320  myvar(n1) = trim(prism_var(n1)%name)
321  myops(n1) = prism_var(n1)%ops
322  mynum(n1) = prism_var(n1)%num
323  ! check that each var name is unique for a given model
324  do n2 = 1,n1-1
325  if (myvar(n1) == myvar(n2)) then
326  WRITE(nulprt,*) subname,estr,'variable name defined more than once by def_var = ',trim(myvar(n1))
327  call oasis_abort(file=__file__,line=__line__)
328  endif
329  enddo
330  enddo
331  endif
332  if (oasis_debug >= 5) then
333  write(nulprt,*) subname,' BCAST from ',n,mpi_root_global(n)
334  call oasis_flush(nulprt)
335  endif
336  call oasis_mpi_bcast(mynvar,mpi_comm_global,'mynvar',mpi_root_global(n))
337  if (oasis_debug >= 5) then
338  write(nulprt,*) subname,' bcast mynvar ',mynvar
339  call oasis_flush(nulprt)
340  endif
341  nallvar(n) = mynvar
342  call oasis_mpi_bcast(myvar,mpi_comm_global,'myvar',mpi_root_global(n))
343  if (oasis_debug >= 5) then
344  write(nulprt,*) subname,' bcast myvar ',trim(myvar(1))
345  call oasis_flush(nulprt)
346  endif
347  allvar(:,n) = myvar(:)
348  call oasis_mpi_bcast(myops,mpi_comm_global,'myops',mpi_root_global(n))
349  if (oasis_debug >= 5) then
350  write(nulprt,*) subname,' bcast myops ',myops(1)
351  call oasis_flush(nulprt)
352  endif
353  allops(:,n) = myops(:)
354  call oasis_mpi_bcast(mynum,mpi_comm_global,'mynum',mpi_root_global(n))
355  if (oasis_debug >= 5) then
356  write(nulprt,*) subname,' bcast mynum ',mynum(1)
357  call oasis_flush(nulprt)
358  endif
359  allnum(:,n) = mynum(:)
360  enddo
361  if (local_timers_on >= 3) call oasis_timer_stop('cpl_setup_n1_bcast')
362 
363  deallocate(myvar,myops)
364 
365  if (oasis_debug >= 2) then
366  write(nulprt,*) subname,' model variable info:'
367  do nm = 1,prism_amodels
368  write(nulprt,'(8x,a,2i6)') ' model,nvars = ',nm,nallvar(nm)
369  do nv = 1,nallvar(nm)
370  cstring = 'unknown'
371  if (allops(nv,nm) == oasis_out) cstring = 'prism_out'
372  if (allops(nv,nm) == oasis_in) cstring = 'prism_in'
373  write(nulprt,'(16x,a,2i6,2x,a,2i6,2x,a)') ' model,idx,var,num,ops = ',nm,nv,&
374  trim(allvar(nv,nm)),allnum(nv,nm),allops(nv,nm),trim(cstring)
375  enddo
376  enddo
377  write(nulprt,*) ' '
378  call oasis_flush(nulprt)
379  endif
380 
381  ! generate sortvars sorted list
382 
383  n1 = 0
384  do n = 1,prism_amodels
385  n1 = n1 + nallvar(n)
386  enddo
387  allocate(sortvars%fld(n1))
388  allocate(sortvars%modnum(n1))
389  allocate(sortvars%varnum(n1))
390  allocate(sortkey(n1))
391  sortvars%num = n1
392 
393  n1 = 0
394  do n = 1,prism_amodels
395  do n2 = 1,nallvar(n)
396  n1 = n1 + 1
397  sortkey(n1) = n1
398  sortvars%fld(n1) = allvar(n2,n)
399  sortvars%modnum(n1) = n
400  sortvars%varnum(n1) = n2
401  enddo
402  enddo
403 
404  call oasis_sys_sortc(sortvars%num, sortvars%fld, sortkey)
405  call oasis_sys_sortikey(sortvars%num, sortvars%modnum, sortkey)
406  call oasis_sys_sortikey(sortvars%num, sortvars%varnum, sortkey)
407 
408  if (oasis_debug >= 15) then
409  write(nulprt,*) subname//' Sorted array : sortvars'
410  do n1 = 1,sortvars%num
411  write(nulprt,*) subname,'sort sortvars',n1,sortkey(n1),sortvars%modnum(n1),sortvars%varnum(n1),trim(sortvars%fld(n1))
412  enddo
413  endif
414 
415  deallocate(sortkey)
416 
417  !----------------------------------------------------------
418  !> * Setup couplers based on namcouple and model variable info.
419  ! These must be paired up consistently, create couplers in
420  ! sorted order (nns)
421  ! nn = namcpl counter, sorted
422  ! nm = model counter, compid is my nm
423  ! nv = variable counter
424  ! nv1 = my variable counter
425  !----------------------------------------------------------
426 
427  if (local_timers_on >= 2) call oasis_timer_stop ('cpl_setup_n1')
428 
429  !--------------------------------
430  !> * Preprocess namcouple strings and sort for faster searches
431  !--------------------------------
432 
433  ! count namcouple field names
434 
435  if (local_timers_on >= 2) call oasis_timer_start('cpl_setup_n2')
436  n1 = 0
437  n2 = 0
438  do nn = 1,nnamcpl
439  n1 = n1 + oasis_string_listgetnum(namsrcfld(nn))
440  n2 = n2 + oasis_string_listgetnum(namdstfld(nn))
441  if (n1 /= n2) then
442  WRITE(nulprt,*) subname,estr,'number of fields in namcouple inconsistent ',nn,n1,n2
443  WRITE(nulprt,*) subname,estr,'namcouple src fields = ',trim(namsrcfld(nn))
444  WRITE(nulprt,*) subname,estr,'namcouple dst fields = ',trim(namdstfld(nn))
445  call oasis_abort(file=__file__,line=__line__)
446  endif
447  enddo
448 
449  ! allocate space
450  ! note: n2==n1
451 
452  sortnsrc%num = n1
453  allocate(sortnsrc%fld(n1))
454  allocate(sortnsrc%namnum(n1))
455  allocate(sortnsrc%fldnum(n1))
456  sortndst%num = n2
457  allocate(sortndst%fld(n2))
458  allocate(sortndst%namnum(n2))
459  allocate(sortndst%fldnum(n2))
460 
461  ! this will check that all namcouple vars are used in application
462  allocate(namsrc_checkused(sortnsrc%num))
463  namsrc_checkused = 0
464 
465  ! fill and sort sortnsrc
466 
467  allocate(sortkey(sortnsrc%num))
468  n1 = 0
469  do nn = 1,nnamcpl
470  do n2 = 1,oasis_string_listgetnum(namsrcfld(nn))
471  n1 = n1 + 1
472  sortkey(n1) = n1
473  sortnsrc%namnum(n1) = nn
474  sortnsrc%fldnum(n1) = n2
475  call oasis_string_listgetname(namsrcfld(nn),n2,sortnsrc%fld(n1))
476  enddo
477  enddo
478 
479  call oasis_sys_sortc(sortnsrc%num, sortnsrc%fld, sortkey)
480  call oasis_sys_sortikey(sortnsrc%num, sortnsrc%namnum, sortkey)
481  call oasis_sys_sortikey(sortnsrc%num, sortnsrc%fldnum, sortkey)
482 
483  if (oasis_debug >= 15) then
484  write(nulprt,*) subname//' Sorted array : sortnsrc'
485  do n1 = 1,sortnsrc%num
486  write(nulprt,*) subname,'sort sortnsrc',n1,sortkey(n1), &
487  sortnsrc%namnum(n1),sortnsrc%fldnum(n1),trim(sortnsrc%fld(n1))
488  enddo
489  endif
490  deallocate(sortkey)
491 
492  ! fill and sort sortndst
493 
494  allocate(sortkey(sortndst%num))
495  n1 = 0
496  do nn = 1,nnamcpl
497  do n2 = 1,oasis_string_listgetnum(namdstfld(nn))
498  n1 = n1 + 1
499  sortkey(n1) = n1
500  sortndst%namnum(n1) = nn
501  sortndst%fldnum(n1) = n2
502  call oasis_string_listgetname(namdstfld(nn),n2,sortndst%fld(n1))
503  enddo
504  enddo
505 
506  call oasis_sys_sortc(sortndst%num, sortndst%fld, sortkey)
507  call oasis_sys_sortikey(sortndst%num, sortndst%namnum, sortkey)
508  call oasis_sys_sortikey(sortndst%num, sortndst%fldnum, sortkey)
509 
510  if (oasis_debug >= 15) then
511  write(nulprt,*) subname//' Sorted array : sortndst'
512  do n1 = 1,sortndst%num
513  write(nulprt,*) subname,'sort sortndst',n1,sortkey(n1), &
514  sortndst%namnum(n1),sortndst%fldnum(n1),trim(sortndst%fld(n1))
515  enddo
516  endif
517  deallocate(sortkey)
518 
519  !==========================================================
520  ! Test Sort Code
521  !==========================================================
522  if (oasis_debug >= 1500) then
523 
524  write(nulprt,*) subname,' Test sort code: '
525 
526  n1 = 10
527  allocate(sorttest%fld(n1))
528  allocate(sorttest%modnum(n1))
529  allocate(sorttest%varnum(n1))
530  allocate(sortkey(n1))
531  sorttest%num = n1
532 
533  sorttest%fld(:) = 'A'
534  do n1 = 1,sorttest%num
535  sortkey(n1) = n1
536  if (n1 == 1) sorttest%fld(n1) = 'D'
537  if (n1 == 2) sorttest%fld(n1) = 'C'
538  if (n1 == 4) sorttest%fld(n1) = 'C'
539  if (n1 == 5) sorttest%fld(n1) = 'D'
540  if (n1 == 8) sorttest%fld(n1) = 'C'
541  if (n1 == 9) sorttest%fld(n1) = 'B'
542  if (n1 == 10) sorttest%fld(n1) = 'C'
543  sorttest%modnum(n1) = n1+100
544  sorttest%varnum(n1) = n1
545  enddo
546 
547  call oasis_sys_sortc(sorttest%num, sorttest%fld, sortkey)
548  call oasis_sys_sortikey(sorttest%num, sorttest%modnum, sortkey)
549  call oasis_sys_sortikey(sorttest%num, sorttest%varnum, sortkey)
550 
551  write(nulprt,*) subname//' Sorted array : sorttest'
552  do n1 = 1,sorttest%num
553  write(nulprt,*) subname,'sort sorttest',n1,sortkey(n1), &
554  sorttest%modnum(n1),sorttest%varnum(n1),trim(sorttest%fld(n1))
555  enddo
556 
557  tmpfld = 'A'
558  call cplfind(sorttest%num, sorttest%fld, tmpfld, ifind, nfind)
559  write(nulprt,*) subname,' cpl find1 ',trim(tmpfld),ifind,nfind
560  do n1 = ifind,ifind+nfind-1
561  write(nulprt,*) subname,' cpl find2 ',n1,trim(sorttest%fld(n1))
562  enddo
563 
564  tmpfld = 'B'
565  call cplfind(sorttest%num, sorttest%fld, tmpfld, ifind, nfind)
566  write(nulprt,*) subname,' cpl find1 ',trim(tmpfld),ifind,nfind
567  do n1 = ifind,ifind+nfind-1
568  write(nulprt,*) subname,' cpl find2 ',n1,trim(sorttest%fld(n1))
569  enddo
570 
571  tmpfld = 'C'
572  call cplfind(sorttest%num, sorttest%fld, tmpfld, ifind, nfind)
573  write(nulprt,*) subname,' cpl find1 ',trim(tmpfld),ifind,nfind
574  do n1 = ifind,ifind+nfind-1
575  write(nulprt,*) subname,' cpl find2 ',n1,trim(sorttest%fld(n1))
576  enddo
577 
578  tmpfld = 'D'
579  call cplfind(sorttest%num, sorttest%fld, tmpfld, ifind, nfind)
580  write(nulprt,*) subname,' cpl find1 ',trim(tmpfld),ifind,nfind
581  do n1 = ifind,ifind+nfind-1
582  write(nulprt,*) subname,' cpl find2 ',n1,trim(sorttest%fld(n1))
583  enddo
584 
585  tmpfld = 'E'
586  call cplfind(sorttest%num, sorttest%fld, tmpfld, ifind, nfind)
587  write(nulprt,*) subname,' cpl find1 ',trim(tmpfld),ifind,nfind
588  do n1 = ifind,ifind+nfind-1
589  write(nulprt,*) subname,' cpl find2 ',n1,trim(sorttest%fld(n1))
590  enddo
591 
592  deallocate(sortkey)
593  deallocate(sorttest%fld)
594  deallocate(sorttest%modnum)
595  deallocate(sorttest%varnum)
596 
597  write(nulprt,*) subname,' Test cplfind: '
598  n1 = max(min(sortndst%num,sortndst%num/3),1)
599  tmpfld = sortndst%fld(n1)
600  call cplfind(sortndst%num, sortndst%fld, tmpfld, ifind, nfind)
601  write(nulprt,*) subname,' cpl find1 ',trim(tmpfld),ifind,nfind
602  do n1 = ifind,ifind+nfind-1
603  write(nulprt,*) subname,' cpl find2 ',n1,trim(sortndst%fld(n1))
604  enddo
605 
606  n1 = max(min(sortndst%num,1),1)
607  tmpfld = sortndst%fld(n1)
608  call cplfind(sortndst%num, sortndst%fld, tmpfld, ifind, nfind)
609  write(nulprt,*) subname,' cpl find1 ',trim(tmpfld),ifind,nfind
610  do n1 = ifind,ifind+nfind-1
611  write(nulprt,*) subname,' cpl find2 ',n1,trim(sortndst%fld(n1))
612  enddo
613 
614  n1 = max(min(sortndst%num,2),1)
615  tmpfld = sortndst%fld(n1)
616  call cplfind(sortndst%num, sortndst%fld, tmpfld, ifind, nfind)
617  write(nulprt,*) subname,' cpl find1 ',trim(tmpfld),ifind,nfind
618  do n1 = ifind,ifind+nfind-1
619  write(nulprt,*) subname,' cpl find2 ',n1,trim(sortndst%fld(n1))
620  enddo
621 
622  n1 = max(min(sortndst%num,sortndst%num-1),1)
623  tmpfld = sortndst%fld(n1)
624  call cplfind(sortndst%num, sortndst%fld, tmpfld, ifind, nfind)
625  write(nulprt,*) subname,' cpl find1 ',trim(tmpfld),ifind,nfind
626  do n1 = ifind,ifind+nfind-1
627  write(nulprt,*) subname,' cpl find2 ',n1,trim(sortndst%fld(n1))
628  enddo
629 
630  n1 = max(min(sortndst%num,sortndst%num),1)
631  tmpfld = sortndst%fld(n1)
632  call cplfind(sortndst%num, sortndst%fld, tmpfld, ifind, nfind)
633  write(nulprt,*) subname,' cpl find1 ',trim(tmpfld),ifind,nfind
634  do n1 = ifind,ifind+nfind-1
635  write(nulprt,*) subname,' cpl find2 ',n1,trim(sortndst%fld(n1))
636  enddo
637 
638  CALL oasis_flush(nulprt)
639  endif
640  !==========================================================
641  ! END Test Sort Code
642  !==========================================================
643 
644  if (local_timers_on >= 2) call oasis_timer_stop ('cpl_setup_n2')
645 
646  call oasis_debug_note(subname//' compare vars and namcouple')
647  call oasis_debug_note(subname//' setup couplers')
648 
649  if (local_timers_on >= 2) call oasis_timer_start('cpl_setup_n3')
650 
651  !--------------------------------
652  !> * Loop over all my model variables
653  !--------------------------------
654 
655  do nv1 = 1,prism_nvar
656 
657  !--------------------------------
658  !> * Get parition and field information
659  !--------------------------------
660 
661  part1 = prism_var(nv1)%part
662  myfld = prism_var(nv1)%name
663 
664  IF (oasis_debug >= 20) THEN
665  WRITE(nulprt,*) ' '
666  WRITE(nulprt,*) subname,' get part and fld ',nv1,part1,trim(myfld)
667  CALL oasis_flush(nulprt)
668  ENDIF
669 
670  !--------------------------------
671  !> * Check if variable is In or Out and then find namcouple matches
672  !--------------------------------
673 
674  if (local_timers_on >= 3) call oasis_timer_start('cpl_setup_n3a')
675  if (prism_var(nv1)%ops == oasis_out) then
676  call cplfind(sortnsrc%num, sortnsrc%fld, myfld, ifind, nfind)
677  elseif (prism_var(nv1)%ops == oasis_in) then
678  call cplfind(sortndst%num, sortndst%fld, myfld, ifind, nfind)
679  endif
680  if (local_timers_on >= 3) call oasis_timer_stop ('cpl_setup_n3a')
681 
682  !--------------------------------
683  !> * Loop over the namcouple matches
684  !--------------------------------
685  do nf = ifind,ifind+nfind-1
686  if (local_timers_on >= 3) call oasis_timer_start('cpl_setup_n3b')
687 
688  flag = oasis_notdef
689 
690  if (prism_var(nv1)%ops == oasis_out) then
691  nn = sortnsrc%namnum(nf)
692  myfldi = sortnsrc%fldnum(nf)
693  myfldlist = namsrcfld(nn)
694  otfldlist = namdstfld(nn)
695  flag = oasis_out
696  elseif (prism_var(nv1)%ops == oasis_in) then
697  nn = sortndst%namnum(nf)
698  myfldi = sortndst%fldnum(nf)
699  myfldlist = namdstfld(nn)
700  otfldlist = namsrcfld(nn)
701  flag = oasis_in
702  endif
703 
704  nns = namnn2sort(nn)
705 
706  IF (oasis_debug >= 20) THEN
707  WRITE(nulprt,*) subname,' found fld1 ',trim(myfld),nv1,nf
708  WRITE(nulprt,*) subname,' found fld2 ',trim(myfld),nns,nn,myfldi,flag
709  CALL oasis_flush(nulprt)
710  ENDIF
711 
712  if (local_timers_on >= 3) call oasis_timer_stop ('cpl_setup_n3b')
713 
714  !--------------------------------
715  ! my variable is in this namcouple input
716  !--------------------------------
717 
718  if (flag /= oasis_notdef) then
719 
720  if (local_timers_on >= 3) call oasis_timer_start('cpl_setup_n3c')
721 
722  !--------------------------------
723  !> * Migrate namcouple info into part
724  !--------------------------------
725 
726  IF (oasis_debug >= 20) THEN
727  WRITE(nulprt,*) subname,' migrate namcouple to part '
728  CALL oasis_flush(nulprt)
729  ENDIF
730 
731  if (flag == oasis_in) then
732  if (prism_part(part1)%nx < 1) then
733  prism_part(part1)%nx = namdst_nx(nn)
734  prism_part(part1)%ny = namdst_ny(nn)
735  prism_part(part1)%gridname = trim(namdstgrd(nn))
736  endif
737  endif
738  if (flag == oasis_out) then
739  if (prism_part(part1)%nx < 1) then
740  prism_part(part1)%nx = namsrc_nx(nn)
741  prism_part(part1)%ny = namsrc_ny(nn)
742  prism_part(part1)%gridname = trim(namsrcgrd(nn))
743  endif
744  endif
745 
746  IF (oasis_debug >= 20) THEN
747  WRITE(nulprt,*) subname,' Field : ',trim(prism_var(nn)%name)
748  WRITE(nulprt,*) subname,' Grid dst : ',trim(namdstgrd(nn))
749  WRITE(nulprt,*) subname,' Grid src : ',trim(namsrcgrd(nn))
750 ! WRITE(nulprt,*) subname,' prism_part : ',prism_part(part1)%gridname
751  CALL oasis_flush(nulprt)
752  ENDIF
753 
754  !--------------------------------
755  !> * Make sure it's either an In or Out, sanity check
756  !--------------------------------
757 
758  if (flag /= oasis_in .and. flag /= oasis_out) then
759  write(nulprt,*) subname,estr,'var must be either OASIS_In or OASIS_Out for var = ',trim(myfld)
760  call oasis_abort(file=__file__,line=__line__)
761  endif
762 
763  if (oasis_debug >= 20) then
764  write(nulprt,'(1x,2a,4i6,2a)') subname,' ca: myfld',nn,compid,&
765  nv1,myfldi,' ',trim(myfld)
766  call oasis_flush(nulprt)
767  endif
768 
769  !--------------------------------
770  !> * Determine matching field name from namcouple
771  !--------------------------------
772 
773  if (local_timers_on >= 3) call oasis_timer_start('cpl_setup_n3c1')
774  otfld = 'NOmatchNOyesNOyesNO'
775  call oasis_string_listgetname(otfldlist,myfldi,otfld)
776  if (local_timers_on >= 3) call oasis_timer_stop ('cpl_setup_n3c1')
777 
778  IF (oasis_debug >= 20) THEN
779  WRITE(nulprt,*) subname,' otfld ',trim(otfld)
780  CALL oasis_flush(nulprt)
781  ENDIF
782 
783  !--------------------------------
784  !> * Search for list of models with other variable
785  !--------------------------------
786 
787  if (local_timers_on >= 3) call oasis_timer_start('cpl_setup_n3c2')
788  call cplfind(sortvars%num, sortvars%fld, otfld, ifind, nfind)
789  if (local_timers_on >= 3) call oasis_timer_stop ('cpl_setup_n3c2')
790  if (local_timers_on >= 3) call oasis_timer_stop ('cpl_setup_n3c')
791 
792  !--------------------------------
793  !> * Loop over those other matching variable names
794  !--------------------------------
795  found = .false.
796  do nvf = ifind, ifind+nfind-1
797 
798  ! check used appropriate array value, we are using "src" side sorted list
799  ! if output, just set the nf value
800  ! if input, search for an nn and myfldi match in the list
801 
802  if (prism_var(nv1)%ops == oasis_out) then
803  namsrc_checkused(nf) = 1
804  if (oasis_debug >= 20) then
805  write(nulprt,*) subname,' set src checkused ',trim(myfld),':',trim(otfld),nf
806  call oasis_flush(nulprt)
807  endif
808  endif
809  if (prism_var(nv1)%ops == oasis_in) then
810  n1 = 0
811  found2 = .false.
812  do while (n1 < sortnsrc%num .and. .not.found2)
813  n1 = n1 + 1
814  if (nn == sortnsrc%namnum(n1) .and. myfldi == sortnsrc%fldnum(n1)) then
815  namsrc_checkused(n1) = 1
816  found2 = .true.
817  if (oasis_debug >= 20) then
818  write(nulprt,*) subname,' set dst checkused ',trim(myfld),':',trim(otfld),n1
819  call oasis_flush(nulprt)
820  endif
821  endif
822  enddo
823  endif
824 
825  if (local_timers_on >= 3) call oasis_timer_start('cpl_setup_n3d')
826  nm = sortvars%modnum(nvf)
827  nv = sortvars%varnum(nvf)
828 
829  if (oasis_debug >= 20) then
830  write(nulprt,*) subname,' match otfld ',trim(otfld),nn
831  call oasis_flush(nulprt)
832  endif
833 
834  !--------------------------------
835  !> * Check that one side is In and other side is Out for communication
836  !--------------------------------
837 
838  if (namfldops(nn) == ip_exported .or. namfldops(nn) == ip_expout) then
839 ! tcraig allow this now
840 ! if (nm == compid) then
841 ! write(nulprt,*) subname,estr,'send recv pair on same model = ', &
842 ! trim(myfld),' ',trim(otfld)
843 ! call oasis_abort(file=__FILE__,line=__LINE__)
844 ! endif
845  if (flag == oasis_out .and. allops(nv,nm) /= oasis_in) then
846  write(nulprt,*) subname,estr,'send recv pair both Out = ', &
847  trim(myfld),' ',trim(otfld)
848  call oasis_abort(file=__file__,line=__line__)
849  endif
850  if (flag == oasis_in .and. allops(nv,nm) /= oasis_out) then
851  write(nulprt,*) subname,estr,'send recv pair both In = ', &
852  trim(myfld),' ',trim(otfld)
853  call oasis_abort(file=__file__,line=__line__)
854  endif
855  endif
856 
857  !--------------------------------
858  !> * Check if input or output, field name should match on both sides.
859  !--------------------------------
860 
861  if (namfldops(nn) == ip_input .or. namfldops(nn) == ip_output) then
862  if (trim(myfld) /= trim(otfld)) then
863  write(nulprt,*) subname,estr,'namcouple field names do not match in/out = ', &
864  trim(myfld),' ',trim(otfld)
865  call oasis_abort(file=__file__,line=__line__)
866  endif
867  endif
868 
869  !--------------------------------
870  !> * Check that the bundle size matches in both models for bundled fields
871  !--------------------------------
872 
873  if (prism_var(nv1)%num /= allnum(nv,nm)) then
874  write(nulprt,*) subname,estr,'namcouple bundle fields do not match for ',trim(myfld),' ',trim(otfld)
875  write(nulprt,*) subname,estr,'namcouple bundle numbers are ',prism_var(nv1)%num,allnum(nv,nm)
876  call oasis_abort(file=__file__,line=__line__)
877  endif
878 
879  !--------------------------------
880  ! Only an error to find two sources for a destination
881  ! Not an error if a two destinations have a single source
882  !--------------------------------
883 
884  if (flag == oasis_in .and. found) then
885  write(nulprt,*) subname,estr,'found two sources for field = ',trim(otfld)
886  call oasis_abort(file=__file__,line=__line__)
887  endif
888  found = .true.
889 
890  nc = nns
891  if (flag == oasis_out) pcpointer => prism_coupler_put(nc)
892  if (flag == oasis_in) pcpointer => prism_coupler_get(nc)
893 
894  !--------------------------------
895  !> * Generate field list, multiple field support
896  !--------------------------------
897 
898  IF (oasis_debug >= 20) THEN
899  WRITE(nulprt,*) subname,' set prism_coupler '
900  CALL oasis_flush(nulprt)
901  ENDIF
902 
903  ! tcraig, changed this to make sure order of fields in list matches on all tasks
904  ! Use the field lists in the namcouple
905  ! Assumes all namcoupler variables are coupled
906  ! The nflds counter doesn't do much anymore here
907  ! The varid size should be size(myfldlist)
908  ! Will need to change IF all namcoupler variables don't need to be coupled
909 
910  pcpointer%nflds = pcpointer%nflds + 1
911 
912 !tcx
913 ! this used to add fields to list one at a time
914 ! svarid = size(pcpointer%varid)
915 ! if (pcpointer%nflds > svarid) then
916 ! allocate(varidtmp(svarid))
917 ! varidtmp(1:svarid) = pcpointer%varid(1:svarid)
918 ! deallocate(pcpointer%varid)
919 ! allocate(pcpointer%varid(pcpointer%nflds+10))
920 ! pcpointer%varid(1:svarid) = varidtmp(1:svarid)
921 ! deallocate(varidtmp)
922 ! endif
923 !
924 ! if (pcpointer%nflds == 1) then
925 ! pcpointer%fldlist = trim(myfld)
926 ! else
927 ! pcpointer%fldlist = trim(pcpointer%fldlist)//':'//trim(myfld)
928 ! endif
929 ! pcpointer%varid(pcpointer%nflds) = nv1
930 !tcx
931 
932  if (pcpointer%nflds == 1) then
933  pcpointer%fldlist = trim(myfldlist)
934  deallocate(pcpointer%varid)
935  allocate(pcpointer%varid(oasis_string_listgetnum(myfldlist)))
936  pcpointer%varid(:) = ispval
937  endif
938 
939  svarid = size(pcpointer%varid)
940  if (myfldi > svarid .or. pcpointer%nflds > svarid) then
941  WRITE(nulprt,*) subname,estr,'multiple field coupling setup error',svarid,myfldi,pcpointer%nflds
942  call oasis_abort(file=__file__,line=__line__)
943  endif
944 
945  pcpointer%varid(myfldi) = nv1
946 
947  !--------------------------------
948  !> * Add this coupler to list of prism_var couplers
949  !--------------------------------
950 
951  prism_var(nv1)%ncpl = prism_var(nv1)%ncpl + 1
952  if (prism_var(nv1)%ncpl > mvarcpl) then
953  WRITE(nulprt,*) subname,estr,'ncpl too high, max size (mvarcpl) = ',mvarcpl
954  WRITE(nulprt,*) subname,estr,'increase mvarcpl in mod_oasis_var'
955  call oasis_abort(file=__file__,line=__line__)
956  endif
957  prism_var(nv1)%cpl(prism_var(nv1)%ncpl) = nc
958 
959  !--------------------------------
960  ! prism_coupler settings
961  !> * Copy namcouple settings into this coupler or
962  !> check that coupler is consistent with prior setting
963  !--------------------------------
964 
965  if (pcpointer%valid) then
966  if (pcpointer%comp /= nm) then
967  WRITE(nulprt,*) subname,estr,'mismatch in field comp for var = ',trim(myfld)
968  call oasis_abort(file=__file__,line=__line__)
969  endif
970  if (pcpointer%namID /= nn) then
971  WRITE(nulprt,*) subname,estr,'mismatch in field namID for var = ',trim(myfld)
972  call oasis_abort(file=__file__,line=__line__)
973  endif
974  if (pcpointer%partID /= part1) then
975  WRITE(nulprt,*) subname,estr,'mismatch in field partID for var = ',trim(myfld)
976  call oasis_abort(file=__file__,line=__line__)
977  endif
978 
979  else
980  pcpointer%comp = nm
981  pcpointer%seq = namfldseq(nn)
982  pcpointer%dt = namflddti(nn)
983  pcpointer%lag = namfldlag(nn)
984  pcpointer%maxtime= namruntim
985  pcpointer%rstfile= trim(namrstfil(nn))
986  pcpointer%inpfile= trim(naminpfil(nn))
987  pcpointer%mapperID = -1
988  pcpointer%partID = part1
989  pcpointer%rpartID= part1
990  pcpointer%namID = nn
991  pcpointer%trans = namfldtrn(nn)
992  pcpointer%conserv= namfldcon(nn)
993  pcpointer%consopt= namfldcoo(nn)
994  pcpointer%ops = namfldops(nn)
995  pcpointer%tag = compid*100*1000 + compid*1000 + nn
996  pcpointer%getput = oasis_notdef
997  pcpointer%sndrcv = .false.
998  pcpointer%output = .false.
999  pcpointer%input = .false.
1000  pcpointer%sndmult= namfldsmu(nn)
1001  pcpointer%sndadd = namfldsad(nn)
1002  pcpointer%rcvmult= namflddmu(nn)
1003  pcpointer%rcvadd = namflddad(nn)
1004  pcpointer%snddiag= namchecki(nn)
1005  pcpointer%rcvdiag= namchecko(nn)
1006 
1007  !--------------------------------
1008  !> * Set prism_coupler input and output flags
1009  ! prism_coupler comm flags, need for tags to match up on both sides
1010  ! tags assume up to 1000 namcouple inputs and 100 models
1011  !--------------------------------
1012 
1013  IF (oasis_debug >= 20) THEN
1014  WRITE(nulprt,*) subname,' inout flags '
1015  CALL oasis_flush(nulprt)
1016  ENDIF
1017 
1018  if (namfldops(nn) == ip_output .or. namfldops(nn) == ip_expout) then
1019  pcpointer%output = .true.
1020  pcpointer%getput = oasis3_put
1021  endif
1022  if (namfldops(nn) == ip_input) then
1023  pcpointer%input = .true.
1024  pcpointer%getput = oasis3_get
1025  endif
1026 
1027  if (namfldops(nn) == ip_exported .or. namfldops(nn) == ip_expout) then
1028  pcpointer%sndrcv = .true.
1029  if (flag == oasis_out) then
1030  pcpointer%tag = nm*100*1000 + compid*1000 + nn
1031  pcpointer%getput = oasis3_put
1032  elseif (flag == oasis_in) then
1033  pcpointer%tag = compid*100*1000 + nm*1000 + nn
1034  pcpointer%getput = oasis3_get
1035  endif
1036  !--------------------------------
1037  !> * Setup prism_coupler router
1038  ! cannot reuse router because don't really know what's on the other side
1039  ! if router is already set for the coupler, then fine, otherwise, set new router
1040  !--------------------------------
1041  if (pcpointer%routerID == ispval) then
1043  if (prism_nrouter > prism_mrouter) then
1044  write(nulprt,*) subname,estr,'prism_nrouter too large = ',prism_nrouter,prism_mrouter
1045  write(nulprt,*) subname,estr,'check prism_mrouter in oasis_coupler_setup '
1046  call oasis_abort(file=__file__,line=__line__)
1047  endif
1048  pcpointer%routerID = prism_nrouter
1049  endif
1050  endif
1051 
1052  !--------------------------------
1053  !> * Setup prism_coupler mapper
1054  !--------------------------------
1055 
1056  IF (oasis_debug >= 20) THEN
1057  WRITE(nulprt,*) subname,' mapper '
1058  CALL oasis_flush(nulprt)
1059  ENDIF
1060 
1061  tmp_mapfile = nammapfil(nn)
1062 
1063  if (trim(tmp_mapfile) == 'idmap' .and. trim(namscrmet(nn)) /= trim(cspval)) then
1064  if (trim(namscrmet(nn)) == 'CONSERV') then
1065  tmp_mapfile = 'rmp_'//trim(namsrcgrd(nn))//'_to_'//trim(namdstgrd(nn))//&
1066  &'_'//trim(namscrmet(nn))//'_'//trim(namscrnor(nn))//'.nc'
1067  else
1068  tmp_mapfile = 'rmp_'//trim(namsrcgrd(nn))//'_to_'//trim(namdstgrd(nn))//&
1069  &'_'//trim(namscrmet(nn))//'.nc'
1070  endif
1071  endif
1072 
1073  if (trim(tmp_mapfile) /= 'idmap') then
1074  pcpointer%maploc = trim(nammaploc(nn))
1075  if ((flag == oasis_in .and. trim(nammaploc(nn)) == 'dst') .or. &
1076  (flag == oasis_out .and. trim(nammaploc(nn)) == 'src')) then
1077  !--------------------------------
1078  !> * Try to reuse mapper already defined,
1079  !> must match mapping file and partition
1080  !--------------------------------
1081  mapid = -1
1082  do n = 1,prism_nmapper
1083  if (trim(prism_mapper(n)%file) == trim(tmp_mapfile) .and. &
1084  trim(prism_mapper(n)%loc ) == trim(nammaploc(nn)) .and. &
1085  trim(prism_mapper(n)%opt ) == trim(nammapopt(nn))) then
1086  if (flag == oasis_in .and. prism_mapper(n)%dpart == part1) mapid = n
1087  if (flag == oasis_out .and. prism_mapper(n)%spart == part1) mapid = n
1088  endif
1089  enddo
1090  !--------------------------------
1091  !> * Or get ready to initialize a new mapper
1092  !--------------------------------
1093  if (mapid < 1) then
1095  if (prism_nmapper > prism_mmapper) then
1096  write(nulprt,*) subname,estr,'prism_nmapper too large',prism_nmapper,prism_mmapper
1097  write(nulprt,*) subname,estr,'check prism_mmapper in oasis_coupler_setup '
1098  call oasis_abort(file=__file__,line=__line__)
1099  endif
1100  mapid = prism_nmapper
1101  prism_mapper(mapid)%file = trim(tmp_mapfile)
1102  prism_mapper(mapid)%loc = trim(nammaploc(nn))
1103  prism_mapper(mapid)%opt = trim(nammapopt(nn))
1104  prism_mapper(mapid)%srcgrid = trim(namsrcgrd(nn))
1105  prism_mapper(mapid)%dstgrid = trim(namdstgrd(nn))
1106  if (flag == oasis_in ) prism_mapper(mapid)%dpart = part1
1107  if (flag == oasis_out) prism_mapper(mapid)%spart = part1
1108  if (oasis_debug > 15) then
1109  write(nulprt,*) subname,' DEBUG new mapper for file ',&
1110  trim(prism_mapper(mapid)%file)
1111  call oasis_flush(nulprt)
1112  endif
1113  endif
1114  pcpointer%mapperID = mapid
1115  endif ! flag and nammaploc match
1116  endif ! nammapfil
1117 
1118  pcpointer%valid = .true.
1119 
1120  endif ! valid
1121 
1122  if (local_timers_on >= 3) call oasis_timer_stop('cpl_setup_n3d')
1123 
1124  enddo ! nvf
1125 
1126  endif ! my var found
1127 
1128  enddo ! nfind
1129  enddo ! nv1
1130  if (local_timers_on >= 2) call oasis_timer_stop ('cpl_setup_n3')
1131  if (local_timers_on >= 1) then
1132  call oasis_timer_start('cpl_setup_n4_barrier')
1133  call oasis_mpi_barrier(mpi_comm_global, 'cpl_setup_n4')
1134  call oasis_timer_stop('cpl_setup_n4_barrier')
1135  call oasis_timer_start('cpl_setup_n4')
1136  endif
1137  if (local_timers_on >= 3) call oasis_timer_start('cpl_setup_n4a')
1138 
1139  ! aggregate checkused info across all pes and then check on each component root
1140  allocate(namsrc_checkused_g(sortnsrc%num))
1141  call oasis_mpi_max(namsrc_checkused,namsrc_checkused_g,mpi_comm_global,string=trim(subname)//':srccheckused',all=.true.)
1142  found = .false.
1143  do n1 = 1,sortnsrc%num
1144  if (namsrc_checkused_g(n1) /= 1) then
1145  if (mpi_rank_local == 0) write(nulprt,*) subname,estr,'namcouple variable not used: ',trim(sortnsrc%fld(n1))
1146  found = .true.
1147  endif
1148  enddo
1149 ! call oasis_mpi_barrier(mpi_comm_global)
1150  if (found) call oasis_abort(file=__file__,line=__line__)
1151  deallocate(namsrc_checkused_g)
1152 
1153  !--- deallocate temporary ---
1154  deallocate(allvar,nallvar,allops,allnum)
1155  deallocate(namsrc_checkused)
1156  deallocate(sortnsrc%fld)
1157  deallocate(sortnsrc%namnum)
1158  deallocate(sortnsrc%fldnum)
1159  deallocate(sortndst%fld)
1160  deallocate(sortndst%namnum)
1161  deallocate(sortndst%fldnum)
1162  deallocate(sortvars%fld)
1163  deallocate(sortvars%modnum)
1164  deallocate(sortvars%varnum)
1165 
1166  !----------------------------------------------------------
1167  !> * Rebuild the fields list based on field bundles as needed
1168  ! need to modify fldlist and varids in prism_couplers
1169  ! order of fields needs to be preserved
1170  !----------------------------------------------------------
1171 
1172  do nc = 1,prism_mcoupler
1173  do npc = 1,2
1174  if (npc == 1) then
1175  pcpointer => prism_coupler_put(nc)
1176  endif
1177  if (npc == 2) then
1178  pcpointer => prism_coupler_get(nc)
1179  endif
1180 
1181  if (pcpointer%valid) then
1182  nflds1 = oasis_string_listgetnum(pcpointer%fldlist)
1183  nflds2 = 0
1184  do n1 = 1,nflds1
1185  nflds2 = nflds2 + prism_var(pcpointer%varid(n1))%num
1186  enddo
1187  if (oasis_debug >= 2) then
1188  write(nulprt,*) subname,' fldlist rebuild nflds1,nflds2 for ',trim(pcpointer%fldlist)
1189  write(nulprt,*) subname,' fldlist rebuild nflds1,nflds2 ',nflds1,nflds2
1190  endif
1191  if (nflds2 < nflds1) then
1192  write(nulprt,*) subname,estr,'fldlist rebuild nflds2 < nflds1 for ',trim(pcpointer%fldlist)
1193  write(nulprt,*) subname,estr,'fldlist reset error in fld cnt = ',nflds1,nflds2
1194  call oasis_abort(file=__file__,line=__line__)
1195  else
1196  if (oasis_debug >= 2) then
1197  write(nulprt,*) subname,' fldlist rebuild nflds2 > nflds1 for ',trim(pcpointer%fldlist)
1198  endif
1199  allocate(varid1(nflds1))
1200  varid1(1:nflds1) = pcpointer%varid(1:nflds1)
1201  myfldlist = pcpointer%fldlist ! temporary storage
1202  pcpointer%fldlist = ""
1203  deallocate(pcpointer%varid)
1204  allocate(pcpointer%varid(nflds2))
1205  ncnt = 0
1206  do n1 = 1,nflds1
1207  do n2 = 1,prism_var(varid1(n1))%num
1208  ncnt = ncnt + 1
1209  pcpointer%varid(ncnt) = varid1(n1)
1210  delim = ":"
1211  if (ncnt == 1) delim = ""
1212  if (len_trim(pcpointer%fldlist) > 0.99 * len(pcpointer%fldlist)) then
1213  write(nulprt,*) subname,estr,'fldlist rebuild too long, limit is ',len(pcpointer%fldlist),' chars'
1214  write(nulprt,*) subname,estr,'current rebuid fldlist is ',trim(pcpointer%fldlist)
1215  call oasis_abort(file=__file__,line=__line__)
1216  endif
1217  call oasis_coupler_bldvarname(varid1(n1),n2,vname)
1218  write(pcpointer%fldlist,'(a)') trim(pcpointer%fldlist)//trim(delim)//trim(vname)
1219  if (oasis_debug >= 2) then
1220  write(nulprt,*) subname,' fldlist rebuild n1, n2 ',n1,n2,ncnt
1221  write(nulprt,*) subname,' fldlist rebuild fldlist ',ncnt,trim(pcpointer%fldlist)
1222  write(nulprt,*) subname,' fldlist rebuild varid ',ncnt,pcpointer%varid(ncnt)
1223  endif
1224  enddo ! n2
1225  enddo ! n1
1226  deallocate(varid1)
1227  endif
1228  endif ! valid
1229  enddo ! npc
1230  enddo ! nc
1231 
1232  if (oasis_debug >= 20) then
1233  write(nulprt,*) ' '
1234  write(nulprt,*) subname,' couplers setup'
1235  do nc = 1,prism_mcoupler
1236 !tcx can't write here, something uninitialized???
1237 !-> CEG it was dpart so added extra if into the print routine
1238 ! if (prism_coupler_put(nc)%valid) call prism_coupler_print(nc,prism_coupler_put(nc))
1239 ! if (prism_coupler_get(nc)%valid) call prism_coupler_print(nc,prism_coupler_get(nc))
1240  enddo
1241  write(nulprt,*) ' '
1242  call oasis_flush(nulprt)
1243  endif
1244 
1245  if (mpi_comm_local == mpi_comm_null) then
1246  return
1247  endif
1248 
1249  !----------------------------------------------------------
1250  !> * Initialize coupling infrastructure based on initial coupler setup above
1251  !----------------------------------------------------------
1252 
1253  call oasis_debug_note(subname//' initialize coupling datatypes')
1254  if (local_timers_on >= 3) call oasis_timer_stop('cpl_setup_n4a')
1255 
1256  !----------------------------------------------------------
1257  !> * Loop over all couplers
1258  !----------------------------------------------------------
1259 
1260  do nc = 1,prism_mcoupler
1261  ! tcraig, this barrier make sure mapping files are generated one coupler at a time
1262  if (local_timers_on >= 3) call oasis_timer_start('cpl_setup_n4_global_barrier')
1263  call oasis_mpi_barrier(mpi_comm_global,'cpl_setup_n4_global')
1264  if (local_timers_on >= 3) call oasis_timer_stop('cpl_setup_n4_global_barrier')
1265  do npc = 1,2
1266  if (npc == 1) then
1267  pcpointer => prism_coupler_put(nc)
1268  pcpntpair => prism_coupler_get(nc)
1269  endif
1270  if (npc == 2) then
1271  pcpointer => prism_coupler_get(nc)
1272  pcpntpair => prism_coupler_put(nc)
1273  endif
1274  if (oasis_debug >= 20) then
1275  write(nulprt,*) subname,' DEBUG cb:initialize coupler ',nc,npc,pcpointer%valid
1276  call oasis_flush(nulprt)
1277  endif
1278 
1279  if (pcpointer%valid) then
1280  if (local_timers_on >= 3) call oasis_timer_start('cpl_setup_n4b')
1281  if (oasis_debug >= 5) then
1282  write(nulprt,*) subname,' DEBUG ci:initialize coupler ',nc,npc
1283  call oasis_flush(nulprt)
1284  endif
1285 
1286  namid = pcpointer%namID
1287  part1 = pcpointer%partID
1288  mapid = pcpointer%mapperID
1289 
1290  if (part1 <= 0) then
1291  write(nulprt,*) subname,estr,'part1 invalid = ',part1
1292  call oasis_abort(file=__file__,line=__line__)
1293  endif
1294 
1295  !--------------------------------
1296  !> * Initialize avect1 which stores the get/put data
1297  !--------------------------------
1298 
1299  gsize = mct_gsmap_gsize(prism_part(part1)%gsmap)
1300  lsize = mct_gsmap_lsize(prism_part(part1)%gsmap,mpi_comm_local)
1301  if (oasis_debug >= 15) then
1302  write(nulprt,'(1x,2a,5i10)') subname,' DEBUG ci:part1 info ',namid,part1,mapid,gsize,lsize
1303  write(nulprt,'(1x,2a,4i12)') subname,' DEBUG ci:part1a',prism_part(part1)%gsmap%ngseg,&
1304  prism_part(part1)%gsmap%gsize
1305  do n1 = 1,min(prism_part(part1)%gsmap%ngseg,10)
1306  write(nulprt,'(1x,2a,4i12)') subname,' DEBUG ci:part1b',n1,&
1307  prism_part(part1)%gsmap%start(n1),&
1308  prism_part(part1)%gsmap%length(n1),&
1309  prism_part(part1)%gsmap%pe_loc(n1)
1310  enddo
1311  call oasis_flush(nulprt)
1312  endif
1313  call mct_avect_init(pcpointer%avect1,rlist=trim(pcpointer%fldlist),lsize=lsize)
1314  call mct_avect_zero(pcpointer%avect1)
1315  pcpointer%aVon(1) = .true.
1316  if (oasis_debug >= 15) then
1317  write(nulprt,*) subname,' DEBUG ci:avect1 initialized '
1318  call oasis_flush(nulprt)
1319  endif
1320 
1321  !--------------------------------
1322  !> * Compute nflds for this coupling and initialize avcnt and status
1323  !--------------------------------
1324 
1325  pcpointer%nflds = mct_avect_nrattr(pcpointer%avect1)
1326  allocate(pcpointer%status(pcpointer%nflds))
1327  allocate(pcpointer%avcnt (pcpointer%nflds))
1328  pcpointer%avcnt(:) = 0
1329  if (pcpointer%getput == oasis3_put) pcpointer%status = oasis_comm_wait
1330  if (pcpointer%getput == oasis3_get) pcpointer%status = oasis_comm_ready
1331  if (local_timers_on >= 3) call oasis_timer_stop('cpl_setup_n4b')
1332 
1333  !--------------------------------
1334  !> * Initialize the mapper data
1335  !--------------------------------
1336 
1337  if (mapid > 0) then
1338 
1339  if (prism_mapper(mapid)%init) then
1340  if (local_timers_on >= 3) call oasis_timer_start('cpl_setup_n4c')
1341  !--------------------------------
1342  ! mapper already initialized
1343  !--------------------------------
1344  if (pcpointer%getput == oasis3_put) then
1345  part2 = prism_mapper(mapid)%dpart
1346  else
1347  part2 = prism_mapper(mapid)%spart
1348  endif
1349  gsize = mct_gsmap_gsize(prism_part(part2)%gsmap)
1350  if (local_timers_on >= 3) call oasis_timer_stop('cpl_setup_n4c')
1351  else
1352  !--------------------------------
1353  ! instantiate mapper
1354  ! read/generate mapping file
1355  ! read non local grid size
1356  ! get gsmap for non local grid
1357  ! read mapping weights and initialize sMatP
1358  !--------------------------------
1359  if (local_timers_on >= 3) call oasis_timer_start('cpl_setup_n4d')
1360  if (oasis_debug >= 15) then
1361  write(nulprt,*) subname,' DEBUG ci:read mapfile ',trim(prism_mapper(mapid)%file)
1362  call oasis_flush(nulprt)
1363  endif
1364  if (mpi_rank_local == 0) then
1365  if (local_timers_on >= 3) call oasis_timer_start('cpl_setup_n4da')
1366  if (local_timers_on >= 3) call oasis_timer_start('cpl_setup_n4da1')
1367  inquire(file=trim(prism_mapper(mapid)%file),exist=exists)
1368  if (local_timers_on >= 3) call oasis_timer_stop('cpl_setup_n4da1')
1369  if (oasis_debug >= 15) then
1370  write(nulprt,*) subname,' DEBUG ci: inquire mapfile ',&
1371  trim(prism_mapper(mapid)%file),exists
1372  call oasis_flush(nulprt)
1373  endif
1374  endif
1375  call oasis_mpi_bcast(exists,mpi_comm_local,subname//' exists')
1376  if (.not.exists) then
1377  if (trim(namscrmet(namid)) /= trim(cspval)) then
1378  !--------------------------------
1379  ! generate mapping file on map group/communicator
1380  ! taken from oasis3 scriprmp
1381  !--------------------------------
1382  if (mpi_in_map) then
1383  if (local_timers_on > 2) call oasis_timer_start('cpl_setup_genmap')
1384  call oasis_map_genmap(mapid,namid)
1385  if (local_timers_on > 2) call oasis_timer_stop('cpl_setup_genmap')
1386  end if
1387  else
1388  write(nulprt,*) subname,estr,'map file does not exist and SCRIPR not set = ',&
1389  trim(prism_mapper(mapid)%file)
1390  call oasis_abort(file=__file__,line=__line__)
1391  endif
1392  endif
1393  !
1394  if (mpi_rank_local == 0) then
1395  !--------------------------------
1396  ! open mapping file
1397  !--------------------------------
1398  if (local_timers_on >= 3) call oasis_timer_start('cpl_setup_n4da3')
1399  status = nf90_open(trim(prism_mapper(mapid)%file),nf90_nowrite,ncid)
1400  if (oasis_debug >= 15) then
1401  status = nf90_inq_dimid(ncid,'dst_grid_size',dimid)
1402  status = nf90_inquire_dimension(ncid,dimid,len=gsize)
1403  write(nulprt,*) subname," DEBUG dst_grid_size ",gsize
1404  status = nf90_inq_dimid(ncid,'src_grid_size',dimid)
1405  status = nf90_inquire_dimension(ncid,dimid,len=gsize)
1406  write(nulprt,*) subname," DEBUG src_grid_size ",gsize
1407  endif
1408  if (pcpointer%getput == oasis3_put) &
1409  status = nf90_inq_dimid(ncid,'dst_grid_size',dimid)
1410  if (pcpointer%getput == oasis3_get) &
1411  status = nf90_inq_dimid(ncid,'src_grid_size',dimid)
1412  status = nf90_inquire_dimension(ncid,dimid,len=gsize)
1413  if (local_timers_on >= 3) call oasis_timer_stop('cpl_setup_n4da3')
1414  if (local_timers_on >= 3) call oasis_timer_stop('cpl_setup_n4da')
1415  endif ! rank = 0
1416  if (local_timers_on >= 3) call oasis_timer_start('cpl_setup_n4db')
1417  call oasis_mpi_bcast(gsize,mpi_comm_local,subname//' gsize')
1418  if (local_timers_on >= 3) call oasis_timer_stop('cpl_setup_n4db')
1419 
1420  if (local_timers_on >= 3) call oasis_timer_start('cpl_setup_n4dc')
1421  if (pcpointer%getput == oasis3_put) then
1422  nx = namdst_nx(namid)
1423  ny = namdst_ny(namid)
1424  gridname = trim(namdstgrd(namid))
1425  mapopt1 = 'dst'
1426  else
1427  nx = namsrc_nx(namid)
1428  ny = namsrc_ny(namid)
1429  gridname = trim(namsrcgrd(namid))
1430  mapopt1 = 'src'
1431  endif
1432 
1433  !--- mapopt sets whether src or dst are rearranged in remap
1434  !--- src = rearrange and map (bfb), dst = map and rearrange (partial sum)
1435  if (prism_mapper(mapid)%opt == 'opt') then
1436  if (pcpointer%getput == oasis3_put .and. prism_part(part1)%gsize > gsize) then
1437  mapopt = 'dst'
1438  elseif (pcpointer%getput == oasis3_get .and. prism_part(part1)%gsize < gsize) then
1439  mapopt = 'dst'
1440  else
1441  mapopt = 'src'
1442  endif
1443  elseif (prism_mapper(mapid)%opt == 'bfb') then
1444  mapopt = 'src'
1445  elseif (prism_mapper(mapid)%opt == 'sum') then
1446  mapopt = 'dst'
1447  else
1448  write(nulprt,*) subname,estr,'mapper opt invalid expect bfb or sum =',trim(prism_mapper(mapid)%opt)
1449  call oasis_abort(file=__file__,line=__line__)
1450  endif
1451 
1452  if (prism_mapper(mapid)%optval /= '' .and. &
1453  prism_mapper(mapid)%optval /= trim(mapopt)) then
1454  write(nulprt,*) subname,estr,'mapper opt changed',&
1455  trim(prism_mapper(mapid)%optval),' ',trim(mapopt)
1456  call oasis_abort(file=__file__,line=__line__)
1457  endif
1458  prism_mapper(mapid)%optval = trim(mapopt)
1459  if (local_timers_on >= 3) call oasis_timer_stop('cpl_setup_n4dc')
1460  if (local_timers_on >= 3) call oasis_timer_stop('cpl_setup_n4d')
1461 
1462  !-------------------------------
1463  ! smatreaddnc allocates sMati to nwgts
1464  ! then instantiate an sMatP for each set of wgts
1465  ! to support higher order mapping
1466  !-------------------------------
1467 
1468  if (oasis_debug > 15) then
1469  write(nulprt,*) subname,' using part2decomp = ',trim(part2decomp)
1470  write(nulprt,*) subname,' mapopt, mapopt1 = ',trim(mapopt),' ',trim(mapopt1)
1471  endif
1472 
1473  if (trim(part2decomp) == 'decomp_wghtfile') then
1474  ! reads wgts based on part1 then creates new part2 decomp based on wgts decomp
1475  ! pass in part1 decomp for "both" decomps for smatreaddnc
1476 
1477  if (smatread_method == "ceg") then
1478  if (local_timers_on >= 1) call oasis_timer_start('cpl_setup_n4rdw_ceg')
1479  call oasis_map_smatreaddnc_ceg(smati,prism_part(part1)%gsmap,prism_part(part1)%gsmap, &
1480  trim(mapopt1),trim(prism_mapper(mapid)%file),mpi_rank_local,mpi_comm_local,nwgts)
1481  if (local_timers_on >= 1) call oasis_timer_stop('cpl_setup_n4rdw_ceg')
1482  else
1483  if (local_timers_on >= 1) call oasis_timer_start('cpl_setup_n4rdw_orig')
1484  call oasis_map_smatreaddnc_orig(smati,prism_part(part1)%gsmap,prism_part(part1)%gsmap, &
1485  trim(mapopt1),trim(prism_mapper(mapid)%file),mpi_rank_local,mpi_comm_local,nwgts)
1486  if (local_timers_on >= 1) call oasis_timer_stop('cpl_setup_n4rdw_orig')
1487  endif
1488 
1489  ! extract the gridIDs from sMati, rows and cols are same in all sMati's here, so just use sMati(1)
1490 ! if (OASIS_debug > 15) then
1491 ! nullify(gridID)
1492 ! call mct_sMat_ExpGRowI(sMati(1), gridID, length=arrlen)
1493 ! write(nulprt,*) subname,' gridID0r ',trim(mapopt),' ',trim(mapopt1)
1494 ! write(nulprt,*) subname,' gridID1r ',size(gridID),arrlen, gsize
1495 ! if (arrlen > 0) then
1496 ! write(nulprt,*) subname,' gridID2r ',minval(gridID),maxval(gridID)
1497 ! write(nulprt,*) subname,' gridID3r ',minval(gridID(1:arrlen)),maxval(gridID(1:arrlen))
1498 ! write(nulprt,*) subname,' gridID4r ',gridID(1:10)
1499 ! endif
1500 ! deallocate(gridID)
1501 ! nullify(gridID)
1502 ! call mct_sMat_ExpGColI(sMati(1), gridID, length=arrlen)
1503 ! write(nulprt,*) subname,' gridID0c ',trim(mapopt),' ',trim(mapopt1)
1504 ! write(nulprt,*) subname,' gridID1c ',size(gridID),arrlen, gsize
1505 ! if (arrlen > 0) then
1506 ! write(nulprt,*) subname,' gridID2c ',minval(gridID),maxval(gridID)
1507 ! write(nulprt,*) subname,' gridID3c ',minval(gridID(1:arrlen)),maxval(gridID(1:arrlen))
1508 ! write(nulprt,*) subname,' gridID4c ',gridID(1:10)
1509 ! endif
1510 ! deallocate(gridID)
1511 ! endif
1512 
1513  if (local_timers_on >= 3) call oasis_timer_start('cpl_setup_n4smat_expg')
1514  nullify(gridid)
1515  if (mapopt1 == 'dst') then
1516  call mct_smat_expgrowi(smati(1), gridid, length=arrlen)
1517  elseif (mapopt1 == 'src') then
1518  call mct_smat_expgcoli(smati(1), gridid, length=arrlen)
1519  else
1520  write(nulprt,*) subname,estr,'invalid mapopt = ',trim(mapopt)
1521  call oasis_abort(file=__file__,line=__line__)
1522  endif
1523  do n = 1,nwgts
1524  call mct_smat_clean(smati(n))
1525  enddo
1526  deallocate(smati)
1527  if (local_timers_on >= 3) call oasis_timer_stop('cpl_setup_n4smat_expg')
1528 
1529  if (oasis_debug > 15) then
1530  write(nulprt,*) subname,' gridID0 ',trim(mapopt),' ',trim(mapopt1)
1531  write(nulprt,*) subname,' gridID1 ',size(gridid),arrlen, gsize
1532  if (arrlen > 0) then
1533  write(nulprt,*) subname,' gridID2 ',minval(gridid),maxval(gridid)
1534  write(nulprt,*) subname,' gridID3 ',minval(gridid(1:arrlen)),maxval(gridid(1:arrlen))
1535  write(nulprt,*) subname,' gridID4 ',gridid(1:10)
1536  endif
1537  endif
1538 
1539  endif
1540 
1541  if (local_timers_on >= 1) then
1542  call oasis_timer_start('cpl_setup_n4part_cr_barrier')
1543  call oasis_mpi_barrier(mpi_comm_local, 'cpl_setup_n4part')
1544  call oasis_timer_stop('cpl_setup_n4part_cr_barrier')
1545  endif
1546  if (local_timers_on >= 1) call oasis_timer_start('cpl_setup_n4part_create')
1547  if (part2decomp == 'decomp_wghtfile') then
1548  call oasis_part_create(part2,trim(part2decomp),gsize,nx,ny,gridname,prism_part(part1)%mpicom,mpi_comm_local,gridid)
1549  deallocate(gridid)
1550  else
1551  call oasis_part_create(part2,trim(part2decomp),gsize,nx,ny,gridname,prism_part(part1)%mpicom,mpi_comm_local)
1552  endif
1553  if (local_timers_on >= 1) call oasis_timer_stop('cpl_setup_n4part_create')
1554 
1555  if (pcpointer%getput == oasis3_put) then
1556  !prism_mapper(mapID)%spart = part1 ! set above
1557  prism_mapper(mapid)%dpart = part2
1558  else
1559  prism_mapper(mapid)%spart = part2
1560  !prism_mapper(mapID)%dpart = part1 ! set above
1561  endif
1562  spart = prism_mapper(mapid)%spart
1563  dpart = prism_mapper(mapid)%dpart
1564 
1565  if (smatread_method == "ceg") then
1566  if (local_timers_on >= 1) then
1567  call oasis_timer_start('cpl_setup_n4rd_ceg_barrier')
1568  call oasis_mpi_barrier(mpi_comm_local, 'cpl_setup_n4rd_ceg')
1569  call oasis_timer_stop('cpl_setup_n4rd_ceg_barrier')
1570  call oasis_timer_start('cpl_setup_n4rd_ceg')
1571  endif
1572  call oasis_map_smatreaddnc_ceg(smati,prism_part(spart)%gsmap,prism_part(dpart)%gsmap, &
1573  trim(mapopt),trim(prism_mapper(mapid)%file),mpi_rank_local,mpi_comm_local,nwgts)
1574  if (local_timers_on >= 1) call oasis_timer_stop('cpl_setup_n4rd_ceg')
1575  else
1576  if (local_timers_on >= 1) then
1577  call oasis_timer_start('cpl_setup_n4rd_orig_barrier')
1578  call oasis_mpi_barrier(mpi_comm_local, 'cpl_setup_n4rd_orig')
1579  call oasis_timer_stop('cpl_setup_n4rd_orig_barrier')
1580  call oasis_timer_start('cpl_setup_n4rd_orig')
1581  endif
1582  call oasis_map_smatreaddnc_orig(smati,prism_part(spart)%gsmap,prism_part(dpart)%gsmap, &
1583  trim(mapopt),trim(prism_mapper(mapid)%file),mpi_rank_local,mpi_comm_local,nwgts)
1584  if (local_timers_on >= 1) call oasis_timer_stop('cpl_setup_n4rd_orig')
1585  endif
1586 
1587  if (oasis_debug >= 15) then
1588  write(nulprt,*) subname," DEBUG part_create part1 gsize",prism_part(part1)%gsize
1589  do r1 = 1,min(prism_part(part1)%gsmap%ngseg,10)
1590  write(nulprt,*) subname," DEBUG part_create part1 info ",&
1591  prism_part(part1)%gsmap%start(r1),prism_part(part1)%gsmap%length(r1),&
1592  prism_part(part1)%gsmap%pe_loc(r1)
1593  enddo
1594 
1595  write(nulprt,*) subname," DEBUG part_create part2 gsize",prism_part(part2)%gsize
1596  do r1 = 1,min(prism_part(part2)%gsmap%ngseg,10)
1597  write(nulprt,*) subname," DEBUG part_create part2 info ",prism_part(part2)%gsmap%start(r1),&
1598  prism_part(part2)%gsmap%length(r1),prism_part(part2)%gsmap%pe_loc(r1)
1599  enddo
1600  endif
1601 
1602  if (local_timers_on >= 1) then
1603  call oasis_timer_start('cpl_setup_n4sminit_barrier')
1604  call oasis_mpi_barrier(mpi_comm_local, 'cpl_setup_n4sminit')
1605  call oasis_timer_stop('cpl_setup_n4sminit_barrier')
1606  call oasis_timer_start('cpl_setup_n4sminit')
1607  endif
1608 
1609  prism_mapper(mapid)%nwgts = nwgts
1610  allocate(prism_mapper(mapid)%sMatP(nwgts))
1611  do n = 1,nwgts
1612  call mct_smatp_init(prism_mapper(mapid)%sMatP(n), smati(n), &
1613  prism_part(spart)%gsmap, prism_part(dpart)%gsmap, 0, mpi_comm_local, compid)
1614  call mct_smat_clean(smati(n))
1615  enddo
1616  deallocate(smati)
1617  if (local_timers_on >= 1) call oasis_timer_stop('cpl_setup_n4sminit')
1618 
1619  if (oasis_debug >= 2) then
1620  if (local_timers_on >= 3) call oasis_timer_start('cpl_setup_n4smprint')
1621  write(cstring,'(a1,i4.4,a1)') 'm',mapid,'-'
1622  ! call mct_rearr_print(prism_mapper(mapID)%sMatP(1)%xtoxprime,mpi_comm_local,nulprt,trim(cstring)//'smpx')
1623  ! call mct_rearr_print(prism_mapper(mapID)%sMatP(1)%yprimetoy,mpi_comm_local,nulprt,trim(cstring)//'smpy')
1624  write(nulprt,*) subname,subname," mct_rearr_print ",trim(cstring)," smpx:"
1625  call mct_rearr_print(prism_mapper(mapid)%sMatP(1)%xtoxprime,mpi_comm_local,nulprt)
1626  write(nulprt,*) subname,subname," mct_rearr_print ",trim(cstring)," smpy:"
1627  call mct_rearr_print(prism_mapper(mapid)%sMatP(1)%yprimetoy,mpi_comm_local,nulprt)
1628  if (local_timers_on >= 3) call oasis_timer_stop('cpl_setup_n4smprint')
1629  endif
1630 
1631  if (local_timers_on >= 3) call oasis_timer_start('cpl_setup_n4e')
1632 
1633  lsize = mct_smat_gnumel(prism_mapper(mapid)%sMatP(1)%Matrix,mpi_comm_local)
1634  prism_mapper(mapid)%init = .true.
1635  if (oasis_debug >= 15) then
1636  write(nulprt,*) subname," DEBUG ci:done initializing prism_mapper",mapid,&
1637  " nElements = ",lsize," nwgts = ",nwgts
1638  call oasis_flush(nulprt)
1639  endif
1640  if (local_timers_on >= 3) call oasis_timer_stop('cpl_setup_n4e')
1641  endif ! map init
1642 
1643  if (local_timers_on >= 3) call oasis_timer_start('cpl_setup_n4f')
1644  !--------------------------------
1645  !> * Read mapper mask and area if not already done
1646  !--------------------------------
1647  if (.not.prism_mapper(mapid)%AVred .and. pcpointer%conserv /= ip_cnone) then
1648  ! initialize and load AV_ms and AV_md
1649 
1650  spart = prism_mapper(mapid)%spart
1651  dpart = prism_mapper(mapid)%dpart
1652 
1653  lsize = mct_gsmap_lsize(prism_part(spart)%gsmap,mpi_comm_local)
1654  call mct_avect_init(prism_mapper(mapid)%av_ms,ilist='mask',rlist='area',lsize=lsize)
1655  call mct_avect_zero(prism_mapper(mapid)%av_ms)
1656 ! gridname = prism_part(spart)%gridname
1657  gridname=prism_mapper(mapid)%srcgrid
1658  call oasis_io_read_avfld('masks.nc',prism_mapper(mapid)%av_ms, &
1659  prism_part(spart)%gsmap,mpi_comm_local,'mask',trim(gridname)//'.msk',fldtype='int')
1660  call oasis_io_read_avfld('areas.nc',prism_mapper(mapid)%av_ms, &
1661  prism_part(spart)%gsmap,mpi_comm_local,'area',trim(gridname)//'.srf',fldtype='real')
1662 
1663  lsize = mct_gsmap_lsize(prism_part(dpart)%gsmap,mpi_comm_local)
1664  call mct_avect_init(prism_mapper(mapid)%av_md,ilist='mask',rlist='area',lsize=lsize)
1665  call mct_avect_zero(prism_mapper(mapid)%av_md)
1666 ! gridname = prism_part(dpart)%gridname
1667  gridname=prism_mapper(mapid)%dstgrid
1668  call oasis_io_read_avfld('masks.nc',prism_mapper(mapid)%av_md, &
1669  prism_part(dpart)%gsmap,mpi_comm_local,'mask',trim(gridname)//'.msk',fldtype='int')
1670  call oasis_io_read_avfld('areas.nc',prism_mapper(mapid)%av_md, &
1671  prism_part(dpart)%gsmap,mpi_comm_local,'area',trim(gridname)//'.srf',fldtype='real')
1672 
1673  prism_mapper(mapid)%AVred = .true.
1674 
1675  if (oasis_debug >= 30) then
1676  write(nulprt,*) subname,' DEBUG msi ',minval(prism_mapper(mapid)%av_ms%iAttr(:,:)),&
1677  maxval(prism_mapper(mapid)%av_ms%iAttr(:,:)),&
1678  sum(prism_mapper(mapid)%av_ms%iAttr(:,:))
1679  write(nulprt,*) subname,' DEBIG msr ',minval(prism_mapper(mapid)%av_ms%rAttr(:,:)),&
1680  maxval(prism_mapper(mapid)%av_ms%rAttr(:,:)),&
1681  sum(prism_mapper(mapid)%av_ms%rAttr(:,:))
1682  write(nulprt,*) subname,' DEBUG mdi ',minval(prism_mapper(mapid)%av_md%iAttr(:,:)),&
1683  maxval(prism_mapper(mapid)%av_md%iAttr(:,:)),&
1684  sum(prism_mapper(mapid)%av_md%iAttr(:,:))
1685  write(nulprt,*) subname,' DEBUG mdr ',minval(prism_mapper(mapid)%av_md%rAttr(:,:)),&
1686  maxval(prism_mapper(mapid)%av_md%rAttr(:,:)),&
1687  sum(prism_mapper(mapid)%av_md%rAttr(:,:))
1688  CALL oasis_flush(nulprt)
1689  endif
1690  endif
1691 
1692  !--------------------------------
1693  !> * Initialize avect1m, the data in avect1 mapped to another grid
1694  !--------------------------------
1695 
1696  lsize = mct_gsmap_lsize(prism_part(part2)%gsmap,mpi_comm_local)
1697  if (oasis_debug >= 15) then
1698  write(nulprt,'(1x,2a,4i12)') subname,' DEBUG ci:part2 info ',part2,mapid,gsize,lsize
1699  write(nulprt,'(1x,2a,4i12)') subname,' DEBUG ci:part2a',prism_part(part2)%gsmap%ngseg,&
1700  prism_part(part2)%gsmap%gsize
1701  do n1 = 1,min(prism_part(part2)%gsmap%ngseg,10)
1702  write(nulprt,'(1x,2a,4i12)') subname,' DEBUG ci:part2b',n1,prism_part(part2)%gsmap%start(n1),&
1703  prism_part(part2)%gsmap%length(n1),prism_part(part2)%gsmap%pe_loc(n1)
1704  enddo
1705  call oasis_flush(nulprt)
1706  endif
1707  call mct_avect_init(pcpointer%avect1m,rlist=trim(pcpointer%fldlist),lsize=lsize)
1708  call mct_avect_zero(pcpointer%avect1m)
1709  if (oasis_debug >= 15) then
1710  write(nulprt,*) subname,' DEBUG ci:avect1m initialized '
1711  call oasis_flush(nulprt)
1712  endif
1713 
1714  !--------------------------------
1715  ! router partition is always other part
1716  !--------------------------------
1717 
1718  pcpointer%rpartID = part2
1719  if (local_timers_on >= 3) call oasis_timer_stop('cpl_setup_n4f')
1720  else
1721 
1722  !--------------------------------
1723  ! router partition is just coupler part
1724  ! Set to this by default above
1725  !--------------------------------
1726 
1727  ! pcpointer%rpartID = pcpointer%partID
1728 
1729  endif ! no mapper
1730 
1731  endif ! endif of pcpointer%valid
1732 
1733 ! print'(I3,A,X,L,X,8(I8,X))',mpi_rank_global, 'would have done sndrcv here', pcpointer%sndrcv,pcpointer%comp,compid, &
1734 ! pcpointer%valid, mapID, pcpointer%rPartID, pcpointer%routerID
1735 
1736  enddo ! npc
1737  enddo ! nc
1738 
1739 !-------------------------------------------------
1740 ! CEG split 1 loop into 2 to allow map reading on different models in parallel.
1741 !-------------------------------------------------
1742 
1743  if (local_timers_on >= 1) then
1744  call oasis_timer_start('cpl_setup_n4_rt_barrier')
1745  call oasis_mpi_barrier(mpi_comm_local, 'cpl_setup_n4_rt')
1746  call oasis_timer_stop('cpl_setup_n4_rt_barrier')
1747  endif
1748 
1749  do nc = 1, prism_mcoupler ! nc
1750  do npc=1,2
1751 
1752  if (npc == 1) then
1753  pcpointer => prism_coupler_put(nc)
1754  pcpntpair => prism_coupler_get(nc)
1755  endif
1756  if (npc == 2) then
1757  pcpointer => prism_coupler_get(nc)
1758  pcpntpair => prism_coupler_put(nc)
1759  endif
1760 
1761  namid = pcpointer%namID
1762  part1 = pcpointer%partID
1763  mapid = pcpointer%mapperID
1764 
1765 ! print'(I3,A,X,L,X,8(I8,X))',mpi_rank_global, '..finally doing sndrcv here', pcpointer%sndrcv, pcpointer%comp, compid, &
1766 ! pcpointer%valid, mapID, pcpointer%rPartID, pcpointer%routerID
1767 ! if (mapID > 0) then
1768 
1769  !--------------------------------
1770  !> * Initialize router based on rpartID
1771  !--------------------------------
1772 
1773  if (local_timers_on >= 2) call oasis_timer_start('cpl_setup_n4_rt')
1774  if (pcpointer%sndrcv) then
1775 
1776  if (oasis_debug >= 15) then
1777  write(nulprt,*) subname,' DEBUG ci:initialize router ',pcpointer%routerID,&
1778  pcpointer%comp,pcpointer%rpartID
1779  call oasis_flush(nulprt)
1780  endif
1781 
1782  if (compid == pcpointer%comp) then
1783  ! routers for sending to self
1784  ! setup router on second pass so rpartID is defined on both sides
1785  ! setup both routers at the same time
1786  if (npc == 2) then
1787  if (oasis_debug >= 15) then
1788  write(nulprt,*) subname,' DEBUG self router between part ',pcpointer%rpartID,' and part ',pcpntpair%rpartID, &
1789  ' with router ',pcpointer%routerID,' and router ',pcpntpair%routerID,' for compid ',compid
1790  endif
1791  if (local_timers_on >= 1) call oasis_timer_start('cpl_setup_n4_rta')
1792  call mct_router_init(prism_part(pcpointer%rpartID)%gsmap, prism_part(pcpntpair%rpartID)%gsmap, &
1793  mpi_comm_local, prism_router(pcpointer%routerID)%router)
1794  call mct_router_init(prism_part(pcpntpair%rpartID)%gsmap, prism_part(pcpointer%rpartID)%gsmap, &
1795  mpi_comm_local, prism_router(pcpntpair%routerID)%router)
1796  if (local_timers_on >= 1) call oasis_timer_stop('cpl_setup_n4_rta')
1797 
1798  if (oasis_debug >= 15) then
1799  write(nulprt,*) subname," DEBUG ci:done initializing prism_router",&
1800  pcpointer%routerID
1801  if (oasis_debug >= 20) then
1802  do r1 = 1,min(prism_part(pcpointer%rpartID)%gsmap%ngseg,10)
1803  write(nulprt,*) subname," DEBUG router gs1 info ",prism_part(pcpointer%rpartID)%gsmap%start(r1),&
1804  prism_part(pcpointer%rpartID)%gsmap%length(r1),prism_part(pcpointer%rpartID)%gsmap%pe_loc(r1)
1805  enddo
1806  do r1 = 1,min(prism_part(pcpointer%partID)%gsmap%ngseg,10)
1807  write(nulprt,*) subname," DEBUG router gs2 info ",prism_part(pcpointer%partID)%gsmap%start(r1),&
1808  prism_part(pcpointer%partID)%gsmap%length(r1),prism_part(pcpointer%partID)%gsmap%pe_loc(r1)
1809  enddo
1810  do r1 = 1,min(prism_part(pcpntpair%rpartID)%gsmap%ngseg,10)
1811  write(nulprt,*) subname," DEBUG router gs3 info ",prism_part(pcpntpair%rpartID)%gsmap%start(r1),&
1812  prism_part(pcpntpair%rpartID)%gsmap%length(r1),prism_part(pcpntpair%rpartID)%gsmap%pe_loc(r1)
1813  enddo
1814  do r1 = 1,min(prism_part(pcpntpair%partid)%gsmap%ngseg,10)
1815  write(nulprt,*) subname," DEBUG router gs4 info ",prism_part(pcpntpair%partid)%gsmap%start(r1),&
1816  prism_part(pcpntpair%partid)%gsmap%length(r1),prism_part(pcpntpair%partid)%gsmap%pe_loc(r1)
1817  enddo
1818  do r1 = 1,prism_router(pcpointer%routerID)%router%nprocs
1819  write(nulprt,*) subname," DEBUG router info ",pcpointer%routerID,r1, &
1820  prism_router(pcpointer%routerID)%router%pe_list(r1),prism_router(pcpointer%routerID)%router%locsize(r1)
1821  enddo
1822  endif
1823  call oasis_flush(nulprt)
1824  endif
1825 
1826  if (oasis_debug >= 15) then
1827  write(nulprt,*) subname," DEBUG ci:done initializing prism_router",&
1828  pcpntpair%routerID
1829  if (oasis_debug >= 20) then
1830  do r1 = 1,prism_router(pcpntpair%routerID)%router%nprocs
1831  write(nulprt,*) subname," DEBUG router info ",pcpntpair%routerID,r1, &
1832  prism_router(pcpntpair%routerID)%router%pe_list(r1),prism_router(pcpntpair%routerID)%router%locsize(r1)
1833  enddo
1834  endif
1835  call oasis_flush(nulprt)
1836  endif
1837  endif
1838 
1839  else
1840 
1841  if (local_timers_on >= 1) call oasis_timer_start('cpl_setup_n4_rtb')
1842  call mct_router_init(pcpointer%comp,prism_part(pcpointer%rpartID)%gsmap, &
1843  mpi_comm_local,prism_router(pcpointer%routerID)%router)
1844  if (local_timers_on >= 1) call oasis_timer_stop('cpl_setup_n4_rtb')
1845 
1846  if (oasis_debug >= 15) then
1847  write(nulprt,*) subname," DEBUG ci:done initializing prism_router",&
1848  pcpointer%routerID
1849  if (oasis_debug >= 20) then
1850  do r1 = 1,prism_router(pcpointer%routerID)%router%nprocs
1851  write(nulprt,*) subname," DEBUG router info ",pcpointer%routerID,r1, &
1852  prism_router(pcpointer%routerID)%router%pe_list(r1),prism_router(pcpointer%routerID)%router%locsize(r1)
1853  enddo
1854  endif
1855  call oasis_flush(nulprt)
1856  endif
1857 
1858  endif
1859 
1860  endif
1861  if (local_timers_on >= 2) call oasis_timer_stop('cpl_setup_n4_rt')
1862 
1863  enddo ! npc
1864  enddo ! prism_mcoupler
1865 
1866  if (local_timers_on >= 3) call oasis_timer_start('cpl_setup_n4g')
1867  !----------------------------------------------------------
1868  !> * Diagnostics for all couplers
1869  !----------------------------------------------------------
1870 
1871  if (oasis_debug >= 2) then
1872  write(nulprt,*) ' '
1873  write(nulprt,*) subname,' couplers initialized'
1874  do nc = 1,prism_mcoupler
1875  if (prism_coupler_put(nc)%valid) call oasis_coupler_print(nc,prism_coupler_put(nc))
1876  if (prism_coupler_get(nc)%valid) call oasis_coupler_print(nc,prism_coupler_get(nc))
1877  enddo
1878  write(nulprt,*) ' '
1879  CALL oasis_flush(nulprt)
1880  endif
1881 
1882  IF (lucia_debug > 0) THEN
1883  DO nc = 1, prism_mcoupler
1884  IF (prism_coupler_put(nc)%valid) &
1885  WRITE(nullucia, '(A12,I4.4,1X,A)') 'Balance: SN ', prism_coupler_put(nc)%namID, trim(prism_coupler_put(nc)%fldlist)
1886  IF (prism_coupler_get(nc)%valid) &
1887  WRITE(nullucia, '(A12,I4.4,1X,A)') 'Balance: RC ', prism_coupler_get(nc)%namID, trim(prism_coupler_get(nc)%fldlist)
1888  ENDDO
1889  ENDIF
1890 
1891  if (local_timers_on >= 3) call oasis_timer_stop ('cpl_setup_n4g')
1892  if (local_timers_on >= 1) call oasis_timer_stop ('cpl_setup_n4')
1893  IF (local_timers_on >= 1) call oasis_timer_stop('cpl_setup')
1894 
1895  call oasis_debug_exit(subname)
1896 
1897  END SUBROUTINE oasis_coupler_setup
1898 
1899 !------------------------------------------------------------
1900 
1901 !> Print routine for oasis_couplers
1902 
1903  SUBROUTINE oasis_coupler_print(cplid,pcprint)
1905  IMPLICIT NONE
1906 
1907  integer(ip_i4_p), intent(in) :: cplid !< coupler id
1908  type(prism_coupler_type), intent(in) :: pcprint !< specific prism_coupler
1909  !----------------------------------------------------------
1910  integer(ip_i4_p) :: mapid, rouid, parid, namid, nflds, rpard
1911  integer(ip_i4_p) :: spart,dpart
1912  character(len=*),parameter :: subname = '(oasis_coupler_print)'
1913 
1914  call oasis_debug_enter(subname)
1915 
1916  mapid = pcprint%mapperid
1917  rouid = pcprint%routerid
1918  parid = pcprint%partid
1919  rpard = pcprint%rpartid
1920  namid = pcprint%namid
1921  nflds = pcprint%nflds
1922 
1923  write(nulprt,*) ' '
1924  write(nulprt,*) subname,' model and cplid',compid,cplid
1925  if (pcprint%getput == oasis3_put) then
1926  write(nulprt,*) subname,' timerid send ',cplid,trim(pcprint%fldlist)
1927  write(nulprt,*) subname,' send fields ',trim(pcprint%fldlist)
1928  write(nulprt,*) subname,' from model ',compid
1929  write(nulprt,*) subname,' to model ',pcprint%comp
1930  write(nulprt,*) subname,' using router ',rouid
1931  write(nulprt,*) subname,' transform ',pcprint%trans
1932  write(nulprt,*) subname,' snd diagnose ',pcprint%snddiag
1933  write(nulprt,*) subname,' snd fld mult ',pcprint%sndmult
1934  write(nulprt,*) subname,' snd fld add ',pcprint%sndadd
1935  endif
1936  if (pcprint%getput == oasis3_get) then
1937  write(nulprt,*) subname,' timerid recv ',cplid,trim(pcprint%fldlist)
1938  write(nulprt,*) subname,' recv fields ',trim(pcprint%fldlist)
1939  write(nulprt,*) subname,' from model ',pcprint%comp
1940  write(nulprt,*) subname,' to model ',compid
1941  write(nulprt,*) subname,' using router ',rouid
1942  write(nulprt,*) subname,' rcv diagnose ',pcprint%rcvdiag
1943  write(nulprt,*) subname,' rcv fld mult ',pcprint%rcvmult
1944  write(nulprt,*) subname,' rcv fld add ',pcprint%rcvadd
1945  endif
1946  write(nulprt,*) subname,' namcouple op ',pcprint%ops
1947  write(nulprt,*) subname,' valid ',pcprint%valid
1948  write(nulprt,*) subname,' namcouple id ',namid
1949  write(nulprt,*) subname,' variable ids ',pcprint%varid(1:nflds)
1950  write(nulprt,*) subname,' sndrcv flag ',pcprint%sndrcv
1951  write(nulprt,*) subname,' output flag ',pcprint%output
1952  write(nulprt,*) subname,' input flag ',pcprint%input
1953  write(nulprt,*) subname,' input file ',trim(pcprint%inpfile)
1954  write(nulprt,*) subname,' restart file ',trim(pcprint%rstfile)
1955  write(nulprt,*) subname,' tag ',pcprint%tag
1956  write(nulprt,*) subname,' seq ',pcprint%seq
1957  write(nulprt,*) subname,' maxtime ',pcprint%maxtime
1958  write(nulprt,*) subname,' dt, lag ',pcprint%dt,pcprint%lag
1959 ! write(nulprt,*) subname,' partid, size ',parid,trim(prism_part(parid)%gridname),&
1960 ! prism_part(parid)%gsize
1961  write(nulprt,*) subname,' partid, gsize ',parid,prism_part(parid)%gsize
1962  write(nulprt,*) subname,' partid, lsize ',parid,prism_part(parid)%lsize
1963  write(nulprt,*) subname,' partid, nx,ny ',prism_part(parid)%nx,prism_part(parid)%ny
1964 ! write(nulprt,*) subname,' rpartid,size ',rpard,trim(prism_part(rpard)%gridname),&
1965 ! prism_part(rpard)%gsize
1966  write(nulprt,*) subname,' rpartid,gsize ',rpard,prism_part(rpard)%gsize
1967  write(nulprt,*) subname,' rpartid,nx,ny ',prism_part(rpard)%nx,prism_part(rpard)%ny
1968  write(nulprt,*) subname,' maploc ',trim(pcprint%maploc)
1969 
1970  if (mapid > 0) then
1971  WRITE(nulprt,*) subname,' src grid :',trim(prism_mapper(mapid)%srcgrid)
1972  WRITE(nulprt,*) subname,' dst grid :',trim(prism_mapper(mapid)%dstgrid)
1973  write(nulprt,*) subname,' use map ',mapid,trim(prism_mapper(mapid)%file)
1974  write(nulprt,*) subname,' nwgts ',mapid,prism_mapper(mapid)%nwgts
1975  spart = prism_mapper(mapid)%spart
1976  dpart = prism_mapper(mapid)%dpart
1977  write(nulprt,*) subname,' conserve ',pcprint%conserv
1978  write(nulprt,*) subname,' conserve opt ',pcprint%consopt
1979  write(nulprt,*) subname,' location ',trim(prism_mapper(mapid)%loc)
1980  write(nulprt,*) subname,' opt,optval ',trim(prism_mapper(mapid)%opt),' ',&
1981  trim(prism_mapper(mapid)%optval)
1982  write(nulprt,*) subname,' s/d partids ',spart,dpart
1983  if (spart > 0) &
1984  write(nulprt,*) subname,' from/to partition',trim(prism_part(spart)%gridname),' ',&
1985  trim(prism_part(dpart)%gridname)
1986  write(nulprt,*) subname,' from nx,ny ',prism_part(spart)%gsize,prism_part(spart)%nx,&
1987  prism_part(spart)%ny
1988  if (dpart > 0) &
1989  write(nulprt,*) subname,' to nx,ny ',prism_part(dpart)%gsize, prism_part(dpart)%nx,&
1990  prism_part(dpart)%ny
1991  endif ! mapid > 0
1992 
1993  call oasis_flush(nulprt)
1994 
1995  call oasis_debug_exit(subname)
1996 
1997  END SUBROUTINE oasis_coupler_print
1998 
1999 !------------------------------------------------------------
2000 ! !BOP ===========================================================================
2001 !
2002 !> Build a consistent variable name based on bundles
2003 !
2004 ! !DESCRIPTION:
2005 ! Build a variable name for a given variable based on the name, number
2006 ! of bundled fields, and bundle level. Needs to be used in a few different
2007 ! places in oasis.
2008 !
2009 ! !INTERFACE: -----------------------------------------------------------------
2010 
2011  SUBROUTINE oasis_coupler_bldvarname(varid, varnum, vname)
2013  IMPLICIT NONE
2014 
2015  integer(ip_i4_p), intent(in) :: varid !< variable id
2016  integer(ip_i4_p), intent(in) :: varnum !< variable bundle level number
2017  character(len=*), intent(out) :: vname !< variable name
2018  !----------------------------------------------------------
2019  character(len=*),parameter :: subname = '(oasis_coupler_bldvarname)'
2020 
2021  call oasis_debug_enter(subname)
2022 
2023  if (varnum > prism_var(varid)%num) then
2024  write(nulprt,*) subname,estr,'invalid varnum varid = ',varid,trim(prism_var(varid)%name)
2025  write(nulprt,*) subname,estr,'invalid varnum = ',varnum,prism_var(varid)%num
2026  call oasis_abort(file=__file__,line=__line__)
2027  endif
2028 
2029  if (prism_var(varid)%num > 1) then
2030  write(vname,'(a,i3.3)') trim(prism_var(varid)%name)//'.',varnum
2031  else
2032  vname = trim(prism_var(varid)%name)
2033  endif
2034 
2035  if (oasis_debug >= 20) then
2036  write(nulprt,*) subname,' check vname ',varnum,trim(vname)
2037  endif
2038 
2039  call oasis_debug_exit(subname)
2040 
2041  END SUBROUTINE oasis_coupler_bldvarname
2042 
2043 !------------------------------------------------------------
2044 ! !BOP ===========================================================================
2045 !
2046 !> Deconstruct the varname based on oasis_coupler_bldvarname
2047 !
2048 ! !DESCRIPTION:
2049 ! Deconstruct a variable name for a given variable based on the name, number
2050 ! of bundled fields, and bundle level. Must be consistent with oasis_coupler_bldvarname
2051 !
2052 ! !INTERFACE: -----------------------------------------------------------------
2053 
2054  SUBROUTINE oasis_coupler_unbldvarname(varid, vname, varnum)
2056  IMPLICIT NONE
2057 
2058  integer(ip_i4_p), intent(in) :: varid !< variable id
2059  character(len=*), intent(in) :: vname !< variable name
2060  integer(ip_i4_p), intent(out) :: varnum !< variable bundle level number
2061  !----------------------------------------------------------
2062  integer(ip_i4_p) :: vlen
2063  character(len=16) :: clen
2064  character(len=*),parameter :: subname = '(oasis_coupler_unbldvarname)'
2065 
2066  call oasis_debug_enter(subname)
2067 
2068  if (prism_var(varid)%num > 1) then
2069  vlen = len_trim(vname)
2070  clen = vname(vlen-2:vlen)
2071  read(clen,'(i3.3)') varnum
2072  if (oasis_debug >= 20) then
2073  write(nulprt,*) subname,' check vlen ',vlen,trim(clen)
2074  endif
2075  else
2076  varnum = 1
2077  endif
2078 
2079  if (oasis_debug >= 20) then
2080  write(nulprt,*) subname,' check varnum ',varnum,trim(vname)
2081  endif
2082 
2083  if (varnum > prism_var(varid)%num) then
2084  write(nulprt,*) subname,estr,'invalid varnum varid = ',varid,trim(prism_var(varid)%name)
2085  write(nulprt,*) subname,estr,'invalid varnum = ',varnum,prism_var(varid)%num
2086  call oasis_abort(file=__file__,line=__line__)
2087  endif
2088 
2089  call oasis_debug_exit(subname)
2090 
2091  END SUBROUTINE oasis_coupler_unbldvarname
2092 
2093 !------------------------------------------------------------
2094 !------------------------------------------------------------
2095 ! !BOP ===========================================================================
2096 !
2097 !> Search a character field list for a matching values
2098 !
2099 ! !DESCRIPTION:
2100 ! Sort a character array and the associated array(s) based on a
2101 ! reasonably fast sort algorithm
2102 !
2103 ! !INTERFACE: -----------------------------------------------------------------
2104 
2105 subroutine cplfind(num, fldlist, fld, ifind, nfind)
2107 ! !USES:
2108 
2109  !--- local kinds ---
2110  integer,parameter :: R8 = ip_double_p
2111  integer,parameter :: IN = ip_i4_p
2112  integer,parameter :: CL = ic_lvar
2113 
2114 ! !INPUT/OUTPUT PARAMETERS:
2115 
2116  integer(IN), intent(in) :: num !< size of array
2117  character(len=CL),intent(in) :: fldlist(:) !< sorted field list
2118  character(len=CL),intent(in) :: fld !< field to search for
2119  integer(IN) ,intent(out) :: ifind !< first match index
2120  integer(IN) ,intent(out) :: nfind !< number that match
2121 
2122 ! !EOP
2123 
2124  !--- local ---
2125  integer(IN) :: is,ie,im
2126  logical :: found
2127 
2128  !--- formats ---
2129  character(*),parameter :: subName = '(cplfind) '
2130 
2131 !-------------------------------------------------------------------------------
2132 !
2133 !-------------------------------------------------------------------------------
2134 
2135 ! call oasis_debug_enter(subname)
2136 
2137  ifind = 0
2138  nfind = 0
2139 
2140  is = 1
2141  ie = num
2142  found = .false.
2143 
2144  ! check endpoints first, the binary search uses integer
2145  ! math which makes hitting the endpoints more difficult
2146  ! so check manually. also if list size is 1, need to do this.
2147 
2148  if (.not.found) then
2149  im = 1
2150  if (fld == fldlist(im)) found = .true.
2151  endif
2152  if (.not.found) then
2153  im = num
2154  if (fld == fldlist(im)) found = .true.
2155  endif
2156 
2157  ! do a binary search
2158 
2159  do while (.not.found .and. ie > is)
2160  im = (is + ie) / 2
2161  im = max(im,is)
2162  im = min(im,ie)
2163 ! write(nulprt,*) subname,'tcx',is,ie,im,trim(fld),' ',trim(fldlist(im))
2164  if (fld == fldlist(im)) then
2165  found = .true.
2166  elseif (fld > fldlist(im)) then
2167  is = max(im,is+1)
2168  else
2169  ie = min(im,ie-1)
2170  endif
2171  enddo
2172 
2173  ! if a match was found, find first and last instance of match in list
2174 
2175  if (found) then
2176  is = im
2177  ie = im
2178  if (is > 1) then
2179  do while (fld == fldlist(is-1) .and. is > 1)
2180  is = is - 1
2181  enddo
2182  endif
2183  if (ie < num) then
2184  do while (fld == fldlist(ie+1) .and. ie < num)
2185  ie = ie + 1
2186  enddo
2187  endif
2188  ifind = is
2189  nfind = (ie - is + 1)
2190  endif
2191 
2192 ! call oasis_debug_exit(subname)
2193 
2194 end subroutine cplfind
2195 
2196 !===============================================================================
2197 
2198 END MODULE mod_oasis_coupler
2199 
2200 
integer(kind=ip_i4_p), public lastseqtime
last coupler sequence time
character(len=ic_med), dimension(:), pointer, public namfldcoo
conserv fld option (bfb, opt)
integer(kind=ip_intwp_p), parameter ip_output
character(len=jpeighty), dimension(:), pointer, public namsrcfld
list of src fields
real(kind=ip_realwp_p), dimension(:), pointer, public namfldsmu
src multiplier term
System type methods.
subroutine, public oasis_debug_note(string)
Used to write information from a subroutine, write info to log file at some debug level...
Provides a common location for several OASIS variables.
Provides reusable IO routines for OASIS.
Definition: mod_oasis_io.F90:4
integer(kind=ip_i4_p), public nnamcpl
number of namcouple inputs
character(len=ic_lvar), dimension(:), pointer, public namdstgrd
dst grid name
integer(kind=ip_i4_p) lucia_debug
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.
Router information for rearranging data on tasks.
integer(kind=ip_i4_p), dimension(:), pointer, public namfldseq
SEQ value.
subroutine, public oasis_map_smatreaddnc_ceg(sMat, SgsMap, DgsMap, newdom, fileName, mytask, mpicom, nwgts, areasrc, areadst, ni_i, nj_i, ni_o, nj_o)
Read in mapping matrix data from a SCRIP netCDF file using smart scatter (ceg)
integer(kind=ip_intwp_p), parameter oasis_in
integer(kind=ip_i4_p), dimension(:), pointer, public namfldtrn
fields transform, ip_instant,...
type(prism_part_type), dimension(mpart), public prism_part
list of defined partitions
integer(kind=ip_intwp_p) nulprt
Generic overloaded interface into MPI broadcast.
character(len=ic_med), public nammapdec
namcouple map decomp value
character(len=ic_med), public nammatxrd
namcouple matrix read option
integer(kind=ip_intwp_p), parameter ip_expout
integer(kind=ip_i4_p) mpi_comm_global
type(prism_coupler_type), dimension(:), pointer, public prism_coupler_get
prism_coupler get array
integer(kind=ip_intwp_p), parameter ip_instant
character(len=ic_med), dimension(:), pointer, public nammaploc
mapping location (src or dst pes)
integer(kind=ip_i4_p), dimension(:), pointer, public namflddti
coupling period (secs)
subroutine, public oasis_abort(id_compid, cd_routine, cd_message, file, line, rcode)
OASIS abort method, publically available to users.
type(prism_coupler_type), dimension(:), pointer, public prism_coupler_put
prism_coupler put array
subroutine, public oasis_map_smatreaddnc_orig(sMat, SgsMap, DgsMap, newdom, fileName, mytask, mpicom, nwgts, areasrc, areadst, ni_i, nj_i, ni_o, nj_o)
Read in mapping matrix data from a SCRIP netCDF weights file.
character(len=jpeighty), dimension(:), pointer, public namdstfld
list of dst fields
character(len=ic_med), dimension(:), pointer, public namrstfil
restart file name
subroutine, public oasis_string_listgetname(list, k, name, rc)
Get name of k-th field in list.
integer, parameter ip_i4_p
integer(kind=ip_i4_p) compid
subroutine oasis_coupler_print(cplid, pcprint)
Print routine for oasis_couplers.
integer(kind=ip_i4_p), dimension(:), pointer, public namfldcon
conserv fld operation
character(len= *), parameter cspval
Initialize the OASIS coupler infrastructure.
integer(kind=ip_i4_p) mpi_rank_local
Defines kinds for OASIS.
integer, parameter ip_double_p
integer(kind=ip_i4_p) prism_amodels
Character string manipulation methods.
integer(kind=ip_intwp_p), parameter ip_exported
integer(kind=ip_intwp_p) nullucia
Provides a generic and simpler interface into MPI calls for OASIS.
integer(kind=ip_i4_p), dimension(:), pointer, public namfldops
operation, ip_expout,...
integer(kind=ip_intwp_p), parameter oasis3_get
Coupler data for managing all aspects of coupling in OASIS.
subroutine cplfind(num, fldlist, fld, ifind, nfind)
Search a character field list for a matching values.
subroutine, public oasis_debug_enter(string)
Used when a subroutine is entered, write info to log file at some debug level.
subroutine, public oasis_sys_sortikey(num, arr, sortkey)
Sort an integer array using a sort key.
character(len=ic_lvar), dimension(:), pointer, public namsrcgrd
src grid name
real(kind=ip_realwp_p), dimension(:), pointer, public namflddad
dst additive term
logical, dimension(:), pointer, public namchecki
checkin flag
OASIS partition data and methods.
integer(kind=ip_i4_p), dimension(:), pointer, public namsrc_nx
src nx grid size
integer(kind=ip_i4_p), parameter, public prism_coupler_avsmax
maximum number of higher order terms in mapping
integer(kind=ip_intwp_p), parameter oasis3_put
subroutine, public oasis_sys_sortc(num, fld, sortkey)
Sort a character array and compute a sort key.
character(len=ic_med), dimension(:), pointer, public nammapopt
mapping option (bfb, sum, or opt)
character(len=ic_med), dimension(:), pointer, public namscrmet
scrip method (CONSERV, DISTWGT, BILINEAR, BICUBIC, GAUSWGT)
real(kind=ip_realwp_p), dimension(:), pointer, public namflddmu
dst multipler term
integer(kind=ip_i4_p), dimension(:), pointer, public namsrc_ny
src ny grid size
integer(kind=ip_i4_p), dimension(:), allocatable mpi_root_global
subroutine, public oasis_map_genmap(mapid, namid)
Routine to generate mapping weights data via a direct SCRIP call.
subroutine, public oasis_coupler_bldvarname(varid, varnum, vname)
Build a consistent variable name based on bundles.
integer(kind=ip_intwp_p), parameter oasis_comm_ready
integer(kind=ip_i4_p), public prism_mmapper
max mappers
Defines parameters for OASIS.
OASIS variable data and methods.
subroutine, public oasis_io_read_avfld(filename, av, gsmap, mpicom, avfld, filefld, fldtype)
Reads single field from a file into an attribute Vector.
subroutine, public oasis_timer_start(timer_label, barrier)
Start a timer.
integer(kind=ip_i4_p) oasis_debug
integer(kind=ip_intwp_p), parameter oasis_out
subroutine, public oasis_timer_stop(timer_label)
Stop a timer.
type(prism_router_type), dimension(:), pointer, public prism_router
prism_router array
character(len= *), parameter, public estr
integer(kind=ip_i4_p) mpi_comm_local
integer function, public oasis_string_listgetnum(str)
return number of fields in string list
subroutine, public oasis_mpi_barrier(comm, string)
Call MPI_BARRIER for a particular communicator.
real(kind=ip_realwp_p), dimension(:), pointer, public namfldsad
src additive term
integer, parameter ic_lvar
type(prism_mapper_type), dimension(:), pointer, public prism_mapper
list of defined mappers
integer(kind=ip_intwp_p), parameter oasis_notdef
integer(kind=ip_i4_p), dimension(:), pointer, public namfldlag
coupling lag (secs)
integer(kind=ip_i4_p), parameter, public mvarcpl
max namcouples per variable
character(len=ic_med), dimension(:), pointer, public naminpfil
input file name
integer(kind=ip_i4_p) prism_mrouter
max routers
logical, public allow_no_restart
flag to allow no restart files at startup
integer(kind=ip_i4_p), public prism_nmapper
mapper counter
integer(kind=ip_intwp_p), parameter ip_input
subroutine, public oasis_flush(nu)
Flushes output to file.
character(len=ic_long), dimension(:), pointer, public nammapfil
mapping file name
integer(kind=ip_i4_p), dimension(:), pointer, public namdst_nx
dst nx grid size
integer(kind=ip_i4_p), dimension(:), pointer, public namnn2sort
sorted namcpl for nn, define sort number, computed later
subroutine, public oasis_coupler_unbldvarname(varid, vname, varnum)
Deconstruct the varname based on oasis_coupler_bldvarname.
integer(kind=ip_i4_p) prism_nrouter
router counter
integer(kind=ip_intwp_p), public prism_nvar
number of variables defined
subroutine, public oasis_coupler_setup()
Main routine to setup couplers.
integer(kind=ip_i4_p), public namruntim
namcouple runtime
Performance timer methods.
integer(ip_intwp_p), public maxvar
number of potential variables, derived from namcouple input
integer(kind=ip_i4_p), public prism_mcoupler
max couplers
integer(kind=ip_i4_p), dimension(:), pointer, public namdst_ny
dst ny grid size
type(prism_var_type), dimension(:), pointer, public prism_var
list of defined variables
Reads the namcouple file for use in OASIS.
integer(ip_i4_p), parameter ispval
logical, dimension(:), pointer, public namchecko
checkout flag
integer(kind=ip_intwp_p), parameter oasis_comm_wait
integer(kind=ip_intwp_p), parameter ip_cnone
integer(kind=ip_i4_p), public lastseq
last coupler sequence
subroutine, public oasis_debug_exit(string)
Used when a subroutine is exited, write info to log file at some debug level.
character(len=ic_med), dimension(:), pointer, public namscrnor
scrip conserv normalization (FRACAREA, DESTAREA, FRACNNEI)
OASIS map (interpolation) data and methods.