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