MFIX  2016-1
open_files.f
Go to the documentation of this file.
1 !vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv!
2 ! !
3 ! Module name: OPEN_FILES !
4 ! Author: P. Nicoletti Date: 12-DEC-91 !
5 ! !
6 ! Purpose: open all the files for this run !
7 ! !
8 !^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^!
9  SUBROUTINE open_files(RUN_NAME, RUN_TYPE, N_SPX)
10 
11  USE machine
12  USE funits
13  USE compar
14  USE cdist
15 
16  use error_manager
17 
18  IMPLICIT NONE
19 
20 ! Error index: 0 - no error, 1 could not open file
21  INTEGER :: IER(0:numpes-1)
22 ! RUN_NAME (as specified in input file)
23  CHARACTER(LEN=*) :: RUN_NAME
24 ! Run_type (as specified in input file)
25  CHARACTER(LEN=*) :: RUN_TYPE
26 ! Number of single precision output files (param.inc)
27  INTEGER :: N_SPX
28 ! local variables
29  CHARACTER(len=4) :: EXT
30 ! run_name + extension
31  CHARACTER(len=255) :: FILE_NAME
32 ! Loop counter
33  INTEGER :: LC
34 ! index to first blank character in run_name
35  INTEGER :: NB
36  CHARACTER(len=35) :: EXT_END
37  CHARACTER(len=10) :: CSTATUS
38 ! Character error code.
39  CHARACTER(len=32) :: CER
40 !-----------------------------------------------
41 
42 
43 ! Initialize the error manager.
44  CALL init_err_msg("OPEN_FILES")
45 
46 ! Initialize the error flag array.
47  ier = 0
48 
49 ! Initialize the generic SPx extension.
50  ext = '.SPx'
51 
52 ! Generic SPx end characters in order.
53  ext_end = '123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
54 
55 ! Get the length of RUN_NAME. Note that len_trim would allow the
56 ! name to still contain spaces. The following approach truncates
57 ! RUN_NAME at the first blank character.
58  nb = index(run_name,' ')
59 
60 ! Only PE_IO opens the RUN_NAME.OUT file.
61  IF(mype == pe_io) CALL open_file (run_name, nb, unit_out, '.OUT',&
62  file_name, 'UNKNOWN', 'SEQUENTIAL','FORMATTED',132, ier(mype))
63 
64 ! Check if there was an error opening the file.
65  IF(error_opening(ier)) THEN
66  WRITE(err_msg,3000)
67  CALL flush_err_msg(abort=.true.)
68  ENDIF
69 
70 
71 ! Open the RES and SPx files. By default, only PE_IO opens these files,
72 ! but all ranks open a rank-specific copy for distributed IO runs.
73  SELECT CASE (trim(run_type))
74 
75 ! Open the RES and SPx files for a new run.
76 !......................................................................
77  CASE ('NEW')
78 
79  IF(mype==pe_io .OR. bdist_io) THEN
80 
81 ! Open the RES file.
82  CALL open_file (run_name, nb, unit_res, '.RES', file_name, &
83  'NEW', 'DIRECT', 'UNFORMATTED', open_n1, ier(mype))
84 ! Report errors.
85  IF (ier(mype) == 100) THEN
86  WRITE(err_msg, 1000)'RES', 'NEW', trim(file_name)
87  CALL flush_err_msg
88  GO TO 100
89  ELSEIF(ier(mype) /= 0) THEN
90  cer=''; WRITE(cer,*)
91  WRITE(err_msg, 2000) trim(file_name), trim(cer)
92  CALL flush_err_msg
93  GO TO 100
94  ENDIF
95 
96 ! Open the SPx files.
97  DO lc = 1, n_spx
98  ext(4:4) = ext_end(lc:lc)
99  CALL open_file(run_name, nb, unit_spx+lc, ext,file_name,&
100  'NEW', 'DIRECT', 'UNFORMATTED', open_n1, ier(mype))
101 ! Report errors.
102  IF (ier(mype) == 100) THEN
103  WRITE(err_msg, 1000)ext(2:4), 'NEW', trim(file_name)
104  CALL flush_err_msg
105  GO TO 100
106  ELSEIF(ier(mype) /= 0) THEN
107  cer=''; WRITE(cer,*)
108  WRITE(err_msg, 2000) trim(file_name), trim(cer)
109  CALL flush_err_msg
110  GO TO 100
111  ENDIF
112  ENDDO
113  ENDIF
114 
115 
116 ! Open the RES and SPx files for a typical restart run.
117 !......................................................................
118  CASE ('RESTART_1')
119 
120 ! Open the RES file.
121  IF(mype == pe_io .or. bdist_io) THEN
122  CALL open_file(run_name, nb, unit_res, '.RES', file_name, &
123  'OLD', 'DIRECT', 'UNFORMATTED', open_n1, ier(mype))
124 ! Report errors.
125  IF (ier(mype) == 101) THEN
126  WRITE(err_msg, 1001)'RES', 'RESTART_1',trim(file_name)
127  CALL flush_err_msg
128  GO TO 100
129  ELSEIF(ier(mype) /= 0) THEN
130  cer=''; WRITE(cer,*)
131  WRITE(err_msg, 2000) trim(file_name), trim(cer)
132  CALL flush_err_msg
133  GO TO 100
134  ENDIF
135 
136 ! Open the SPx files.
137  DO lc = 1, n_spx
138  ext(4:4) = ext_end(lc:lc)
139  CALL open_file (run_name,nb, unit_spx+lc,ext, file_name,&
140  'OLD', 'DIRECT', 'UNFORMATTED', open_n1, ier(mype))
141 ! Report errors.
142  IF (ier(mype) == 101) THEN
143  WRITE(err_msg, 1001) ext(2:4), 'RESTART_1', &
144  trim(file_name)
145  CALL flush_err_msg
146  GO TO 100
147  ELSEIF(ier(mype) /= 0) THEN
148  cer=''; WRITE(cer,*)
149  WRITE(err_msg, 2000) trim(file_name), trim(cer)
150  CALL flush_err_msg
151  GO TO 100
152  ENDIF
153  END DO
154  ENDIF
155 
156 
157 ! Open the RES and SPx files for a typical restart run.
158 !......................................................................
159  CASE ('RESTART_2')
160 ! Open the RES file.
161  cstatus = 'OLD'
162  IF(mype == pe_io .OR. bdist_io) THEN
163  IF(bstart_with_one_res) cstatus = 'UNKNOWN'
164  CALL open_file (run_name, nb, unit_res, '.RES', file_name, &
165  cstatus,'DIRECT', 'UNFORMATTED', open_n1, ier(mype))
166 ! Report errors.
167  IF (ier(mype) == 101) THEN
168  WRITE(err_msg, 1001)'RES', 'RESTART_2',trim(file_name)
169  CALL flush_err_msg
170  GO TO 100
171  ELSEIF(ier(mype) /= 0) THEN
172  cer=''; WRITE(cer,*)
173  WRITE(err_msg, 2000) trim(file_name), trim(cer)
174  CALL flush_err_msg
175  GO TO 100
176  ENDIF
177 
178 ! Open the SPx files.
179  DO lc = 1, n_spx
180  ext(4:4) = ext_end(lc:lc)
181  CALL open_file (run_name,nb,unit_spx+lc, ext, file_name,&
182  'NEW' , 'DIRECT', 'UNFORMATTED', open_n1, ier(mype))
183 ! Report errors.
184  IF (ier(mype) == 100) THEN
185  WRITE(err_msg, 1000)ext(2:4), 'RESTART_2', &
186  trim(file_name)
187  CALL flush_err_msg
188  GO TO 100
189  ELSEIF(ier(mype) /= 0) THEN
190  cer=''; WRITE(cer,*)
191  WRITE(err_msg, 2000) trim(file_name), trim(cer)
192  CALL flush_err_msg
193  GO TO 100
194  ENDIF
195  END DO
196  ENDIF
197 
198  CASE DEFAULT
199  WRITE(err_msg, 3000)
200  CALL flush_err_msg
201  GO TO 100
202 
203  END SELECT
204 
205 ! If an error was detected, abort the run.
206  100 IF(error_opening(ier)) CALL mfix_exit(mype)
207 
208 ! Initialize the error manager.
209  CALL finl_err_msg
210 
211  RETURN
212 
213  1000 FORMAT('Error 1000: ',a,' file detected but RUN_TYPE=',a/, &
214  'Cannot open file: ',a)
215 
216  1001 FORMAT('Error 1001: ',a,' file missing for RUN_TYPE=',a/, &
217  'Cannot open file: ',a)
218 
219  2000 FORMAT('Error 2000: Unknown error opening file ',a,/ &
220  'Error code: ',a)
221 
222  3000 FORMAT('Error 3000: Unknown run type: ',a)
223 
224 
225  CONTAINS
226 
227 
228 !``````````````````````````````````````````````````````````````````````!
229 ! FUNCTION: ERROR_OPENING !
230 ! Purpose: Collect the error flags from all processes and sum them. !
231 ! RESULT: .TRUE. :: Sum of IER over all processes is non-zero. !
232 ! .FALSE. :: GLOBAL_ALL_SUM is zero. !
233 ! !
234 !......................................................................!
235  LOGICAL FUNCTION error_opening(IER_l)
237 ! MPI Wrapper function.
238  use mpi_utility, only: global_all_sum
239 
240 ! Array containing error flags from all ranks.
241  INTEGER, INTENT(IN) :: IER_L(0:numpes-1)
242 ! Initialize error flags.
243  error_opening = .false.
244 ! Globally collect flags.
245  CALL global_all_sum(ier)
246 ! Report errors.
247  IF(sum(ier_l) /= 0) error_opening = .true.
248 
249  RETURN
250  END FUNCTION error_opening
251 
252  END SUBROUTINE open_files
253 
254 
255 !vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv!
256 ! !
257 ! Module name: OPEN_PE_LOG !
258 ! Author: P. Nicoletti Date: 12-DEC-91 !
259 ! !
260 ! Purpose: Every rank open a .LOG file for domain specific errors. !
261 ! This routine should only be invoked before writing to the log and !
262 ! exiting. !
263 ! !
264 ! This routine only opens files when the following are met: !
265 ! (1) MFIX is run in DMP parallel (MPI) !
266 ! (2) ENABLE_DMP_LOG is not set in the mfix.dat file. !
267 ! !
268 !^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^!
269  SUBROUTINE open_pe_log(IER)
271 ! Global Variables:
272 !---------------------------------------------------------------------//
273 ! File unit for LOG files.
274  USE funits, only: unit_log
275 ! User specifed run name
276  USE run, only: run_name
277 ! MPI Rank of current process.
278  USE compar, only: mype
279 ! Total number of MPI ranks.
280  USE compar, only: numpes
281 ! Flag: My rank reports errors.
282  use funits, only: dmp_log
283 ! Flag: The log had to be opened.
284  use funits, only: log_was_closed
285 
286  IMPLICIT NONE
287 
288 ! Dummy Arguments:
289 !---------------------------------------------------------------------//
290 ! Error index.
291  INTEGER, INTENT(inout) :: IER
292 
293 ! Local Variables:
294 !---------------------------------------------------------------------//
295 ! Log file name.
296  CHARACTER(len=255) :: LOGFILE
297  CHARACTER(len=255) :: FILE_NAME
298 ! Flag for LOG files that are already open.
299  LOGICAL :: DO_NOTHING
300 ! Index of first blank character in RUN_NAME
301  INTEGER :: NB
302 !......................................................................!
303 
304 
305 ! Enable output from this rank.
306  dmp_log = .true.
307 
308 ! Return to the caller if this rank is already connect to a log file.
309  INQUIRE(unit=unit_log, opened=do_nothing)
310  IF(do_nothing) RETURN
311 
312 ! Flag that the log had to be opened.
313  log_was_closed = .true.
314 
315 ! Verify the length of user-provided name.
316  logfile = ''
317  nb = index(run_name,' ')
318 
319 ! Specify the .LOG file name based on MPI Rank extenion.
320  IF(numpes == 1) THEN
321  WRITE(logfile,"(A)")run_name(1:(nb-1))
322  ELSEIF(numpes < 10) THEN
323  WRITE(logfile,"(A,'_',I1.1)") run_name(1:(nb-1)), mype
324  ELSEIF(numpes < 100) THEN
325  WRITE(logfile,"(A,'_',I2.2)") run_name(1:(nb-1)), mype
326  ELSEIF(numpes < 1000) THEN
327  WRITE(logfile,"(A,'_',I3.3)") run_name(1:(nb-1)), mype
328  ELSEIF(numpes < 10000) THEN
329  WRITE(logfile,"(A,'_',I4.4)") run_name(1:(nb-1)), mype
330  ELSE
331  WRITE(logfile,"(A,'_',I8.8)") run_name(1:(nb-1)), mype
332  ENDIF
333 
334 ! Open the .LOG file. From here forward, all routines should store
335 ! error messages (at a minimum) in the .LOG file.
336  nb = len_trim(logfile)+1
337  CALL open_file(logfile, nb, unit_log, '.LOG', file_name, &
338  'APPEND', 'SEQUENTIAL', 'FORMATTED', 132, ier)
339 
340  RETURN
341  END SUBROUTINE open_pe_log
342 
343 
344 !vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv!
345 ! !
346 ! Module name: CLOSE_PE_LOG !
347 ! Author: P. Nicoletti Date: 12-DEC-91 !
348 ! !
349 ! Purpose: Every rank open a .LOG file for domain specific errors. !
350 ! This routine should only be invoked before writing to the log and !
351 ! exiting. !
352 ! !
353 ! This routine only opens files when the following are met: !
354 ! (1) MFIX is run in DMP parallel (MPI) !
355 ! (2) ENABLE_DMP_LOG is not set in the mfix.dat file. !
356 ! !
357 !^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^!
358  SUBROUTINE close_pe_log
360 ! Global Variables:
361 !---------------------------------------------------------------------//
362 ! File unit for LOG files.
363  USE funits, only: unit_log
364 ! Flag: My rank reports errors.
365  use funits, only: dmp_log
366 ! Flag: The log had to be opened.
367  use funits, only: log_was_closed
368 
369  IMPLICIT NONE
370 
371 !......................................................................!
372 
373 
374 ! The log had to be opened for global error.
375  IF(log_was_closed) THEN
376 ! Reset the flag.
377  log_was_closed = .false.
378 ! Disable output from this rank and close connection to LOG.
379  dmp_log = .false.
380 ! Return to the caller if this rank is already connect to a log file.
381  CLOSE(unit_log)
382  ENDIF
383 
384  RETURN
385  END SUBROUTINE close_pe_log
logical dmp_log
Definition: funits_mod.f:6
logical function error_opening(IER_l)
Definition: open_files.f:236
logical bdist_io
Definition: cdist_mod.f:4
subroutine finl_err_msg
integer open_n1
Definition: machine_mod.f:5
integer, parameter unit_out
Definition: funits_mod.f:18
subroutine open_files(RUN_NAME, RUN_TYPE, N_SPX)
Definition: open_files.f:10
character(len=60) run_name
Definition: run_mod.f:24
logical bstart_with_one_res
Definition: cdist_mod.f:5
integer numpes
Definition: compar_mod.f:24
subroutine init_err_msg(CALLER)
integer pe_io
Definition: compar_mod.f:30
subroutine open_file(FILENAME, NB, IUNIT, EXT, FULL_NAME, OPEN_STAT, OPEN_ACCESS, OPEN_FORM, IRECL, IER)
Definition: open_file.f:24
Definition: cdist_mod.f:2
integer, parameter unit_spx
Definition: funits_mod.f:30
integer, parameter unit_log
Definition: funits_mod.f:21
Definition: run_mod.f:13
integer mype
Definition: compar_mod.f:24
logical log_was_closed
Definition: funits_mod.f:9
subroutine close_pe_log
Definition: open_files.f:359
character(len=line_length), dimension(line_count) err_msg
integer, parameter unit_res
Definition: funits_mod.f:27
subroutine open_pe_log(IER)
Definition: open_files.f:270
subroutine flush_err_msg(DEBUG, HEADER, FOOTER, ABORT, LOG, CALL_TREE)