Octopus
parser.F90
Go to the documentation of this file.
1!! Copyright (C) 2003-2006 M. Marques, A. Castro, A. Rubio, G. Bertsch
2!!
3!! This program is free software; you can redistribute it and/or modify
4!! it under the terms of the GNU General Public License as published by
5!! the Free Software Foundation; either version 2, or (at your option)
6!! any later version.
7!!
8!! This program is distributed in the hope that it will be useful,
9!! but WITHOUT ANY WARRANTY; without even the implied warranty of
10!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11!! GNU General Public License for more details.
12!!
13!! You should have received a copy of the GNU General Public License
14!! along with this program; if not, write to the Free Software
15!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16!! 02110-1301, USA.
17!!
18
19#include "global.h"
20
21module parser_oct_m
22 use global_oct_m
23 use loct_oct_m
24 use mpi_oct_m
26 use unit_oct_m
28
29 implicit none
30
31 private
32 public :: &
33 block_t, &
35 parser_end, &
36 parse_init, &
38 parse_end, &
55
56 type :: block_t
57 private
58 integer, pointer :: p
59 end type block_t
60
62 character(len=27), parameter, public :: parser_varname_excluded_characters = '|!''"#$%&/\‍()=?{}+-*^.,;:<> '
63
64 interface parse_init
65 integer function oct_parse_init(file_out, mpiv_node)
66 implicit none
67 character(len=*), intent(in) :: file_out
68 integer, intent(in) :: mpiv_node
69 end function oct_parse_init
70 end interface parse_init
71
72 interface parse_putsym
73 subroutine oct_parse_putsym_int(sym, i)
74 implicit none
75 character(len=*), intent(in) :: sym
76 integer, intent(in) :: i
77 end subroutine oct_parse_putsym_int
78
79 subroutine oct_parse_putsym_double(sym, d)
80 use, intrinsic :: iso_fortran_env
81 implicit none
82 character(len=*), intent(in) :: sym
83 real(real64), intent(in) :: d
84 end subroutine oct_parse_putsym_double
85 end interface parse_putsym
86
87 interface parse_input_file
88 integer function oct_parse_input(file_in, set_used)
89 implicit none
90 character(len=*), intent(in) :: file_in
91 integer, intent(in) :: set_used
92 end function oct_parse_input
93 end interface parse_input_file
94
95 interface parse_input_string
96 integer function oct_parse_input_string(file_contents, set_used)
97 implicit none
98 character(len=*), intent(in) :: file_contents
99 integer, intent(in) :: set_used
100 end function oct_parse_input_string
101 end interface parse_input_string
102
103 interface parse_environment
104 subroutine oct_parse_environment(prefix)
105 implicit none
106 character(len=*), intent(in) :: prefix
107 end subroutine oct_parse_environment
108 end interface parse_environment
109
110 interface parse_end
111 subroutine oct_parse_end()
112 implicit none
113 end subroutine oct_parse_end
114 end interface parse_end
115
117 subroutine oct_sym_output_table(only_unused, mpiv_node)
118 implicit none
119 integer, intent(in) :: only_unused
120 integer, intent(in) :: mpiv_node
121 end subroutine oct_sym_output_table
122 end interface sym_output_table
123
124 interface parse_isdef
125 integer pure function oct_parse_isdef(name)
126 implicit none
127 character(len=*), intent(in) :: name
128 end function oct_parse_isdef
129 end interface parse_isdef
130
131 interface
132 subroutine oct_parse_int(name, def, res)
133 use, intrinsic :: iso_fortran_env
134 implicit none
135 character(len=*), intent(in) :: name
136 integer(int64), intent(in) :: def
137 integer(int64), intent(out) :: res
138 end subroutine oct_parse_int
139
140 subroutine oct_parse_double(name, def, res)
141 use, intrinsic :: iso_fortran_env
142 implicit none
143 character(len=*), intent(in) :: name
144 real(real64), intent(in) :: def
145 real(real64), intent(out) :: res
146 end subroutine oct_parse_double
147
148 subroutine oct_parse_complex(name, def, res)
149 use, intrinsic :: iso_fortran_env
150 implicit none
151 character(len=*), intent(in) :: name
152 complex(real64), intent(in) :: def
153 complex(real64), intent(out) :: res
154 end subroutine oct_parse_complex
155
156 subroutine oct_parse_string(name, def, res)
157 implicit none
158 character(len=*), intent(in) :: name, def
159 character(len=*), intent(out) :: res
160 end subroutine oct_parse_string
161
162 integer function oct_parse_block(name, blk)
163 import block_t
164 implicit none
165 character(len=*), intent(in) :: name
166 type(block_t), intent(out) :: blk
167 end function oct_parse_block
168 end interface
169
170 interface parse_variable
171 module procedure parse_integer
172 module procedure parse_integer8
173 module procedure parse_integer48
174 module procedure parse_integer84
175 module procedure parse_logical
176 module procedure parse_string
177 module procedure parse_cmplx
178 module procedure oct_parse_double_unit
179 end interface parse_variable
180
181 interface parse_block_end
182 subroutine oct_parse_block_end(blk)
183 import block_t
184 implicit none
185 type(block_t), intent(inout) :: blk
186 end subroutine oct_parse_block_end
187 end interface parse_block_end
188
189 interface parse_block_n
190 integer function oct_parse_block_n(blk)
191 import block_t
192 implicit none
193 type(block_t), intent(in) :: blk
194 end function oct_parse_block_n
195 end interface parse_block_n
196
197 interface parse_block_cols
198 integer function oct_parse_block_cols(blk, line)
199 import block_t
200 implicit none
201 type(block_t), intent(in) :: blk
202 integer, intent(in) :: line
203 end function oct_parse_block_cols
204 end interface parse_block_cols
207 subroutine oct_parse_block_int(blk, l, c, res)
208 import block_t
209 implicit none
210 type(block_t), intent(in) :: blk
211 integer, intent(in) :: l, c
212 integer, intent(out) :: res
213 end subroutine oct_parse_block_int
214
215 subroutine oct_parse_block_int8(blk, l, c, res)
216 use, intrinsic :: iso_fortran_env
217 import block_t
218 implicit none
219 type(block_t), intent(in) :: blk
220 integer, intent(in) :: l, c
221 integer(int64), intent(out) :: res
222 end subroutine oct_parse_block_int8
223 end interface parse_block_integer
224
225 interface parse_block_float
226 subroutine oct_parse_block_double(blk, l, c, res)
227 use, intrinsic :: iso_fortran_env
228 import block_t
229 implicit none
230 type(block_t), intent(in) :: blk
231 integer, intent(in) :: l, c
232 real(real64), intent(out) :: res
233 end subroutine oct_parse_block_double
234
236 end interface parse_block_float
237
238 interface parse_block_cmplx
239 subroutine oct_parse_block_complex(blk, l, c, res)
240 use, intrinsic :: iso_fortran_env
241 import block_t
242 implicit none
243 type(block_t), intent(in) :: blk
244 integer, intent(in) :: l, c
245 complex(real64), intent(out) :: res
246 end subroutine oct_parse_block_complex
247 end interface parse_block_cmplx
248
249 interface parse_block_string
250 subroutine oct_parse_block_string(blk, l, c, res)
251 import block_t
252 implicit none
253 type(block_t), intent(in) :: blk
254 integer, intent(in) :: l, c
255 character(len=*), intent(out) :: res
256 end subroutine oct_parse_block_string
257 end interface parse_block_string
258
259 ! ---------------------------------------------------------
270 ! ---------------------------------------------------------
271
272 interface
273 subroutine oct_parse_expression(re, im, ndim, x, r, t, pot)
274 use, intrinsic :: iso_fortran_env
275 implicit none
276 real(real64), intent(in) :: x, r, t
277 integer, intent(in) :: ndim
278 real(real64), intent(out) :: re, im
279 character(len=*), intent(in) :: pot
280 end subroutine oct_parse_expression
281 end interface
282
283 interface parse_expression
284 subroutine oct_parse_expression1(re, im, c, x, string)
285 use, intrinsic :: iso_fortran_env
286 implicit none
287 real(real64), intent(out) :: re, im
288 character(len=*), intent(in) :: c
289 real(real64), intent(in) :: x
290 character(len=*), intent(in) :: string
291 end subroutine oct_parse_expression1
294 end interface
295
296contains
297
308 subroutine parser_initialize_symbol_table(log_file)
309 character(len=*), optional, intent(in) :: log_file
311 integer :: ierr
312 logical :: file_exists
313 character(len=:), allocatable :: log_file_
314
315 if (present(log_file)) then
316 log_file_ = trim(log_file)
317 else
318 log_file_ = 'exec/parser.log'
319 end if
321 inquire(file=trim(conf%share)//'/variables', exist=file_exists)
322 if (.not. file_exists) then
323 write(stderr,'(a)') '*** Fatal Error (description follows)'
324 write(stderr,'(a)') 'Error initializing parser'
325 write(stderr,'(a)') 'Cannot open variables file: '//trim(conf%share)//'/variables'
326 call parse_fatal()
327 end if
328
329 ! If using default log file, make the directory
330 if (.not. present(log_file)) then
331 if (mpi_world%is_root()) call loct_mkdir('exec')
332 endif
334 ! Initialize the symbol table, and the log file
335 ! Note, it would make sense to expose `sym_init_table` as its own call
336 ierr = parse_init(log_file_, mpi_world%rank)
337 if (ierr /= 0) then
338 write(stderr,'(a)') '*** Fatal Error (description follows)'
339 write(stderr,'(a)') 'Error initializing parser: cannot write to ' // log_file_
340 write(stderr,'(a)') 'Do you have write permissions in this directory?'
341 call parse_fatal()
342 end if
343
344 ! Parse option definitions, and use them to populate the symbol table keys
345 ierr = parse_input_file(trim(conf%share)//'/variables', set_used = 1)
346 if (ierr /= 0) then
347 write(stderr,'(a)') '*** Fatal Error (description follows)'
348 write(stderr,'(a)') 'Error initializing parser'
349 write(stderr,'(a)') 'Cannot open variables file: '//trim(conf%share)//'/variables'
350 call parse_fatal()
351 end if
352
353 end subroutine parser_initialize_symbol_table
354
355
357 subroutine parser_init()
358
359 integer :: ierr
360 logical :: file_exists
361
363
364 inquire(file='inp', exist=file_exists)
365 if (.not. file_exists) then
366 write(stderr,'(a)') '*** Fatal Error (description follows)'
367 write(stderr,'(a)') 'Error initializing parser'
368 write(stderr,'(a)') 'Cannot open input file!'
369 write(stderr,'(a)') 'Please provide an input file with name inp in the current workdir'
370 call parse_fatal()
371 end if
372
373 ierr = parse_input_file('inp', set_used = 0)
374 if (ierr /= 0) then
375 write(stderr,'(a)') '*** Fatal Error (description follows)'
376 write(stderr,'(a)') 'Error initializing parser'
377 write(stderr,'(a)') 'Cannot open input file!'
378 write(stderr,'(a)') 'Please provide an input file with name inp in the current workdir'
380 end if
381
382 ! parse OCT_ prefixed variables from environment
383 call parse_environment("OCT_")
384
385 end subroutine parser_init
386
388 subroutine parser_end()
389 integer :: parser_log
390
391 ! Output the symbol table
392 call sym_output_table(only_unused = 1, mpiv_node = mpi_world%rank)
393 ! Free the symbol table and close global C file handle.
394 call parse_end()
395
396 ! Write the octopus version and git_commit hash to the parser.log.
397 ! This is done after parse_end(), to avoid conflicting with the existing open file handle
398 if(mpi_world%is_root()) then
399 open(newunit=parser_log, file='exec/parser.log', status='old', action='write', position='append')
400 write(parser_log, '(a)') '# Octopus version: '//trim(conf%version)
401 write(parser_log, '(a)') '# Octopus git_commit: '//trim(conf%git_commit)
402 close(parser_log)
403 end if
404
405 end subroutine parser_end
406
407 ! ---------------------------------------------------------
408
409 logical function parse_is_defined(namespace, name) result(isdef)
410 type(namespace_t), intent(in) :: namespace
411 character(len=*), intent(in) :: name
412
413 isdef = parse_isdef(parse_get_full_name(namespace, name)) /= 0
414
415 end function parse_is_defined
416
417 ! ---------------------------------------------------------
418
419 subroutine parse_integer(namespace, name, def, res)
420 type(namespace_t), intent(in) :: namespace
421 character(len=*), intent(in) :: name
422 integer, intent(in) :: def
423 integer, intent(out) :: res
424
425 integer(int64) :: res8
426
427 call parse_check_varinfo(name)
428 call oct_parse_int(parse_get_full_name(namespace, name), int(def, int64), res8)
429
430 res = int(res8)
431
432 end subroutine parse_integer
433
434 ! ---------------------------------------------------------
435
436 subroutine parse_integer8(namespace, name, def, res)
437 type(namespace_t), intent(in) :: namespace
438 character(len=*), intent(in) :: name
439 integer(int64), intent(in) :: def
440 integer(int64), intent(out) :: res
441
442 call parse_check_varinfo(name)
443 call oct_parse_int(parse_get_full_name(namespace, name), def, res)
444
445 end subroutine parse_integer8
446
447 ! ---------------------------------------------------------
448
449 subroutine parse_integer48(namespace, name, def, res)
450 type(namespace_t), intent(in) :: namespace
451 character(len=*), intent(in) :: name
452 integer, intent(in) :: def
453 integer(int64), intent(out) :: res
454
455 call parse_check_varinfo(name)
456 call oct_parse_int(parse_get_full_name(namespace, name), int(def, int64), res)
457
458 end subroutine parse_integer48
459
460 ! ---------------------------------------------------------
461
462 subroutine parse_integer84(namespace, name, def, res)
463 type(namespace_t), intent(in) :: namespace
464 character(len=*), intent(in) :: name
465 integer(int64), intent(in) :: def
466 integer, intent(out) :: res
467
468 integer(int64) :: res8
469
470 call parse_check_varinfo(name)
471 call oct_parse_int(parse_get_full_name(namespace, name), def, res8)
472
473 res = int(res8)
474
475 end subroutine parse_integer84
476
477 ! ---------------------------------------------------------
478
479 subroutine parse_string(namespace, name, def, res)
480 type(namespace_t), intent(in) :: namespace
481 character(len=*), intent(in) :: name
482 character(len=*), intent(in) :: def
483 character(len=*), intent(out) :: res
484
485 call parse_check_varinfo(name)
486 call oct_parse_string(parse_get_full_name(namespace, name), def, res)
487
488 end subroutine parse_string
489
490
491 subroutine parse_logical(namespace, name, def, res)
492 type(namespace_t), intent(in) :: namespace
493 character(len=*), intent(in) :: name
494 logical, intent(in) :: def
495 logical, intent(out) :: res
496
497 integer(int64) :: idef, ires
498
499 call parse_check_varinfo(name)
500
501 ! logical is a FORTRAN type, so we emulate the routine with integers
502 idef = 0
503 if (def) idef = 1
505 call oct_parse_int(parse_get_full_name(namespace, name), idef, ires)
506 res = (ires /= 0)
507
508 end subroutine parse_logical
509
510 ! ---------------------------------------------------------
511
512 subroutine parse_cmplx(namespace, name, def, res)
513 type(namespace_t), intent(in) :: namespace
514 character(len=*), intent(in) :: name
515 complex(real64), intent(in) :: def
516 complex(real64), intent(out) :: res
517
518 call parse_check_varinfo(name)
519 call oct_parse_complex(parse_get_full_name(namespace, name), def, res)
520
521 end subroutine parse_cmplx
522
523 ! ---------------------------------------------------------
524
525 integer function parse_block(namespace, name, blk, check_varinfo_)
526 type(namespace_t), intent(in) :: namespace
527 character(len=*), intent(in) :: name
528 type(block_t), intent(out) :: blk
529 logical, optional, intent(in) :: check_varinfo_
530
531 logical check_varinfo
532
533 check_varinfo = .true.
534 if (present(check_varinfo_)) check_varinfo = check_varinfo_
535
536 if (check_varinfo) then
537 call parse_check_varinfo(name)
538 end if
539 parse_block = oct_parse_block(parse_get_full_name(namespace, name), blk)
540
541 end function parse_block
542
543 ! ---------------------------------------------------------
545 subroutine parse_block_logical(blk, l, c, res)
546 type(block_t), intent(in) :: blk
547 integer, intent(in) :: l, c
548 logical, intent(out) :: res
549
550 integer :: ires
551
552 call oct_parse_block_int(blk, l, c, ires)
553 res = (ires /= 0)
554
555 end subroutine parse_block_logical
556
557 ! ---------------------------------------------------------
558
559 subroutine oct_parse_double_unit(namespace, name, def, res, unit)
560 type(namespace_t), intent(in) :: namespace
561 character(len=*), intent(in) :: name
562 real(real64), intent(in) :: def
563 real(real64), intent(out) :: res
564 type(unit_t), optional, intent(in) :: unit
565
566 call parse_check_varinfo(name)
567
568 if (present(unit)) then
569 call oct_parse_double(parse_get_full_name(namespace, name), units_from_atomic(unit, def), res)
570 res = units_to_atomic(unit, res)
571 else
572 call oct_parse_double(parse_get_full_name(namespace, name), def, res)
573 end if
575 end subroutine oct_parse_double_unit
576
577 ! ---------------------------------------------------------
578
579 subroutine oct_parse_block_double_unit(blk, l, c, res, unit)
580 type(block_t), intent(in) :: blk
581 integer, intent(in) :: l, c
582 real(real64), intent(out) :: res
583 type(unit_t), intent(in) :: unit
584
585 call oct_parse_block_double(blk, l, c, res)
586 res = units_to_atomic(unit, res)
587
588 end subroutine oct_parse_block_double_unit
589
590 ! ---------------------------------------------------------
591 subroutine oct_parse_expression_vec(re, im, ndim, x, r, t, pot)
592 real(real64), intent(out) :: re, im
593 integer, intent(in) :: ndim
594 real(real64), intent(in) :: x(:), r, t
595 character(len=*), intent(in) :: pot
596
597 call oct_parse_expression(re, im, ndim, x(1), r, t, pot)
598
599 end subroutine oct_parse_expression_vec
600
601
602 ! ----------------------------------------------------------------------
607 subroutine parse_array(inp_string, x, arraychar)
608 character(len=*), intent(inout) :: inp_string
609 real(real64), intent(in) :: x(:, :)
610 character(len=1), intent(in) :: arraychar
611
612 integer :: i, m, n_atom, coord, string_length
613 character (LEN=100) :: v_string
614
615 string_length = len(inp_string)
616 do i = 1, string_length - 1
617 if (inp_string(i:i+1) == arraychar//"[") then
618 m = 0
619 if (inp_string(i+3:i+3) == ",") m = 1
620 if (inp_string(i+4:i+4) == ",") m = 2
621 if (m == 0) then
622 write(stderr, '(a)') "*** Fatal Error (description follows)"
623 write(stderr, '(a)') "Attempting to parse a string with array elements larger than 99"
624 call parse_fatal()
625 end if
626 read(inp_string(i+2:i+1+m),*) n_atom
627 read(inp_string(i+3+m:i+3+m),*) coord
628 write(v_string,*) x(n_atom, coord)
629 inp_string = inp_string(:i-1) // "(" // trim(v_string) // ")" // inp_string(i+5+m:)
630 end if
631 end do
632
633 end subroutine parse_array
634
635 ! ----------------------------------------------------------------------
636
637 subroutine parse_check_varinfo(varname)
638 character(len=*), intent(in) :: varname
639
640 if (.not. varinfo_exists(varname)) then
641 write(stderr,'(a)') "*** Fatal Internal Error (description follows)"
642 write(stderr,'(a)') 'Attempting to parse undocumented variable '//trim(varname)//'.'
643 call parse_fatal()
644 end if
645
646 end subroutine parse_check_varinfo
647
648 ! ----------------------------------------------------------------------
675 function parse_get_full_name(namespace, varname) result(name)
676 type(namespace_t), target, intent(in) :: namespace
677 character(len=*), intent(in) :: varname
678 character(len=:), allocatable :: name
679
680 logical :: found
681 integer :: is
682 type(namespace_t), pointer :: ancestor
683 character(len=MAX_NAMESPACE_LEN) :: ancestor_name, tmp
684
685 found = .false.
687 ! Loop over all ancestors, starting from the right-most
688 ancestor => namespace
689 do while (associated(ancestor) .and. .not. found)
690
691 ! Loop over all paths to this ancestor, starting from the most complete path
692 ancestor_name = ancestor%get()
693 is = -1
694 do while (len_trim(ancestor_name) > 0 .and. is /= 0 .and. .not. found)
695 ! Check if the current path is found in the input file
696 name = trim(ancestor_name) // "." // trim(varname)
697 found = parse_isdef(trim(name)) /= 0
698
699 ! Remove the left-most namespace ("is" will be zero if there is only one namespace left)
700 is = index(ancestor_name, ".")
701 tmp = ancestor_name(is+1:)
702 ancestor_name = tmp
703 end do
704 ancestor => ancestor%parent
705 end do
706
707 ! If no suitable namespace found, just return the variable name
708 if (.not. found) name = varname
709
710 end function parse_get_full_name
711
712 ! ----------------------------------------------------------------------
713 subroutine parse_fatal()
714
715 call mpi_world%abort()
716
717 end subroutine parse_fatal
718
719end module parser_oct_m
720
721!! Local Variables:
722!! mode: f90
723!! coding: utf-8
724!! End:
The public subroutine parse_expression accepts two possible interfaces, one which assumes that the va...
Definition: parser.F90:368
character(len=:) function, allocatable, public parse_get_full_name(namespace, varname)
Given a namespace and a variable name, this function will iterate over all namespace ancestors contai...
Definition: parser.F90:771
logical function, public parse_is_defined(namespace, name)
Definition: parser.F90:505
subroutine parse_logical(namespace, name, def, res)
Definition: parser.F90:587
subroutine parse_integer(namespace, name, def, res)
Definition: parser.F90:515
subroutine parse_fatal()
Definition: parser.F90:809
subroutine parse_integer48(namespace, name, def, res)
Definition: parser.F90:545
subroutine, public parser_init()
Initialise the Octopus parser.
Definition: parser.F90:453
subroutine, public parse_block_logical(blk, l, c, res)
Definition: parser.F90:641
subroutine, public parser_end()
End the Octopus parser.
Definition: parser.F90:484
subroutine oct_parse_block_double_unit(blk, l, c, res, unit)
Definition: parser.F90:675
subroutine parse_integer84(namespace, name, def, res)
Definition: parser.F90:558
subroutine, public parse_array(inp_string, x, arraychar)
A very primitive way to "preprocess" a string that contains reference to the elements of a two-dimens...
Definition: parser.F90:703
subroutine parse_integer8(namespace, name, def, res)
Definition: parser.F90:532
subroutine oct_parse_double_unit(namespace, name, def, res, unit)
Definition: parser.F90:655
subroutine parse_string(namespace, name, def, res)
Definition: parser.F90:575
subroutine oct_parse_expression_vec(re, im, ndim, x, r, t, pot)
Definition: parser.F90:687
subroutine parse_check_varinfo(varname)
Definition: parser.F90:733
subroutine parse_cmplx(namespace, name, def, res)
Definition: parser.F90:608
integer function, public parse_block(namespace, name, blk, check_varinfo_)
Definition: parser.F90:621
subroutine, public parser_initialize_symbol_table(log_file)
Initialise the Octopus parser symbol table from file of keys.
Definition: parser.F90:404
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
Definition: unit.F90:134
int true(void)