source: CPL/oasis3-mct/branches/OASIS3-MCT_5.0_branch/lib/psmile/src/mod_oasis_var.F90 @ 6331

Last change on this file since 6331 was 6331, checked in by aclsce, 17 months ago

Moved oasis-mct_5.0 in oasis3-mct/branches directory.

File size: 13.9 KB
Line 
1
2!> OASIS variable data and methods
3
4  MODULE mod_oasis_var
5
6  USE mod_oasis_kinds
7  USE mod_oasis_data
8  USE mod_oasis_parameters
9  USE mod_oasis_sys
10  USE mod_oasis_mpi
11  USE mod_oasis_timer
12  USE mod_oasis_part
13
14  IMPLICIT none
15
16  private
17
18  !--- interfaces ---
19  public oasis_def_var
20  public oasis_var_setup
21
22  !> Overloaded interface into oasis_def_var to support old and new interface
23  interface oasis_def_var ; module procedure &
24    oasis_def_var_v1, &
25    oasis_def_var_v2
26  end interface
27
28  !--- datatypes ---
29
30  integer(ip_intwp_p),public   :: maxvar  !< number of potential variables, derived from namcouple input
31  integer(kind=ip_i4_p),parameter,public :: mvarcpl = 10   !< max namcouples per variable
32
33  !> Model variable data for model coupling
34  type prism_var_type
35     character(len=ic_lvar):: name  !< variable name
36     integer(kind=ip_i4_p) :: part  !< variable partition
37     integer(kind=ip_i4_p) :: ndim  !< rank of variable
38     integer(kind=ip_i4_p) :: num   !< size of variable
39     integer(kind=ip_i4_p) :: ops   !< input or output
40     integer(kind=ip_i4_p) :: type  !< type kind of variable
41     integer(kind=ip_i4_p) :: size  !< total size of field
42     integer(kind=ip_i4_p) :: ncpl  !< number of namcouple couplers
43     integer(kind=ip_i4_p) :: cpl(mvarcpl)  !< list of namcouple couplers
44  end type prism_var_type
45
46  integer(kind=ip_intwp_p),public :: prism_nvar = 0    !< number of variables defined
47  TYPE(prism_var_type),POINTER,public :: prism_var(:)  !< list of defined variables
48
49  CONTAINS
50
51!---------------------------------------------------------------
52
53!> The original OASIS user interface to define variables
54!> Called via oasis_def_var
55
56  SUBROUTINE oasis_def_var_v1(id_nports, cdport, id_part, &
57         id_var_nodims, kinout, id_var_shape, ktype, kinfo)
58     !---------------------------------------------------------------
59     INTEGER(kind=ip_i4_p),intent(out) :: id_nports    !< coupling field ID
60     CHARACTER(len=*)     ,intent(in)  :: cdport       !< field name as in namcouple
61     INTEGER(kind=ip_i4_p),intent(in)  :: id_part      !< partition ID
62     INTEGER(kind=ip_i4_p),intent(in)  :: id_var_nodims(2)  !< rank and number of bundles
63     INTEGER(kind=ip_i4_p),intent(in)  :: kinout       !< input or output flag
64     INTEGER(kind=ip_i4_p),intent(in)  :: id_var_shape(2*id_var_nodims(1)) !< size of field (no longer used)
65     INTEGER(kind=ip_i4_p),intent(in)  :: ktype        !< type of coupling field
66     INTEGER(kind=ip_i4_p),intent(out),optional :: kinfo    !< return code
67     !---------------------------------------------------------------
68     character(len=*),parameter :: subname = '(oasis_def_var_v1)'
69     !---------------------------------------------------------------
70
71     call oasis_debug_enter(subname)
72
73     if (present(kinfo)) then
74       call oasis_def_var_v2(id_nports, cdport, id_part, &
75         id_var_nodims, kinout, ktype, kinfo)
76     else
77       call oasis_def_var_v2(id_nports, cdport, id_part, &
78         id_var_nodims, kinout, ktype)
79     endif
80
81     call oasis_debug_exit(subname)
82
83   END SUBROUTINE oasis_def_var_v1
84
85!---------------------------------------------------------------
86
87!> The updated OASIS user interface to define variables
88!> Called via oasis_def_var
89
90  SUBROUTINE oasis_def_var_v2(id_nports, cdport, id_part, &
91         id_var_nodims, kinout, ktype, kinfo)
92     !---------------------------------------------------------------
93     INTEGER(kind=ip_i4_p),intent(out) :: id_nports    !< coupling field ID
94     CHARACTER(len=*)     ,intent(in)  :: cdport       !< field name as in namcouple
95     INTEGER(kind=ip_i4_p),intent(in)  :: id_part      !< partition ID
96     INTEGER(kind=ip_i4_p),intent(in)  :: id_var_nodims(2)  !< rank and number of bundles
97     INTEGER(kind=ip_i4_p),intent(in)  :: kinout       !< input or output flag
98     INTEGER(kind=ip_i4_p),intent(in)  :: ktype        !< type of coupling field
99     INTEGER(kind=ip_i4_p),intent(out),optional :: kinfo    !< return code
100     !---------------------------------------------------------------
101     INTEGER(kind=ip_i4_p)  :: il_var_nodims_temp(2)  !< rank and number of bundles temporary
102     INTEGER(kind=ip_i4_p)  :: n
103     CHARACTER(len=ic_lvar) :: trimmed_cdport   ! Trimmed version of cdport
104     character(len=*),parameter :: subname  = '(oasis_def_var_v2)'
105     character(len=*),parameter :: subnamei = '(oasis_def_var)'
106     LOGICAL    :: l_field_in_namcouple
107     !---------------------------------------------------------------
108
109     call oasis_debug_enter(subname)
110     if (.not. oasis_coupled) then
111        call oasis_debug_exit(subname)
112        return
113     endif
114
115     !-------------------------------------------------     
116     !> * Check len of incoming variable name
117     ! Trim incoming name once to avoid multiple trim operations
118     ! in subsequent loops
119     !-------------------------------------------------     
120
121     if (len_trim(cdport) > ic_lvar) then
122        WRITE(nulprt,*) subnamei,estr,'variable too long = ',trim(cdport)
123        WRITE(nulprt,*) subnamei,estr,'max variable length (ic_lvar) = ',ic_lvar
124        call oasis_abort(file=__FILE__,line=__LINE__)
125     endif
126     trimmed_cdport = trim(cdport)
127
128     if (present(kinfo)) kinfo = OASIS_Ok
129
130     l_field_in_namcouple = .FALSE.
131     n = 0
132
133     !-------------------------------------------------     
134     !> * Search for field in namcouple field lists
135     !-------------------------------------------------
136
137     ! If either condition ceases to be true then bail out of the loop
138     DO WHILE (n < size_namfld .AND. (.NOT.l_field_in_namcouple))
139        n = n+1
140        IF ( (trimmed_cdport == total_namsrcfld(n)).OR.    &
141             (trimmed_cdport == total_namdstfld(n)) ) THEN
142              l_field_in_namcouple = .TRUE.
143        ENDIF       
144     enddo
145
146     !-------------------------------------------------     
147     !> * Return if field not found in namcouple
148     !-------------------------------------------------     
149
150     if (.not. l_field_in_namcouple) then
151        id_nports = OASIS_Var_Uncpl
152        if (OASIS_debug >= 2) then
153           write(nulprt,*) subnamei,' variable not in namcouple return ',trimmed_cdport
154           call oasis_flush(nulprt)
155        endif
156        call oasis_debug_exit(subname)
157        return
158     endif
159
160     !-------------------------------------------------     
161     !> * Abort if field already defined
162     !-------------------------------------------------     
163
164     do n = 1,prism_nvar
165        if (trimmed_cdport == prism_var(n)%name) then
166           write(nulprt,*) subnamei,estr,'variable already defined with def_var = ',trimmed_cdport
167           write(nulprt,*) subnamei,estr,'check oasis_def_var calls in your model'
168           call oasis_abort(file=__FILE__,line=__LINE__)
169        endif
170     enddo
171
172     ! tcraig, this is due to i3.3 in the 2d->1d field bundle renaming
173     il_var_nodims_temp(:)=id_var_nodims(:)
174     IF (il_var_nodims_temp(2) > 999) THEN
175        write(nulprt,*) subnamei,estr,'variable id_var_nodims(2) too large.  limit is 999 ',il_var_nodims_temp(2)
176        write(nulprt,*) subnamei,estr,'check oasis_def_var calls in your model'
177        call oasis_abort(file=__FILE__,line=__LINE__)
178     ENDIF
179         
180     IF (il_var_nodims_temp(2) <= 0) THEN
181         il_var_nodims_temp(2)=1
182         WRITE(nulprt,*) subnamei,'WARNING id_var_nodim(2) cannot be negative or 0 ; put to 1'
183         call oasis_flush(nulprt)
184     ENDIF
185
186     !-------------------------------------------------     
187     !> * Increment the variable and store the values
188     !-------------------------------------------------     
189
190     prism_nvar = prism_nvar + 1
191     id_nports = prism_nvar
192
193     if (prism_nvar > maxvar) then
194        write(nulprt,*) subnamei,estr,'prism_nvar too large = ',prism_nvar,maxvar
195        write(nulprt,*) subnamei,estr,'check maxvar set in oasis_init_comp'
196        call oasis_abort(file=__FILE__,line=__LINE__)
197     endif
198
199     call oasis_var_zero(prism_var(prism_nvar))
200     prism_var(prism_nvar)%name = trimmed_cdport
201     prism_var(prism_nvar)%part = id_part
202     prism_var(prism_nvar)%num  = il_var_nodims_temp(2)
203     prism_var(prism_nvar)%ops  = kinout
204     prism_var(prism_nvar)%type = ktype
205     prism_var(prism_nvar)%size = 1
206     prism_var(prism_nvar)%ncpl = 0
207     prism_var(prism_nvar)%cpl  = 0
208
209     !----------------------------------
210     !> * Write some diagnostics
211     !----------------------------------
212
213     if (OASIS_debug >= 2) then
214        write(nulprt,*) ' '
215        write(nulprt,*) subnamei,' prism_nvar    = ',prism_nvar
216        write(nulprt,*) subnamei,' varname = ',prism_nvar,trim(prism_var(prism_nvar)%name)
217        write(nulprt,*) subnamei,' varpart = ',prism_nvar,prism_var(prism_nvar)%part
218        write(nulprt,*) subnamei,' varnum  = ',prism_nvar,prism_var(prism_nvar)%num
219        write(nulprt,*) subnamei,' varops  = ',prism_nvar,prism_var(prism_nvar)%ops
220        write(nulprt,*) subnamei,' vartype = ',prism_nvar,prism_var(prism_nvar)%type
221        write(nulprt,*) ' '
222        CALL oasis_flush(nulprt)
223     endif
224
225     call oasis_debug_exit(subname)
226
227   END SUBROUTINE oasis_def_var_v2
228
229!---------------------------------------------------------------
230
231!> Synchronize variables across all tasks, called at oasis enddef.
232
233  SUBROUTINE oasis_var_setup()
234   IMPLICIT NONE
235
236   !--------------------------------------------------------
237   integer(kind=ip_intwp_p) :: m,n,p,v
238   INTEGER(kind=ip_intwp_p) :: ierr, taskid
239   integer(kind=ip_intwp_p) :: vcnt
240   logical                  :: found, fastcheckout
241   character(len=ic_lvar)  ,allocatable :: vname0(:),vname(:)
242   character(len=ic_lvar2) ,allocatable :: pname0(:),pname(:)
243   integer(kind=ip_intwp_p),allocatable :: inout0(:),inout(:)
244   integer(kind=ip_intwp_p),allocatable :: vanum0(:),vanum(:)
245   logical, parameter :: local_timers_on = .false.
246   character(len=*),parameter :: subname = '(oasis_var_setup)'
247   !--------------------------------------------------------
248
249   call oasis_debug_enter(subname)
250
251   IF (local_timers_on) call oasis_timer_start('var_setup')
252
253   IF (local_timers_on) call oasis_timer_start('var_setup_reducelists')
254   allocate(vname0(prism_nvar))
255   allocate(pname0(prism_nvar))
256   allocate(inout0(prism_nvar))
257   allocate(vanum0(prism_nvar))
258   do n = 1,prism_nvar
259      vname0(n) = prism_var(n)%name
260      inout0(n) = prism_var(n)%ops
261      vanum0(n) = prism_var(n)%num
262      pname0(n) = prism_part(prism_var(n)%part)%partname
263   enddo
264
265   call oasis_mpi_reducelists(vname0,mpi_comm_local,vcnt,vname,'var_setup', &
266        fastcheck=.true.,fastcheckout=fastcheckout, &
267        linp2=pname0,lout2=pname,linp3=inout0,lout3=inout,linp4=vanum0,lout4=vanum)
268
269   deallocate(vname0)
270   deallocate(pname0)
271   deallocate(inout0)
272   deallocate(vanum0)
273   IF (local_timers_on) call oasis_timer_stop('var_setup_reducelists')
274
275   !-------------------------------------------------     
276   !> * Initialize variables on tasks where they are not previously defined.
277   ! if fastcheck worked, then don't need to do this extra work to add undefined vars
278   !-------------------------------------------------     
279
280   if (.not. fastcheckout) then
281
282      if (local_timers_on) call oasis_timer_start('var_setup_initvar')
283      do v = 1,vcnt
284
285         !--- either a prism_var that already exists
286         found = .false.
287         n = 0
288         do while (n < prism_nvar .and. .not.found)
289            n = n + 1
290            if (prism_var(n)%name == vname(v)) then
291               found = .true.
292            endif
293         enddo
294
295         !--- or a new prism_var that must be instantiated
296         if (.not.found) then
297            prism_nvar = prism_nvar + 1
298
299            call oasis_var_zero(prism_var(prism_nvar))
300            prism_var(prism_nvar)%name = vname(v)
301            prism_var(prism_nvar)%ops  = inout(v)
302            prism_var(prism_nvar)%num  = vanum(v)
303            prism_var(prism_nvar)%ncpl = 0
304            !--- figure out the local part id for the part name
305            p = 0
306            found = .false.
307            do while (p < prism_npart .and. .not.found)
308               p = p + 1
309               if (prism_part(p)%partname == pname(v)) then
310                  found = .true.
311               endif
312            enddo
313            if (found) then
314               prism_var(prism_nvar)%part = p
315               if (OASIS_debug >= 15) then
316                  write(nulprt,*) subname,' found part match ',trim(vname(v)),trim(pname(v)),p
317               endif
318            else
319               write(nulprt,*) subname,estr,'prism part not found part = ',trim(pname(v)),' var = ',trim(vname(v))
320               call oasis_abort(file=__FILE__,line=__LINE__)
321            endif
322   
323            if (OASIS_debug >= 2) then
324               write(nulprt,*) ' '
325               write(nulprt,*) subname,' add var = ',prism_nvar,trim(prism_var(prism_nvar)%name),&
326                               prism_var(prism_nvar)%part,&
327                               trim(prism_part(prism_var(prism_nvar)%part)%partname),prism_var(prism_nvar)%ops
328               CALL oasis_flush(nulprt)
329            ENDIF
330         endif
331
332      enddo   ! v = 1,vcnt
333      if (local_timers_on) call oasis_timer_stop ('var_setup_initvar')
334
335   endif   ! fastcheckout
336
337   deallocate(vname,pname,inout,vanum)
338
339   IF (local_timers_on) call oasis_timer_stop('var_setup')
340     
341   call oasis_debug_exit(subname)
342
343   END SUBROUTINE oasis_var_setup
344
345!---------------------------------------------------------------
346
347!> Zero variable information
348
349  SUBROUTINE oasis_var_zero(prism_var)
350   IMPLICIT NONE
351
352   !--------------------------------------------------------
353   type(prism_var_type),intent(inout) :: prism_var
354   character(len=*),parameter :: subname = '(oasis_var_zero)'
355   !--------------------------------------------------------
356
357   call oasis_debug_enter(subname)
358
359   prism_var%name = 'oasis_var_name_unset'
360   prism_var%part = -1
361   prism_var%ndim = -1
362   prism_var%num  = -1
363   prism_var%ops  = -1
364   prism_var%type = -1
365   prism_var%size = -1
366   prism_var%ncpl = 0
367   prism_var%cpl  = -1
368
369   call oasis_debug_exit(subname)
370
371   END SUBROUTINE oasis_var_zero
372
373!---------------------------------------------------------------
374 END MODULE mod_oasis_var
375
Note: See TracBrowser for help on using the repository browser.