PartMC  2.4.0
spec_file.F90
Go to the documentation of this file.
1 ! Copyright (C) 2007-2012 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)
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)
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)
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)
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)
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: ' &
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_set_size(line, n_data)
264  n_data = 0
265  rest = line_string
266  done = .false.
267  do while (.not. done)
268  if (len_trim(rest) == 0) then ! only spaces left
269  done = .true.
270  else
271  ! strip the data element
272  n_data = n_data + 1
273  i = index(rest, ' ') ! first space
274  if (i <= 1) then
275  call spec_file_die_msg(332939443, file, &
276  'internal processing error')
277  end if
278  if (i >= spec_line_max_var_len) then
279  call spec_file_die_msg(145508629, file, &
280  'data element ' // trim(integer_to_string(n_data)) &
281  // ' longer than: ' &
283  end if
284  line%data(n_data) = rest(1:(i-1))
285  rest = rest(i:)
287  end if
288  end do
289 
290  end subroutine spec_file_read_line
291 
292 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
293 
294  !> Read a spec_line from the spec_file. This will always succeed or
295  !> error out, so should only be called if we know there should be a
296  !> valid line coming.
297  subroutine spec_file_read_line_no_eof(file, line)
299  !> Spec file.
300  type(spec_file_t), intent(inout) :: file
301  !> Spec line.
302  type(spec_line_t), intent(inout) :: line
303 
304  logical :: eof
305 
306  call spec_file_read_line(file, line, eof)
307  if (eof) then
308  call spec_file_die_msg(358475502, file, 'unexpected end of file')
309  end if
310 
311  end subroutine spec_file_read_line_no_eof
312 
313 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
314 
315  !> Read a list of spec_lines from a file, stopping at max_lines
316  !> or EOF, whichever comes first.
317  subroutine spec_file_read_line_list(file, max_lines, line_list)
319  !> Spec file.
320  type(spec_file_t), intent(inout) :: file
321  !> Max lines to read (0 = no max).
322  integer, intent(in) :: max_lines
323  !> List of spec_lines.
324  type(spec_line_t), allocatable :: line_list(:)
325 
326  logical :: eof
327  integer :: i, num_lines
328  type(spec_line_t) :: temp_line_list(spec_file_max_list_lines)
329 
330  ! read file, working out how many lines we have
331  num_lines = 0
332  eof = .false.
333  call spec_file_read_line(file, temp_line_list(num_lines + 1), eof)
334  do while (.not. eof)
335  num_lines = num_lines + 1
336  if (num_lines > spec_file_max_list_lines) then
337  call spec_file_die_msg(450564159, file, &
338  'maximum number of lines exceeded')
339  end if
340  if (max_lines > 0) then
341  if (num_lines >= max_lines) then
342  eof = .true.
343  end if
344  end if
345  if (.not. eof) then
346  call spec_file_read_line(file, temp_line_list(num_lines + 1), eof)
347  end if
348  end do
349 
350  ! copy data to actual list
351  ! FIXME: following allocate shouldn't be needed, but is on gfortran 4.6.3
352  allocate(line_list(num_lines))
353  line_list = temp_line_list(1:num_lines)
354 
355  end subroutine spec_file_read_line_list
356 
357 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
358 
359  !> Read an array of spec_lines from a file, stopping at max_lines
360  !> or EOF. All lines must have the same number of elements.
361  subroutine spec_file_read_line_array(file, max_lines, line_array)
363  !> Spec file.
364  type(spec_file_t), intent(inout) :: file
365  !> Max lines to read (0 = no max).
366  integer, intent(in) :: max_lines
367  !> Array of spec_lines,.
368  type(spec_line_t), allocatable :: line_array(:)
369 
370  integer :: i, line_length
371 
372  call spec_file_read_line_list(file, max_lines, line_array)
373  if (size(line_array) > 0) then
374  line_length = size(line_array(1)%data)
375  do i = 2,size(line_array)
376  if (size(line_array(i)%data) /= line_length) then
377  call spec_file_die_msg(298076484, file, &
378  'lines have unequal numbers of entries for array')
379  end if
380  end do
381  end if
382 
383  end subroutine spec_file_read_line_array
384 
385 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
386 
387  !> Check that the name of the line data is as given.
388  subroutine spec_file_check_line_name(file, line, name)
390  !> Spec file.
391  type(spec_file_t), intent(in) :: file
392  !> Spec line.
393  type(spec_line_t), intent(in) :: line
394  !> Expected line name.
395  character(len=*), intent(in) :: name
396 
397  if (line%name /= name) then
398  call spec_file_die_msg(462932478, file, &
399  'line must begin with: ' // trim(name) &
400  // ' not: ' // trim(line%name))
401  end if
402 
403  end subroutine spec_file_check_line_name
404 
405 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
406 
407  !> Checks that the read_name is the same as name.
408  subroutine spec_file_check_name(file, name, read_name)
410  !> Spec file.
411  type(spec_file_t), intent(inout) :: file
412  !> Name that we should have.
413  character(len=*), intent(in) :: name
414  !> Name that we do have.
415  character(len=*), intent(in) :: read_name
416 
417  integer name_len, read_name_len
418 
419  if (name /= read_name) then
420  call spec_file_die_msg(683719069, file, &
421  'line must begin with: ' // trim(name) &
422  // ' not: ' // trim(read_name))
423  end if
424 
425  end subroutine spec_file_check_name
426 
427 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
428 
429  !> Check that the length of the line data is as given.
430  subroutine spec_file_check_line_length(file, line, length)
432  !> Spec file.
433  type(spec_file_t), intent(in) :: file
434  !> Spec line.
435  type(spec_line_t), intent(in) :: line
436  !> Expected data length.
437  integer, intent(in) :: length
438 
439  if (size(line%data) /= length) then
440  call spec_file_die_msg(189339129, file, 'expected ' &
441  // trim(integer_to_string(length)) // ' data items on line')
442  end if
443 
444  end subroutine spec_file_check_line_length
445 
446 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
447 
448  !> Check the IOSTAT and error if it is bad.
449  subroutine spec_file_check_read_iostat(file, ios, type)
451  !> Spec file.
452  type(spec_file_t), intent(in) :: file
453  !> Iostat result.
454  integer, intent(in) :: ios
455  !> Type being read during error.
456  character(len=*), intent(in) :: type
457 
458  if (ios /= 0) then
459  call spec_file_die_msg(704342497, file, &
460  'error reading: IOSTAT = ' // trim(integer_to_string(ios)))
461  end if
462 
463  end subroutine spec_file_check_read_iostat
464 
465 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
466 
467  !> Convert a string to an integer.
468  integer function spec_file_string_to_integer(file, string)
470  !> Spec file.
471  type(spec_file_t), intent(in) :: file
472  !> String to convert.
473  character(len=*), intent(in) :: string
474 
475  integer :: val
476  integer :: ios
477 
478  read(string, '(i20)', iostat=ios) val
479  call spec_file_check_read_iostat(file, ios, "integer")
481 
482  end function spec_file_string_to_integer
483 
484 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
485 
486  !> Convert a string to an real.
487  real(kind=dp) function spec_file_string_to_real(file, string)
489  !> Spec file.
490  type(spec_file_t), intent(in) :: file
491  !> String to convert.
492  character(len=*), intent(in) :: string
493 
494  real(kind=dp) :: val
495  integer :: ios
496 
497  read(string, '(f30.0)', iostat=ios) val
498  call spec_file_check_read_iostat(file, ios, "real")
500 
501  end function spec_file_string_to_real
502 
503 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
504 
505  !> Convert a string to an logical.
506  logical function spec_file_string_to_logical(file, string)
508  !> Spec file.
509  type(spec_file_t), intent(in) :: file
510  !> String to convert.
511  character(len=*), intent(in) :: string
512 
513  logical :: val
514  integer :: ios
515 
516  val = .false.
517  if ((trim(string) == 'yes') &
518  .or. (trim(string) == 'y') &
519  .or. (trim(string) == 'true') &
520  .or. (trim(string) == 't') &
521  .or. (trim(string) == '1')) then
522  val = .true.
523  elseif ((trim(string) == 'no') &
524  .or. (trim(string) == 'n') &
525  .or. (trim(string) == 'false') &
526  .or. (trim(string) == 'f') &
527  .or. (trim(string) == '0')) then
528  val = .false.
529  else
530  call spec_file_check_read_iostat(file, 1, "logical")
531  end if
533 
534  end function spec_file_string_to_logical
535 
536 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
537 
538  !> Read an integer from a spec file that must have the given name.
539  subroutine spec_file_read_integer(file, name, var)
541  !> Spec file.
542  type(spec_file_t), intent(inout) :: file
543  !> Name.
544  character(len=*), intent(in) :: name
545  !> Variable to store data.
546  integer, intent(out) :: var
547 
548  type(spec_line_t) :: line
549 
550  call spec_file_read_line_no_eof(file, line)
551  call spec_file_check_line_name(file, line, name)
552  call spec_file_check_line_length(file, line, 1)
553  var = spec_file_string_to_integer(file, line%data(1))
554 
555  end subroutine spec_file_read_integer
556 
557 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
558 
559  !> Read a real number from a spec file that must have the given
560  !> name.
561  subroutine spec_file_read_real(file, name, var)
563  !> Spec file.
564  type(spec_file_t), intent(inout) :: file
565  !> Name.
566  character(len=*), intent(in) :: name
567  !> Variable to store data.
568  real(kind=dp), intent(out) :: var
569 
570  type(spec_line_t) :: line
571 
572  call spec_file_read_line_no_eof(file, line)
573  call spec_file_check_line_name(file, line, name)
574  call spec_file_check_line_length(file, line, 1)
575  var = spec_file_string_to_real(file, line%data(1))
576 
577  end subroutine spec_file_read_real
578 
579 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
580 
581  !> Read a logical from a spec file that must have a given name.
582  subroutine spec_file_read_logical(file, name, var)
584  !> Spec file.
585  type(spec_file_t), intent(inout) :: file
586  !> Name.
587  character(len=*), intent(in) :: name
588  !> Variable to store data.
589  logical, intent(out) :: var
590 
591  type(spec_line_t) :: line
592 
593  call spec_file_read_line_no_eof(file, line)
594  call spec_file_check_line_name(file, line, name)
595  call spec_file_check_line_length(file, line, 1)
596  var = spec_file_string_to_logical(file, line%data(1))
597 
598  end subroutine spec_file_read_logical
599 
600 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
601 
602  !> Read a string from a spec file that must have a given name.
603  subroutine spec_file_read_string(file, name, var)
605  !> Spec file.
606  type(spec_file_t), intent(inout) :: file
607  !> Name.
608  character(len=*), intent(in) :: name
609  !> Variable to store data.
610  character(len=*), intent(out) :: var
611 
612  type(spec_line_t) :: line
613 
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 = line%data(1)
618 
619  end subroutine spec_file_read_string
620 
621 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
622 
623  !> Read a complex number from a spec file that must have the given
624  !> name.
625  subroutine spec_file_read_complex(file, name, var)
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  complex(kind=dc), intent(out) :: var
633 
634  type(spec_line_t) :: line
635 
636  call spec_file_read_line_no_eof(file, line)
637  call spec_file_check_line_name(file, line, name)
638  call spec_file_check_line_length(file, line, 2)
639  var = cmplx(spec_file_string_to_real(file, line%data(1)), &
640  spec_file_string_to_real(file, line%data(2)), kind=dc)
641 
642  end subroutine spec_file_read_complex
643 
644 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
645 
646  !> Read an array of named lines with real data. All lines must have
647  !> the same number of data elements.
648  subroutine spec_file_read_real_named_array(file, max_lines, names, vals)
650  !> Spec file.
651  type(spec_file_t), intent(inout) :: file
652  !> Max lines to read (0 = no max).
653  integer, intent(in) :: max_lines
654  !> Names of lines.
655  character(len=SPEC_LINE_MAX_VAR_LEN), allocatable :: names(:)
656  !> Data values.
657  real(kind=dp), allocatable :: vals(:,:)
658 
659  type(spec_line_t), allocatable :: line_array(:)
660  integer :: num_lines, line_length, i, j
661 
662  call spec_file_read_line_array(file, max_lines, line_array)
663  num_lines = size(line_array)
664  if (allocated(names)) deallocate(names)
665  if (allocated(vals)) deallocate(vals)
666  if (num_lines > 0) then
667  line_length = size(line_array(1)%data)
668  allocate(names(num_lines))
669  allocate(vals(num_lines, line_length))
670  do i = 1,num_lines
671  names(i) = line_array(i)%name
672  do j = 1,line_length
673  vals(i,j) = spec_file_string_to_real(file, line_array(i)%data(j))
674  end do
675  end do
676  else
677  allocate(names(0))
678  allocate(vals(0,0))
679  end if
680 
681  end subroutine spec_file_read_real_named_array
682 
683 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
684 
685  !> Read an a time-indexed array of real data.
686  subroutine spec_file_read_timed_real_array(file, name, times, vals)
688  !> Spec file.
689  type(spec_file_t), intent(inout) :: file
690  !> Variable name.
691  character(len=*), intent(in) :: name
692  !> Names of lines.
693  real(kind=dp), allocatable :: times(:)
694  !> Data values.
695  real(kind=dp), allocatable :: vals(:)
696 
697  integer :: n_lines, n_times
698  character(len=SPEC_LINE_MAX_VAR_LEN), allocatable :: read_names(:)
699  real(kind=dp), allocatable :: read_data(:,:)
700 
701  call spec_file_read_real_named_array(file, 0, read_names, read_data)
702 
703  n_lines = size(read_names)
704  if (n_lines /= 2) then
705  call die_msg(694159200, 'must have exactly two data lines in file ' &
706  // trim(file%name))
707  end if
708  n_times = size(read_data,2)
709  if (n_times < 1) then
710  call die_msg(925956383, 'must have at least one data poin in file ' &
711  // trim(file%name))
712  end if
713  if (trim(read_names(1)) /= "time") then
714  call die_msg(407039398, 'first data line in ' // trim(file%name) &
715  // ' must start with: time not: ' // trim(read_names(1)))
716  end if
717  if (trim(read_names(2)) /= name) then
718  call die_msg(692842968, 'second data line in ' // trim(file%name) &
719  // ' must start with: ' // trim(name) &
720  // ' not: ' // trim(read_names(2)))
721  end if
722 
723  times = read_data(1,:)
724  vals = read_data(2,:)
725 
726  end subroutine spec_file_read_timed_real_array
727 
728 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
729 
730 end module pmc_spec_file
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:148
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:626
An input file with extra data for printing messages.
Definition: spec_file.F90:59
integer function spec_file_string_to_integer(file, string)
Convert a string to an integer.
Definition: spec_file.F90:469
subroutine spec_file_close(file)
Close a spec file.
Definition: spec_file.F90:135
subroutine spec_line_strip_comment(string)
Strip the comments from a string. Comments are everything after the first # character.
Definition: spec_line.F90:57
subroutine spec_file_check_read_iostat(file, ios, type)
Check the IOSTAT and error if it is bad.
Definition: spec_file.F90:450
subroutine spec_line_strip_leading_spaces(string)
Strip leading spaces from a string.
Definition: spec_line.F90:93
A single line of input data, split at whitespace.
Definition: spec_line.F90:27
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
subroutine spec_file_check_line_length(file, line, length)
Check that the length of the line data is as given.
Definition: spec_file.F90:431
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:184
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:562
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:362
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:540
subroutine die_msg(code, error_msg)
Error immediately.
Definition: util.F90:134
integer function get_unit()
Returns an available unit number. This should be freed by free_unit().
Definition: util.F90:148
subroutine spec_line_set_size(spec_line, n_data)
Sets the number of data elements in the line.
Definition: spec_line.F90:40
logical function spec_file_string_to_logical(file, string)
Convert a string to an logical.
Definition: spec_file.F90:507
real(kind=dp) function spec_file_string_to_real(file, string)
Convert a string to an real.
Definition: spec_file.F90:488
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:583
subroutine spec_file_die_msg(code, file, msg)
Exit with an error message containing filename and line number.
Definition: spec_file.F90:74
subroutine spec_file_read_line(file, line, eof)
Read a spec_line from the spec_file.
Definition: spec_file.F90:215
Reading formatted text input.
Definition: spec_file.F90:43
subroutine spec_file_check_name(file, name, read_name)
Checks that the read_name is the same as name.
Definition: spec_file.F90:409
integer, parameter spec_file_max_list_lines
Maximum number of lines in an array.
Definition: spec_file.F90:49
subroutine spec_file_open(filename, file)
Open a spec file for reading.
Definition: spec_file.F90:112
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:649
subroutine spec_file_check_line_name(file, line, name)
Check that the name of the line data is as given.
Definition: spec_file.F90:389
A single line of formatted test for input.
Definition: spec_line.F90:9
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:91
subroutine spec_file_read_timed_real_array(file, name, times, vals)
Read an a time-indexed array of real data.
Definition: spec_file.F90:687
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_string(file, name, var)
Read a string from a spec file that must have a given name.
Definition: spec_file.F90:604
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:75
character(len=pmc_util_convert_string_len) function integer_to_string(val)
Convert an integer to a string format.
Definition: util.F90:766
Common utility subroutines.
Definition: util.F90:9
integer, parameter dc
Kind of a double precision complex number.
Definition: constants.F90:14
subroutine free_unit(unit)
Frees a unit number returned by get_unit().
Definition: util.F90:172
integer, parameter spec_line_max_var_len
Maximum size of a variable.
Definition: spec_line.F90:16