PartMC  2.3.0
spec_file.F90
Go to the documentation of this file.
1 ! Copyright (C) 2007-2011 Nicole Riemer and Matthew West
2 ! Licensed under the GNU General Public License version 2 or (at your
3 ! option) any later version. See the file COPYING for details.
4 
5 !> \file
6 !> The pmc_spec_file module.
7 
8 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
9 
10 !> \page spec_file_format Input File Format: Spec File Format
11 !!
12 !! All PartMC input files are in a text format. Each line consists of
13 !! a <b>parameter name</b>, followed by the <b>parameter value</b>,
14 !! and an optional comment starting with the # character. Blank lines
15 !! and comment-only lines are permitted, and everything on a line
16 !! after a # is completely ignored.
17 !!
18 !! Parameter names are strings (normally lowercase) without spaces,
19 !! such as \c output_prefix or \c del_t. The case of parameter names
20 !! is significant. The order of parameters in a file is not
21 !! arbitrary. Instead, they must come in the prescribed order and
22 !! cannot be skipped or rearranged.
23 !!
24 !! The parameter types are:
25 !! - \b string: a single string without spaces (case is significant)
26 !! - \b logical: a true/false value that can be the exact values
27 !! "yes", "y", "true", "t", or "1" (for true values), or "no",
28 !! "n", "false", "f", or "0" (for false values
29 !! - \b integer: a positive or negative integer (depending on
30 !! whether PartMC was compiled as 32bit or 64bit the maximum size
31 !! will vary)
32 !! - \b real: a floating point real number in Fortran syntax,
33 !! e.g. -1.45, 5.27e10 (the available precision and range is that
34 !! of whatever double precision meant during the compilation)
35 !! - \b complex: two real numbers separated by a space, giving the
36 !! real and imaginary parts of a complex number, respectively
37 !! - <b>real array</b>: a list of real numbers separated by spaces,
38 !! giving the entries of the array
39 
40 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
41 
42 !> Reading formatted text input.
44 
45  use pmc_spec_line
46  use pmc_util
47 
48  !> Maximum number of lines in an array.
49  integer, parameter :: SPEC_FILE_MAX_LIST_LINES = 1000
50 
51  !> An input file with extra data for printing messages.
52  !!
53  !! An spec_file_t is just a simple wrapper around a Fortran unit
54  !! number together with the filename and current line number. The
55  !! line number is updated manually by the various \c spec_file_*()
56  !! subroutine. To maintain its validity all file accesses must be
57  !! done via the \c spec_file_*() subroutines, and no data should be
58  !! accessed directly via \c spec_file%%unit.
60  !> Filename.
61  character(len=SPEC_LINE_MAX_VAR_LEN) :: name
62  !> Attached unit.
63  integer :: unit
64  !> Current line number.
65  integer :: line_num
66  end type spec_file_t
67 
68 contains
69 
70 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
71 
72  !> Exit with an error message containing filename and line number.
73  subroutine spec_file_die_msg(code, file, msg)
74 
75  !> Failure status code.
76  integer, intent(in) :: code
77  !> Spec file.
78  type(spec_file_t), intent(in) :: file
79  !> Error message.
80  character(len=*), intent(in) :: msg
81 
82  call spec_file_assert_msg(code, file, .false., msg)
83 
84  end subroutine spec_file_die_msg
85 
86 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
87 
88  !> Exit with an error message containing filename and line number
89  !> if \c condition_ok is \c .false.
90  subroutine spec_file_assert_msg(code, file, condition_ok, msg)
91 
92  !> Failure status code.
93  integer, intent(in) :: code
94  !> Spec file.
95  type(spec_file_t), intent(in) :: file
96  !> Whether the assertion is ok.
97  logical, intent(in) :: condition_ok
98  !> Error message.
99  character(len=*), intent(in) :: msg
100 
101  if (.not. condition_ok) then
102  call die_msg(code, "file " // trim(file%name) // " line " &
103  // trim(integer_to_string(file%line_num)) // ": " // trim(msg))
104  end if
105 
106  end subroutine spec_file_assert_msg
107 
108 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
109 
110  !> Open a spec file for reading.
111  subroutine spec_file_open(filename, file)
112 
113  !> Name of file to open.
114  character(len=*), intent(in) :: filename
115  !> Spec file.
116  type(spec_file_t), intent(out) :: file
117 
118  integer :: ios, unit
119 
120  file%name = trim(filename)
121  file%unit = get_unit()
122  open(unit=file%unit, status='old', file=file%name, iostat=ios)
123  if (ios /= 0) then
124  call die_msg(173932734, "unable to open file " // trim(file%name) &
125  // " for reading: IOSTAT = " // trim(integer_to_string(ios)))
126  end if
127  file%line_num = 0
128 
129  end subroutine spec_file_open
130 
131 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
132 
133  !> Close a spec file.
134  subroutine spec_file_close(file)
135 
136  !> Spec file.
137  type(spec_file_t), intent(in) :: file
138 
139  close(file%unit)
140  call free_unit(file%unit)
141 
142  end subroutine spec_file_close
143 
144 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
145 
146  !> Read a single line from a spec file, signaling if we have hit EOF.
147  subroutine spec_file_read_line_raw(file, line, eof)
148 
149  !> Spec file.
150  type(spec_file_t), intent(inout) :: file
151  !> Complete line read.
152  character(len=*), intent(out) :: line
153  !> True if at EOF.
154  logical, intent(out) :: eof
155 
156  integer :: ios, n_read
157 
158  file%line_num = file%line_num + 1
159  eof = .false.
160  line = "" ! needed for pgf95 for reading blank lines
161  read(unit=file%unit, fmt='(a)', advance='no', end=100, eor=110, &
162  iostat=ios) line
163  if (ios /= 0) then
164  call spec_file_die_msg(869855853, file, &
165  'error reading: IOSTAT = ' // trim(integer_to_string(ios)))
166  end if
167  ! only reach here if we didn't hit end-of-record (end-of-line) in
168  ! the above read, meaning the line was too long
169  call spec_file_die_msg(468785871, file, &
170  'line exceeds length: ' // trim(integer_to_string(len(line))))
171 
172 100 line = "" ! goto here if end-of-file was encountered immediately
173  eof = .true.
174 
175 110 return ! goto here if end-of-record, meaning everything is ok
176 
177  end subroutine spec_file_read_line_raw
178 
179 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
180 
181  !> Read the next line from the spec file that contains useful data
182  !> (stripping comments and blank lines).
183  subroutine spec_file_read_next_data_line(file, line, eof)
184 
185  !> Spec file.
186  type(spec_file_t), intent(inout) :: file
187  !> Complete line read.
188  character(len=*), intent(out) :: line
189  !> True if EOF encountered.
190  logical, intent(out) :: eof
191 
192  logical :: done
193 
194  done = .false.
195  do while (.not. done)
196  call spec_file_read_line_raw(file, line, eof)
197  if (eof) then
198  done = .true.
199  else
200  call spec_line_strip_comment(line)
201  call spec_line_tabs_to_spaces(line)
203  if (len_trim(line) > 0) then
204  done = .true.
205  end if
206  end if
207  end do
208 
209  end subroutine spec_file_read_next_data_line
210 
211 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
212 
213  !> Read a spec_line from the spec_file.
214  subroutine spec_file_read_line(file, line, eof)
215 
216  !> Spec file.
217  type(spec_file_t), intent(inout) :: file
218  !> Spec line.
219  type(spec_line_t), intent(inout) :: line
220  !> True if EOF encountered.
221  logical, intent(out) :: eof
222 
223  character(len=SPEC_LINE_MAX_LEN) :: line_string, rest
224  integer i, n_data
225  logical done
226 
227  call spec_file_read_next_data_line(file, line_string, eof)
228  if (eof) return
229 
230  ! strip off the name
231  i = index(line_string, ' ') ! first space
232  if (i == 0) then
233  call spec_file_die_msg(117442928, file, 'line contains no whitespace')
234  end if
235  if (i == 1) then
236  call spec_file_die_msg(650916702, file, 'line starts with whitespace')
237  end if
238  if (i >= spec_line_max_var_len) then
239  call spec_file_die_msg(170403881, file, 'line name longer than: ' &
240  // trim(integer_to_string(spec_line_max_var_len)))
241  end if
242  line%name = line_string(1:(i-1))
243  line_string = line_string(i:)
244  call spec_line_strip_leading_spaces(line_string)
245 
246  ! figure out how many data items we have (consecutive non-spaces)
247  n_data = 0
248  rest = line_string
249  done = .false.
250  do while (.not. done)
251  if (len_trim(rest) == 0) then ! only spaces left
252  done = .true.
253  else
254  ! strip the data element
255  n_data = n_data + 1
256  i = index(rest, ' ') ! first space
257  rest = rest(i:)
259  end if
260  end do
261 
262  ! allocate the data and read out the data items
263  call spec_line_deallocate(line)
264  call spec_line_allocate_size(line, n_data)
265  n_data = 0
266  rest = line_string
267  done = .false.
268  do while (.not. done)
269  if (len_trim(rest) == 0) then ! only spaces left
270  done = .true.
271  else
272  ! strip the data element
273  n_data = n_data + 1
274  i = index(rest, ' ') ! first space
275  if (i <= 1) then
276  call spec_file_die_msg(332939443, file, &
277  'internal processing error')
278  end if
279  if (i >= spec_line_max_var_len) then
280  call spec_file_die_msg(145508629, file, &
281  'data element ' // trim(integer_to_string(n_data)) &
282  // ' longer than: ' &
283  // trim(integer_to_string(spec_line_max_var_len)))
284  end if
285  line%data(n_data) = rest(1:(i-1))
286  rest = rest(i:)
288  end if
289  end do
290 
291  end subroutine spec_file_read_line
292 
293 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
294 
295  !> Read a spec_line from the spec_file. This will always succeed or
296  !> error out, so should only be called if we know there should be a
297  !> valid line coming.
298  subroutine spec_file_read_line_no_eof(file, line)
299 
300  !> Spec file.
301  type(spec_file_t), intent(inout) :: file
302  !> Spec line.
303  type(spec_line_t), intent(inout) :: line
304 
305  logical :: eof
306 
307  call spec_file_read_line(file, line, eof)
308  if (eof) then
309  call spec_file_die_msg(358475502, file, 'unexpected end of file')
310  end if
311 
312  end subroutine spec_file_read_line_no_eof
313 
314 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
315 
316  !> Read a list of spec_lines from a file, stopping at max_lines
317  !> or EOF, whichever comes first.
318  subroutine spec_file_read_line_list(file, max_lines, line_list)
319 
320  !> Spec file.
321  type(spec_file_t), intent(inout) :: file
322  !> Max lines to read (0 = no max).
323  integer, intent(in) :: max_lines
324  !> List of spec_lines.
325  type(spec_line_t), pointer :: line_list(:)
326 
327  logical :: eof
328  integer :: i, num_lines
329  type(spec_line_t) :: temp_line_list(spec_file_max_list_lines)
330 
331  ! read file, working out how many lines we have
332  num_lines = 0
333  eof = .false.
334  call spec_line_allocate(temp_line_list(num_lines + 1))
335  call spec_file_read_line(file, temp_line_list(num_lines + 1), eof)
336  if (eof) then
337  call spec_line_deallocate(temp_line_list(num_lines + 1))
338  end if
339  do while (.not. eof)
340  num_lines = num_lines + 1
341  if (num_lines > spec_file_max_list_lines) then
342  call spec_file_die_msg(450564159, file, &
343  'maximum number of lines exceeded')
344  end if
345  if (max_lines > 0) then
346  if (num_lines >= max_lines) then
347  eof = .true.
348  end if
349  end if
350  if (.not. eof) then
351  call spec_line_allocate(temp_line_list(num_lines + 1))
352  call spec_file_read_line(file, temp_line_list(num_lines + 1), eof)
353  if (eof) then
354  call spec_line_deallocate(temp_line_list(num_lines + 1))
355  end if
356  end if
357  end do
358 
359  ! copy data to actual list
360  do i = 1,size(line_list)
361  call spec_line_deallocate(line_list(i))
362  end do
363  deallocate(line_list)
364  allocate(line_list(num_lines))
365  do i = 1,num_lines
366  call spec_line_allocate(line_list(i))
367  call spec_line_copy(temp_line_list(i), line_list(i))
368  call spec_line_deallocate(temp_line_list(i))
369  end do
370 
371  end subroutine spec_file_read_line_list
372 
373 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
374 
375  !> Read an array of spec_lines from a file, stopping at max_lines
376  !> or EOF. All lines must have the same number of elements.
377  subroutine spec_file_read_line_array(file, max_lines, line_array)
378 
379  !> Spec file.
380  type(spec_file_t), intent(inout) :: file
381  !> Max lines to read (0 = no max).
382  integer, intent(in) :: max_lines
383  !> Array of spec_lines,.
384  type(spec_line_t), pointer :: line_array(:)
385 
386  integer :: i, line_length
387 
388  call spec_file_read_line_list(file, max_lines, line_array)
389  if (size(line_array) > 0) then
390  line_length = size(line_array(1)%data)
391  do i = 2,size(line_array)
392  if (size(line_array(i)%data) /= line_length) then
393  call spec_file_die_msg(298076484, file, &
394  'lines have unequal numbers of entries for array')
395  end if
396  end do
397  end if
398 
399  end subroutine spec_file_read_line_array
400 
401 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
402 
403  !> Check that the name of the line data is as given.
404  subroutine spec_file_check_line_name(file, line, name)
405 
406  !> Spec file.
407  type(spec_file_t), intent(in) :: file
408  !> Spec line.
409  type(spec_line_t), intent(in) :: line
410  !> Expected line name.
411  character(len=*), intent(in) :: name
412 
413  if (line%name /= name) then
414  call spec_file_die_msg(462932478, file, &
415  'line must begin with: ' // trim(name) &
416  // ' not: ' // trim(line%name))
417  end if
418 
419  end subroutine spec_file_check_line_name
420 
421 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
422 
423  !> Checks that the read_name is the same as name.
424  subroutine spec_file_check_name(file, name, read_name)
425 
426  !> Spec file.
427  type(spec_file_t), intent(inout) :: file
428  !> Name that we should have.
429  character(len=*), intent(in) :: name
430  !> Name that we do have.
431  character(len=*), intent(in) :: read_name
432 
433  integer name_len, read_name_len
434 
435  if (name /= read_name) then
436  call spec_file_die_msg(683719069, file, &
437  'line must begin with: ' // trim(name) &
438  // ' not: ' // trim(read_name))
439  end if
440 
441  end subroutine spec_file_check_name
442 
443 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
444 
445  !> Check that the length of the line data is as given.
446  subroutine spec_file_check_line_length(file, line, length)
447 
448  !> Spec file.
449  type(spec_file_t), intent(in) :: file
450  !> Spec line.
451  type(spec_line_t), intent(in) :: line
452  !> Expected data length.
453  integer, intent(in) :: length
454 
455  if (size(line%data) /= length) then
456  call spec_file_die_msg(189339129, file, 'expected ' &
457  // trim(integer_to_string(length)) // ' data items on line')
458  end if
459 
460  end subroutine spec_file_check_line_length
461 
462 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
463 
464  !> Check the IOSTAT and error if it is bad.
465  subroutine spec_file_check_read_iostat(file, ios, type)
466 
467  !> Spec file.
468  type(spec_file_t), intent(in) :: file
469  !> Iostat result.
470  integer, intent(in) :: ios
471  !> Type being read during error.
472  character(len=*), intent(in) :: type
473 
474  if (ios /= 0) then
475  call spec_file_die_msg(704342497, file, &
476  'error reading: IOSTAT = ' // trim(integer_to_string(ios)))
477  end if
478 
479  end subroutine spec_file_check_read_iostat
480 
481 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
482 
483  !> Convert a string to an integer.
484  integer function spec_file_string_to_integer(file, string)
485 
486  !> Spec file.
487  type(spec_file_t), intent(in) :: file
488  !> String to convert.
489  character(len=*), intent(in) :: string
490 
491  integer :: val
492  integer :: ios
493 
494  read(string, '(i20)', iostat=ios) val
495  call spec_file_check_read_iostat(file, ios, "integer")
497 
498  end function spec_file_string_to_integer
499 
500 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
501 
502  !> Convert a string to an real.
503  real(kind=dp) function spec_file_string_to_real(file, string)
504 
505  !> Spec file.
506  type(spec_file_t), intent(in) :: file
507  !> String to convert.
508  character(len=*), intent(in) :: string
509 
510  real(kind=dp) :: val
511  integer :: ios
512 
513  read(string, '(f30.0)', iostat=ios) val
514  call spec_file_check_read_iostat(file, ios, "real")
516 
517  end function spec_file_string_to_real
518 
519 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
520 
521  !> Convert a string to an logical.
522  logical function spec_file_string_to_logical(file, string)
523 
524  !> Spec file.
525  type(spec_file_t), intent(in) :: file
526  !> String to convert.
527  character(len=*), intent(in) :: string
528 
529  logical :: val
530  integer :: ios
531 
532  val = .false.
533  if ((trim(string) == 'yes') &
534  .or. (trim(string) == 'y') &
535  .or. (trim(string) == 'true') &
536  .or. (trim(string) == 't') &
537  .or. (trim(string) == '1')) then
538  val = .true.
539  elseif ((trim(string) == 'no') &
540  .or. (trim(string) == 'n') &
541  .or. (trim(string) == 'false') &
542  .or. (trim(string) == 'f') &
543  .or. (trim(string) == '0')) then
544  val = .false.
545  else
546  call spec_file_check_read_iostat(file, 1, "logical")
547  end if
549 
550  end function spec_file_string_to_logical
551 
552 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
553 
554  !> Read an integer from a spec file that must have the given name.
555  subroutine spec_file_read_integer(file, name, var)
556 
557  !> Spec file.
558  type(spec_file_t), intent(inout) :: file
559  !> Name.
560  character(len=*), intent(in) :: name
561  !> Variable to store data.
562  integer, intent(out) :: var
563 
564  type(spec_line_t) :: line
565 
566  call spec_line_allocate(line)
567  call spec_file_read_line_no_eof(file, line)
568  call spec_file_check_line_name(file, line, name)
569  call spec_file_check_line_length(file, line, 1)
570  var = spec_file_string_to_integer(file, line%data(1))
571  call spec_line_deallocate(line)
572 
573  end subroutine spec_file_read_integer
574 
575 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
576 
577  !> Read a real number from a spec file that must have the given
578  !> name.
579  subroutine spec_file_read_real(file, name, var)
580 
581  !> Spec file.
582  type(spec_file_t), intent(inout) :: file
583  !> Name.
584  character(len=*), intent(in) :: name
585  !> Variable to store data.
586  real(kind=dp), intent(out) :: var
587 
588  type(spec_line_t) :: line
589 
590  call spec_line_allocate(line)
591  call spec_file_read_line_no_eof(file, line)
592  call spec_file_check_line_name(file, line, name)
593  call spec_file_check_line_length(file, line, 1)
594  var = spec_file_string_to_real(file, line%data(1))
595  call spec_line_deallocate(line)
596 
597  end subroutine spec_file_read_real
598 
599 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
600 
601  !> Read a logical from a spec file that must have a given name.
602  subroutine spec_file_read_logical(file, name, var)
603 
604  !> Spec file.
605  type(spec_file_t), intent(inout) :: file
606  !> Name.
607  character(len=*), intent(in) :: name
608  !> Variable to store data.
609  logical, intent(out) :: var
610 
611  type(spec_line_t) :: line
612 
613  call spec_line_allocate(line)
614  call spec_file_read_line_no_eof(file, line)
615  call spec_file_check_line_name(file, line, name)
616  call spec_file_check_line_length(file, line, 1)
617  var = spec_file_string_to_logical(file, line%data(1))
618  call spec_line_deallocate(line)
619 
620  end subroutine spec_file_read_logical
621 
622 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
623 
624  !> Read a string from a spec file that must have a given name.
625  subroutine spec_file_read_string(file, name, var)
626 
627  !> Spec file.
628  type(spec_file_t), intent(inout) :: file
629  !> Name.
630  character(len=*), intent(in) :: name
631  !> Variable to store data.
632  character(len=*), intent(out) :: var
633 
634  type(spec_line_t) :: line
635 
636  call spec_line_allocate(line)
637  call spec_file_read_line_no_eof(file, line)
638  call spec_file_check_line_name(file, line, name)
639  call spec_file_check_line_length(file, line, 1)
640  var = line%data(1)
641  call spec_line_deallocate(line)
642 
643  end subroutine spec_file_read_string
644 
645 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
646 
647  !> Read a complex number from a spec file that must have the given
648  !> name.
649  subroutine spec_file_read_complex(file, name, var)
650 
651  !> Spec file.
652  type(spec_file_t), intent(inout) :: file
653  !> Name.
654  character(len=*), intent(in) :: name
655  !> Variable to store data.
656  complex(kind=dc), intent(out) :: var
657 
658  type(spec_line_t) :: line
659 
660  call spec_line_allocate(line)
661  call spec_file_read_line_no_eof(file, line)
662  call spec_file_check_line_name(file, line, name)
663  call spec_file_check_line_length(file, line, 2)
664  var = cmplx(spec_file_string_to_real(file, line%data(1)), &
665  spec_file_string_to_real(file, line%data(2)), kind=dc)
666  call spec_line_deallocate(line)
667 
668  end subroutine spec_file_read_complex
669 
670 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
671 
672  !> Read an array of named lines with real data. All lines must have
673  !> the same number of data elements.
674  subroutine spec_file_read_real_named_array(file, max_lines, names, vals)
675 
676  !> Spec file.
677  type(spec_file_t), intent(inout) :: file
678  !> Max lines to read (0 = no max).
679  integer, intent(in) :: max_lines
680  !> Names of lines.
681  character(len=SPEC_LINE_MAX_VAR_LEN), pointer :: names(:)
682  !> Data values.
683  real(kind=dp), pointer :: vals(:,:)
684 
685  type(spec_line_t), pointer :: line_array(:)
686  integer :: num_lines, line_length, i, j
687 
688  allocate(line_array(0))
689  call spec_file_read_line_array(file, max_lines, line_array)
690  num_lines = size(line_array)
691  deallocate(names)
692  deallocate(vals)
693  if (num_lines > 0) then
694  line_length = size(line_array(1)%data)
695  allocate(names(num_lines))
696  allocate(vals(num_lines, line_length))
697  do i = 1,num_lines
698  names(i) = line_array(i)%name
699  do j = 1,line_length
700  vals(i,j) = spec_file_string_to_real(file, line_array(i)%data(j))
701  end do
702  end do
703  else
704  allocate(names(0))
705  allocate(vals(0,0))
706  end if
707  do i = 1,num_lines
708  call spec_line_deallocate(line_array(i))
709  end do
710  deallocate(line_array)
711 
712  end subroutine spec_file_read_real_named_array
713 
714 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
715 
716  !> Read an a time-indexed array of real data.
717  subroutine spec_file_read_timed_real_array(file, name, times, vals)
718 
719  !> Spec file.
720  type(spec_file_t), intent(inout) :: file
721  !> Variable name.
722  character(len=*), intent(in) :: name
723  !> Names of lines.
724  real(kind=dp), pointer :: times(:)
725  !> Data values.
726  real(kind=dp), pointer :: vals(:)
727 
728  integer :: n_lines, n_times
729  character(len=SPEC_LINE_MAX_VAR_LEN), pointer :: read_names(:)
730  real(kind=dp), pointer :: read_data(:,:)
731 
732  allocate(read_names(0))
733  allocate(read_data(0,0))
734  call spec_file_read_real_named_array(file, 0, read_names, read_data)
735 
736  n_lines = size(read_names)
737  if (n_lines /= 2) then
738  call die_msg(694159200, 'must have exactly two data lines in file ' &
739  // trim(file%name))
740  end if
741  n_times = size(read_data,2)
742  if (n_times < 1) then
743  call die_msg(925956383, 'must have at least one data poin in file ' &
744  // trim(file%name))
745  end if
746  if (trim(read_names(1)) /= "time") then
747  call die_msg(407039398, 'first data line in ' // trim(file%name) &
748  // ' must start with: time not: ' // trim(read_names(1)))
749  end if
750  if (trim(read_names(2)) /= name) then
751  call die_msg(692842968, 'second data line in ' // trim(file%name) &
752  // ' must start with: ' // trim(name) &
753  // ' not: ' // trim(read_names(2)))
754  end if
755 
756  deallocate(times)
757  deallocate(vals)
758  allocate(times(n_times))
759  allocate(vals(n_times))
760  times = read_data(1,:)
761  vals = read_data(2,:)
762  deallocate(read_names)
763  deallocate(read_data)
764 
765  end subroutine spec_file_read_timed_real_array
766 
767 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
768 
769 end module pmc_spec_file
An input file with extra data for printing messages.
Definition: spec_file.F90:59
subroutine spec_line_strip_comment(string)
Strip the comments from a string. Comments are everything after the first # character.
Definition: spec_line.F90:98
subroutine spec_file_check_line_name(file, line, name)
Check that the name of the line data is as given.
Definition: spec_file.F90:404
subroutine die_msg(code, error_msg)
Error immediately.
Definition: util.F90:133
subroutine spec_file_open(filename, file)
Open a spec file for reading.
Definition: spec_file.F90:111
subroutine spec_file_read_timed_real_array(file, name, times, vals)
Read an a time-indexed array of real data.
Definition: spec_file.F90:717
subroutine spec_file_assert_msg(code, file, condition_ok, msg)
Exit with an error message containing filename and line number if condition_ok is ...
Definition: spec_file.F90:90
subroutine spec_line_strip_leading_spaces(string)
Strip leading spaces from a string.
Definition: spec_line.F90:134
A single line of input data, split at whitespace.
Definition: spec_line.F90:27
subroutine spec_file_read_complex(file, name, var)
Read a complex number from a spec file that must have the given name.
Definition: spec_file.F90:649
subroutine spec_file_read_integer(file, name, var)
Read an integer from a spec file that must have the given name.
Definition: spec_file.F90:555
subroutine spec_file_check_line_length(file, line, length)
Check that the length of the line data is as given.
Definition: spec_file.F90:446
subroutine spec_file_read_line_array(file, max_lines, line_array)
Read an array of spec_lines from a file, stopping at max_lines or EOF. All lines must have the same n...
Definition: spec_file.F90:377
subroutine spec_line_copy(from_spec_line, to_spec_line)
Copies a spec_line.
Definition: spec_line.F90:77
logical function spec_file_string_to_logical(file, string)
Convert a string to an logical.
Definition: spec_file.F90:522
subroutine spec_file_read_real_named_array(file, max_lines, names, vals)
Read an array of named lines with real data. All lines must have the same number of data elements...
Definition: spec_file.F90:674
subroutine spec_file_check_name(file, name, read_name)
Checks that the read_name is the same as name.
Definition: spec_file.F90:424
Common utility subroutines.
Definition: util.F90:9
subroutine spec_line_tabs_to_spaces(string)
Expand all tabs in a string into single spaces (one tab makes one space).
Definition: spec_line.F90:116
subroutine spec_file_read_string(file, name, var)
Read a string from a spec file that must have a given name.
Definition: spec_file.F90:625
integer function spec_file_string_to_integer(file, string)
Convert a string to an integer.
Definition: spec_file.F90:484
subroutine spec_file_read_next_data_line(file, line, eof)
Read the next line from the spec file that contains useful data (stripping comments and blank lines)...
Definition: spec_file.F90:183
subroutine spec_file_read_logical(file, name, var)
Read a logical from a spec file that must have a given name.
Definition: spec_file.F90:602
character(len=pmc_util_convert_string_len) function integer_to_string(val)
Convert an integer to a string format.
Definition: util.F90:743
A single line of formatted test for input.
Definition: spec_line.F90:9
subroutine spec_file_check_read_iostat(file, ios, type)
Check the IOSTAT and error if it is bad.
Definition: spec_file.F90:465
subroutine spec_file_read_line_list(file, max_lines, line_list)
Read a list of spec_lines from a file, stopping at max_lines or EOF, whichever comes first...
Definition: spec_file.F90:318
Reading formatted text input.
Definition: spec_file.F90:43
subroutine spec_file_close(file)
Close a spec file.
Definition: spec_file.F90:134
integer function get_unit()
Returns an available unit number. This should be freed by free_unit().
Definition: util.F90:147
subroutine spec_line_allocate_size(spec_line, n_data)
Allocates memory for a spec_line of the given size.
Definition: spec_line.F90:51
subroutine spec_line_allocate(spec_line)
Allocates memory for a spec_line.
Definition: spec_line.F90:39
real(kind=dp) function spec_file_string_to_real(file, string)
Convert a string to an real.
Definition: spec_file.F90:503
subroutine spec_file_read_line(file, line, eof)
Read a spec_line from the spec_file.
Definition: spec_file.F90:214
subroutine spec_file_die_msg(code, file, msg)
Exit with an error message containing filename and line number.
Definition: spec_file.F90:73
subroutine spec_line_deallocate(spec_line)
Frees all storage.
Definition: spec_line.F90:65
subroutine spec_file_read_line_no_eof(file, line)
Read a spec_line from the spec_file. This will always succeed or error out, so should only be called ...
Definition: spec_file.F90:298
subroutine spec_file_read_real(file, name, var)
Read a real number from a spec file that must have the given name.
Definition: spec_file.F90:579
subroutine free_unit(unit)
Frees a unit number returned by get_unit().
Definition: util.F90:171
subroutine spec_file_read_line_raw(file, line, eof)
Read a single line from a spec file, signaling if we have hit EOF.
Definition: spec_file.F90:147