My Project
mod_par.f90
Go to the documentation of this file.
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 !/===========================================================================/
13 ! Copyright (c) 2007, The University of Massachusetts Dartmouth
14 ! Produced at the School of Marine Science & Technology
15 ! Marine Ecosystem Dynamics Modeling group
16 ! All rights reserved.
17 !
18 ! FVCOM has been developed by the joint UMASSD-WHOI research team. For
19 ! details of authorship and attribution of credit please see the FVCOM
20 ! technical manual or contact the MEDM group.
21 !
22 !
23 ! This file is part of FVCOM. For details, see http://fvcom.smast.umassd.edu
24 ! The full copyright notice is contained in the file COPYRIGHT located in the
25 ! root directory of the FVCOM code. This original header must be maintained
26 ! in all distributed versions.
27 !
28 ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
29 ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
30 ! THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31 ! PURPOSE ARE DISCLAIMED.
32 !
33 !/---------------------------------------------------------------------------/
34 ! CVS VERSION INFORMATION
35 ! $Id$
36 ! $Name$
37 ! $Revision$
38 !/===========================================================================/
39 
40 MODULE mod_par
41  USE mod_types
42  USE mod_utils
43  USE lims, ONLY : ngl, mgl
44  USE mod_time, ONLY : mpi_time
45  IMPLICIT NONE
46  SAVE
47 
48 !
49 !--Global Information
50 !
51  INTEGER, POINTER :: el_pid(:) !!PROCESSOR OWNER OF GLOBAL ELEMENT
52 
53  INTEGER, POINTER :: elid(:) !!LOCAL VALUE OF GLOBAL ELEMENT
54  INTEGER, POINTER :: nlid(:) !!LOCAL VALUE OF GLOBAL NODE
55  INTEGER, POINTER :: elid_x(:) !!LOCAL VALUE OF GLOBAL ELEMENT INCLUDING HALOS
56  INTEGER, POINTER :: nlid_x(:) !!LOCAL VALUE OF GLOBAL NODE INCLUDING HALOS
57 !
58 !--Internal Information (Local)
59 !
60  INTEGER, POINTER :: egid(:) !!GLOBAL ID OF LOCAL ELEMENT
61  INTEGER, POINTER :: ngid(:) !!GLOBAL ID OF LOCAL NODE
62  INTEGER, POINTER :: egid_x(:) !!GLOBAL ID OF LOCAL ELEMENT
63  INTEGER, POINTER :: ngid_x(:) !!GLOBAL ID OF LOCAL NODE
64 
65 !
66 !--Boundary Information: Halo Elements
67 !
68  INTEGER :: nhe !!NUMBER OF HALO ELEMENTS
69  INTEGER, POINTER :: he_lst(:) !!GLOBAL IDENTITIES OF HALO ELEMENTS
70  INTEGER, POINTER :: he_own(:) !!OWNER OF HALO ELEMENTS
71 
72 !
73 !--Boundary Information: Internal Boundary Nodes
74 !
75  INTEGER :: nbn !!NUMBER OF BOUNDARY NODES
76  INTEGER :: mx_mlt !!MAX MULTIPLICITY OF BOUNDARY NODES
77  INTEGER, POINTER :: bn_lst(:) !!GLOBAL IDENTITY OF BOUNDARY NODES
78  INTEGER, POINTER :: bn_loc(:) !!LOCAL IDENTITY OF BOUNDARY NODES
79  INTEGER, POINTER :: bn_mlt(:) !!MULTIPLICITY OF BOUNDARY NODES
80  INTEGER, POINTER :: bn_ney(:,:) !!NODE OWNER LIST
81  INTEGER, POINTER :: nde_id(:) !! = 0 IF INTERNAL, 1 IF ON INTERNAL BOUNDARY
82 
83 !
84 !--Boundary Information: Halo Nodes
85 !
86  INTEGER :: nhn !!NUMBER OF HALO NODES
87  INTEGER, POINTER :: hn_lst(:) !!LIST OF HALO NODES
88  INTEGER, POINTER :: hn_own(:) !!PRIMARY OWNER OF HALO NODES
89 
90 
91  INTERFACE pprint
92  MODULE PROCEDURE pprint_arr
93  MODULE PROCEDURE pprint_vec
94  END INTERFACE
95 
96  INTERFACE aprint
97  MODULE PROCEDURE aprint_arr
98  MODULE PROCEDURE aprint_vec
99  END INTERFACE
100 !===================================================================================|
101  CONTAINS !!INCLUDED SUBROUTINES FOLLOW
102 !===================================================================================|
103 
104 !==============================================================================|
105 ! WRITE OUT VARIABLE INFORMATION TO LOCAL FILES |
106 ! |
107 ! USAGE EXAMPLES |
108 ! |
109 ! write u velocity at surface in triangle 256 to file fort.306 with iteration |
110 ! I1 = LBOUND(U,1) ; I2 = UBOUND(U,1) |
111 ! CALL PPRINT(306,I1,I2,KB,U,"element",256,1,1,FLOAT(IINT)) |
112 ! |
113 ! I1 = LBOUND(EL,1) ; I2 = UBOUND(EL,1) |
114 ! write surface elevation at node 233 to file fort.409 with time in hours |
115 ! CALL PPRINT(406,I1,I2,1,EL,"node",233,1,1,THOUR) |
116 ! |
117 ! I1 = LBOUND(T1,1) ; I2 = UBOUND(T1,1) |
118 ! write vertical distribution of salinity at node 422 to file fort.433 |
119 ! CALL PPRINT(433,I1,I2,KB,T1,"node",422,1,KBM1,THOUR) |
120 ! |
121 ! ARGUMENT LIST |
122 ! PPRINT(IUNIT,LB1,UB1,UB2,VARP,VART,ILOC,K1,K2,REF) |
123 ! 1.) IUNIT - UNIT NUMBER FOR OUTPUT FILE (MUST BE >= 300 .and. <7000) |
124 ! 2.) LB1 - LOWER BOUND OF 1ST ARGUMENT OF ARRAY TO PRINT (USUAlLY 0) |
125 ! 3.) LB2 - UPPER BOUND OF 1ST ARRAY DIMENSION (USUALLY NT OR MT) |
126 ! NOTE: LB1/LB2 CAN BE DETERMINE AUTOMATICALLY WITH LBOUND/UBOUND |
127 ! 4.) UB2 - UPPER BOUND OF SECOND ARRAY DIMENSION |
128 ! UB2 = 1 FOR SURFACE ARRAYS LIKE EL,UA |
129 ! UB2 = KB FOR 3D ARRAYS LIKE U/V |
130 ! 5.) VARP = VARIABLE TO PRINT (ARRAY NAME = U,V,WW,EL,T1,RHO1, etc) |
131 ! 6.) VART = VARIABLE LOCATION ("element" or "node") |
132 ! 7.) ILOC = INDEX OF ELEMENT/NODE TO PRINT |
133 ! 8.) K1 = LOWER RANGE OF SIGMA LEVEL TO PRINT |
134 ! 9.) K2 = UPPER RANGE OF SIGMA LEVEL TO PRINT |
135 ! K1 = 1,K2 = 1 FOR SURFACE VALUES ONLY |
136 ! K1 = 1,K2 = KBM1 FOR ALL LEVELS |
137 ! 10.) REF = REFERENCE VALUE FOR DATA (MUST BE FLOAT) |
138 ! REF = THOURS FOR CALCULATION TIME IN HOURS |
139 ! REF = FLOAT(IINT) FOR ITERATION NUMBER |
140 ! 11.) IPT = UNIT TO WRITE ERRORS TO (USE IPT) |
141 !==============================================================================|
142 
143 !==============================================================================|
144  SUBROUTINE aprint_vec(IUNIT,VARP,VART,NOW,ILOC,MSG)
146  IMPLICIT NONE
147  TYPE(time), INTENT(IN) :: NOW
148  INTEGER, INTENT(IN) :: IUNIT,ILOC
149  REAL(SP), ALLOCATABLE, INTENT(IN),TARGET :: VARP(:)
150  CHARACTER(LEN=*), INTENT(IN) :: VART
151  CHARACTER(LEN=*), INTENT(IN),OPTIONAL :: MSG
152  REAL(SP), POINTER:: VARP_O(:)
153 
154  varp_o => varp
155 
156  IF(PRESENT(msg))THEN
157  CALL pprint_vec(iunit,varp_o,vart,now,iloc,msg)
158  ELSE
159  CALL pprint_vec(iunit,varp_o,vart,now,iloc)
160  END IF
161 
162  END SUBROUTINE aprint_vec
163 
164 !==============================================================================|
165  SUBROUTINE pprint_vec(IUNIT,VARP,VART,NOW,ILOC,MSG)
167  USE lims
168 
169  IMPLICIT NONE
170  TYPE(time), INTENT(IN) :: NOW
171  INTEGER, INTENT(IN) :: IUNIT,ILOC
172  REAL(SP), POINTER, INTENT(IN) :: VARP(:)
173  CHARACTER(LEN=*), INTENT(IN) :: VART
174  CHARACTER(LEN=*), INTENT(IN),OPTIONAL :: MSG
175 
176  CHARACTER(LEN=80),parameter :: VAR_E = "element"
177  CHARACTER(LEN=80),parameter :: VAR_N = "node"
178 
179  CHARACTER(LEN=100) :: STRNG
180  CHARACTER(LEN=20) :: short
181 
182  INTEGER :: I,J,K,PROCMAX,II,IBND,Kopt,IERR
183  LOGICAL :: PRINT_PROC
184 
185  !==============================================================================|
186 
187  !------------------------------------------------------------------------------|
188  ! Process Iunit for Errors |
189  !------------------------------------------------------------------------------|
190  IF(iunit /= ipt .and. (iunit < 300 .or. iunit > 7000) )THEN
191  CALL fatal_error('ERROR IN PPRINT',&
192  & 'FILE UNIT < 300 AND UNIT > 7000 ARE RESERVED FOR FVCOM I/O',&
193  & 'PLEASE INCREASE IUNIT TO 300+')
194  END IF
195 
196  !------------------------------------------------------------------------------|
197  ! Process Vartype for Errors |
198  !------------------------------------------------------------------------------|
199  IF(vart /= var_e .AND. vart /= var_n)THEN
200  CALL fatal_error('VART IN PPRINT NOT CORRECT :'//trim(vart),&
201  & 'SHOULD BE "'//trim(var_e)//'" or "'//trim(var_n)//'"')
202  END IF
203 
204 
205  !------------------------------------------------------------------------------|
206  ! Process string output |
207  !------------------------------------------------------------------------------|
208  IF(PRESENT(msg)) strng=trim(msg)//"; IINT"
209 
210 
211  IF(abs(iint) .lt. 1000) THEN
212  WRITE(short,'(I5)') iint
213  ELSE IF(abs(iint) .lt. 1000000) THEN
214  WRITE(short,'(I8)') iint
215  ELSE
216  WRITE(short,*) iint
217  END IF
218 
219  IF(use_real_world_time) THEN
220  strng = trim(strng)//trim(short)//", Date/Time:"&
221  &//trim(write_datetime(now,3,timezone))//"; ILOC= "
222  ELSE
223  strng = trim(strng)//trim(short)//", Time(s):"
224  WRITE(short,'(f16.8)') seconds(now)
225  strng = trim(strng)//trim(short)//"; ILOC="
226  END IF
227 
228  WRITE(short,'(I8)') iloc
229  strng = trim(strng)//trim(short)//"; VALUE="
230 
231  !------------------------------------------------------------------------------|
232  ! Single Processor Case |
233  !------------------------------------------------------------------------------|
234  IF(nprocs == 1)THEN
235  WRITE(iunit,*) trim(strng),varp(iloc)
236  END IF
237 
238  !------------------------------------------------------------------------------|
239  ! Multi Processor Case with Element Based Variable (u,v,ww, etc) |
240  ! Transform to Local Element ID with "ELID" |
241  !------------------------------------------------------------------------------|
242 
243  IF(nprocs /= 1 .AND. vart == var_e .AND. elid(iloc) /= 0)THEN
244 
245  WRITE(iunit,*) trim(strng),varp(elid(iloc))
246 
247  END IF
248 
249  !------------------------------------------------------------------------------|
250  ! Multi Processor Case with Node Based Variable (s1,t1,rho1,e1, etc) |
251  ! Transform to Local Node ID with "NLID" |
252  ! If Node is Interprocessor Boundary Node, Choose Processor with Highest |
253  ! ID Number to Write Values to File |
254  !------------------------------------------------------------------------------|
255 
256  IF(nprocs /= 1 .AND. vart == var_n .AND. nlid(iloc) > 0)THEN
257 
258  print_proc = .true.
259  IF(nde_id(nlid(iloc)) == 1)THEN !!BOUNDARY NODE
260 
261  DO ii=1,nbn
262  IF(bn_lst(ii) == iloc) ibnd = ii
263  END DO
264 
265  procmax = 10000
266  DO j=1,nprocs
267  IF(bn_ney(ibnd,j)==1) THEN
268  IF(j < procmax) procmax = j
269  END IF
270  END DO
271 
272  IF(procmax /= myid) print_proc = .false. !!NOT RESPONSIBLE FOR OUTPUT
273  END IF
274 
275  IF(print_proc)THEN
276  WRITE(iunit,*) trim(strng),varp(nlid(iloc))
277  END IF
278 
279  END IF
280 
281 
282 
283  RETURN
284  END SUBROUTINE pprint_vec
285 !==============================================================================|
286 !==============================================================================|
287  SUBROUTINE aprint_arr(IUNIT,VARP,VART,NOW,ILOC,K1,K2,MSG)
289  IMPLICIT NONE
290  TYPE(time), INTENT(IN) :: NOW
291  INTEGER, INTENT(IN) :: IUNIT,ILOC,K1
292  INTEGER, INTENT(IN),OPTIONAL :: K2
293  REAL(SP), ALLOCATABLE, INTENT(IN),TARGET :: VARP(:,:)
294  CHARACTER(LEN=*), INTENT(IN) :: VART
295  CHARACTER(LEN=*), INTENT(IN),OPTIONAL :: MSG
296  REAL(SP), POINTER:: VARP_O(:,:)
297 
298  varp_o => varp
299 
300  IF (PRESENT(k2)) THEN
301  IF(PRESENT(msg))THEN
302  CALL pprint_arr(iunit,varp_o,vart,now,iloc,k1,k2,msg)
303  ELSE
304  CALL pprint_arr(iunit,varp_o,vart,now,iloc,k1,k2)
305  END IF
306  ELSE
307  IF(PRESENT(msg))THEN
308  CALL pprint_arr(iunit,varp_o,vart,now,iloc,k1,k1,msg)
309  ELSE
310  CALL pprint_arr(iunit,varp_o,vart,now,iloc,k1)
311  END IF
312  END IF
313  END SUBROUTINE aprint_arr
314 
315 !==============================================================================|
316  SUBROUTINE pprint_arr(IUNIT,VARP,VART,NOW,ILOC,K1,K2,MSG)
318  USE lims
319 
320  IMPLICIT NONE
321  TYPE(time), INTENT(IN) :: NOW
322  INTEGER, INTENT(IN) :: IUNIT,ILOC,K1
323  INTEGER, INTENT(IN),OPTIONAL :: K2
324  REAL(SP), POINTER, INTENT(IN) :: VARP(:,:)
325  CHARACTER(LEN=*), INTENT(IN) :: VART
326  CHARACTER(LEN=*), INTENT(IN),OPTIONAL :: MSG
327 
328  CHARACTER(LEN=80),parameter :: VAR_E = "element"
329  CHARACTER(LEN=80),parameter :: VAR_N = "node"
330 
331  CHARACTER(LEN=100) :: STRNG
332  CHARACTER(LEN=20) :: short
333 
334  INTEGER :: I,J,K,PROCMAX,II,IBND,Kopt,IERR
335  LOGICAL :: PRINT_PROC
336 
337  !==============================================================================|
338 
339  !------------------------------------------------------------------------------|
340  ! Process Iunit for Errors |
341  !------------------------------------------------------------------------------|
342  IF(iunit /= ipt .and. (iunit < 300 .or. iunit > 7000) )THEN
343  CALL fatal_error('ERROR IN PPRINT',&
344  & 'FILE UNIT < 300 AND UNIT > 7000 ARE RESERVED FOR FVCOM I/O',&
345  & 'PLEASE INCREASE IUNIT TO 300+')
346  END IF
347 
348  !------------------------------------------------------------------------------|
349  ! Process Vartype for Errors |
350  !------------------------------------------------------------------------------|
351  IF(vart /= var_e .AND. vart /= var_n)THEN
352  CALL fatal_error('VART IN PPRINT NOT CORRECT :'//trim(vart),&
353  & 'SHOULD BE "'//trim(var_e)//'" or "'//trim(var_n)//'"')
354  END IF
355 
356  !------------------------------------------------------------------------------|
357  ! Process optional sigma level range |
358  !------------------------------------------------------------------------------|
359 
360  IF(PRESENT(k2)) THEN
361  kopt=k2
362  ELSE
363  kopt=k1
364  END IF
365 
366  !------------------------------------------------------------------------------|
367  ! Process string output |
368  !------------------------------------------------------------------------------|
369  IF(PRESENT(msg)) strng=trim(msg)//"; IINT"
370 
371 
372  IF(abs(iint) .lt. 1000) THEN
373  WRITE(short,'(I5)') iint
374  ELSE IF(abs(iint) .lt. 1000000) THEN
375  WRITE(short,'(I8)') iint
376  ELSE
377  WRITE(short,*) iint
378  END IF
379 
380  IF(use_real_world_time) THEN
381  strng = trim(strng)//trim(short)//", Date/Time:"&
382  &//trim(write_datetime(now,3,timezone))//"; ILOC "
383  ELSE
384  strng = trim(strng)//trim(short)//", Time(s):"
385  WRITE(short,'(f16.8)') seconds(now)
386  strng = trim(strng)//trim(short)//"; ILOC="
387  END IF
388 
389  WRITE(short,'(I8)') iloc
390  strng = trim(strng)//trim(short)//"; VALUES="
391  !------------------------------------------------------------------------------|
392  ! Single Processor Case |
393  !------------------------------------------------------------------------------|
394  IF(nprocs == 1)THEN
395  WRITE(iunit,*) trim(strng)
396  WRITE(iunit,*) (varp(iloc,k),k=k1,kopt)
397  END IF
398 
399  !------------------------------------------------------------------------------|
400  ! Multi Processor Case with Element Based Variable (u,v,ww, etc) |
401  ! Transform to Local Element ID with "ELID" |
402  !------------------------------------------------------------------------------|
403 
404  IF(nprocs /= 1 .AND. vart == var_e .AND. elid(iloc) /= 0)THEN
405 
406  WRITE(iunit,*) trim(strng)
407  WRITE(iunit,*) (varp(elid(iloc),k),k=k1,kopt)
408 
409  END IF
410 
411  !------------------------------------------------------------------------------|
412  ! Multi Processor Case with Node Based Variable (s1,t1,rho1,e1, etc) |
413  ! Transform to Local Node ID with "NLID" |
414  ! If Node is Interprocessor Boundary Node, Choose Processor with Highest |
415  ! ID Number to Write Values to File |
416  !------------------------------------------------------------------------------|
417 
418  IF(nprocs /= 1 .AND. vart == var_n .AND. nlid(iloc) > 0)THEN
419 
420  print_proc = .true.
421  IF(nde_id(nlid(iloc)) == 1)THEN !!BOUNDARY NODE
422 
423  DO ii=1,nbn
424  IF(bn_lst(ii) == iloc) ibnd = ii
425  END DO
426 
427  procmax = 10000
428  DO j=1,nprocs
429  IF(bn_ney(ibnd,j)==1) THEN
430  IF(j < procmax) procmax = j
431  END IF
432  END DO
433 
434  IF(procmax /= myid) print_proc = .false. !!NOT RESPONSIBLE FOR OUTPUT
435  END IF
436 
437  IF(print_proc)THEN
438  WRITE(iunit,*) trim(strng)
439  WRITE(iunit,*) (varp(nlid(iloc),k),k=k1,kopt)
440  END IF
441 
442  END IF
443 
444 
445  RETURN
446  END SUBROUTINE pprint_arr
447 !==============================================================================|
448 
449 END MODULE mod_par
integer nbn
Definition: mod_par.f90:75
integer nhe
Definition: mod_par.f90:68
integer, dimension(:), pointer elid
Definition: mod_par.f90:53
integer myid
Definition: mod_main.f90:67
integer, dimension(:), pointer ngid_x
Definition: mod_par.f90:63
integer, target nprocs
Definition: mod_main.f90:72
integer, dimension(:), pointer elid_x
Definition: mod_par.f90:55
integer, dimension(:), pointer he_own
Definition: mod_par.f90:70
integer, dimension(:), pointer nlid_x
Definition: mod_par.f90:56
integer mx_mlt
Definition: mod_par.f90:76
integer, dimension(:), pointer bn_mlt
Definition: mod_par.f90:79
integer, dimension(:), pointer nde_id
Definition: mod_par.f90:81
integer, dimension(:), pointer hn_own
Definition: mod_par.f90:88
integer, dimension(:), pointer nlid
Definition: mod_par.f90:54
integer(itime) iint
Definition: mod_main.f90:850
character(len=80) timezone
Definition: mod_main.f90:126
integer, dimension(:), pointer bn_lst
Definition: mod_par.f90:77
subroutine pprint_vec(IUNIT, VARP, VART, NOW, ILOC, MSG)
Definition: mod_par.f90:166
subroutine aprint_arr(IUNIT, VARP, VART, NOW, ILOC, K1, K2, MSG)
Definition: mod_par.f90:288
integer mgl
Definition: mod_main.f90:50
logical use_real_world_time
Definition: mod_main.f90:131
integer, dimension(:), pointer hn_lst
Definition: mod_par.f90:87
subroutine fatal_error(ER1, ER2, ER3, ER4)
Definition: mod_utils.f90:230
integer, dimension(:), pointer he_lst
Definition: mod_par.f90:69
integer mpi_time
Definition: mod_time.f90:50
integer, dimension(:), pointer bn_loc
Definition: mod_par.f90:78
integer, dimension(:,:), pointer bn_ney
Definition: mod_par.f90:80
integer, dimension(:), pointer ngid
Definition: mod_par.f90:61
integer ipt
Definition: mod_main.f90:922
integer, dimension(:), pointer el_pid
Definition: mod_par.f90:51
integer, dimension(:), pointer egid
Definition: mod_par.f90:60
integer ngl
Definition: mod_main.f90:49
subroutine pprint_arr(IUNIT, VARP, VART, NOW, ILOC, K1, K2, MSG)
Definition: mod_par.f90:317
subroutine aprint_vec(IUNIT, VARP, VART, NOW, ILOC, MSG)
Definition: mod_par.f90:145
integer nhn
Definition: mod_par.f90:86
integer, dimension(:), pointer egid_x
Definition: mod_par.f90:62