71 integer,
parameter :: max_lines = 20
72 character(len=256),
dimension(max_lines),
public :: message
73 character(len=68),
parameter,
public :: hyphens = &
74 '--------------------------------------------------------------------'
75 character(len=69),
parameter,
public :: shyphens =
'*'//hyphens
77 character(len=512),
private :: msg
79 character(len=64),
private :: oct_status =
'undefined'
81 type(sihash_t),
private :: namespace_unit
82 type(sphash_t),
private :: namespace_mpi_grp
114 integer :: experimentals
115 integer :: current_line
121 integer,
intent(in) :: signum
122 character(len=*),
intent(out) :: signame
136 logical :: trap_signals
184 type(sihash_iterator_t) :: it
189 if (experimentals > 0 .or. warnings > 0)
then
195 if (warnings > 0)
then
198 if (warnings > 1)
then
206 if (experimentals > 0)
then
210 if (experimentals > 1)
then
217 call messages_write(
' Since you used one or more experimental features, results are likely')
219 call messages_write(
' wrong and should not be considered as valid scientific data. Check')
222 call messages_write(
' http://octopus-code.org/experimental_features')
225 call messages_write(
' or contact the octopus developers for details.')
230 open(unit =
iunit_out, file =
'exec/messages', action =
'write')
231 write(
iunit_out,
'(a, i9)')
"warnings = ", warnings
232 write(
iunit_out,
'(a, i9)')
"experimental = ", experimentals
237 call it%start(namespace_unit)
238 do while(it%has_next())
240 if (iu /= stderr .and. iu /= stdout)
call io_close(iu)
250 type(
namespace_t),
optional,
intent(in) :: namespace
254 if (
present(namespace))
then
256 if (namespace%get()==
"")
then
261 iunit =
sihash_lookup( namespace_unit, namespace%get(), found)
263 if (.not. found)
then
265 iunit =
io_open(
"log", namespace=namespace, action=
"write")
270 write(message(1),*)
"Cannot get unit for namespace ", namespace%get()
284 type(
mpi_grp_t),
target,
intent(in) :: mpigrp
292 type(
namespace_t),
optional,
intent(in) :: namespace
295 class(*),
pointer :: value
298 if (
present(namespace))
then
299 value =>
sphash_lookup(namespace_mpi_grp, trim(namespace%get()), found)
310 write(message(1),*)
"Cannot get mpi_grp for namespace ",namespace%get()
321 integer,
optional,
intent(in) :: no_lines
322 logical,
optional,
intent(in) :: only_root_writes
323 type(
namespace_t),
optional,
intent(in) :: namespace
326 integer :: ii, no_lines_
327 logical :: only_root_writes_, should_write
328 integer,
allocatable :: recv_buf(:), recv_req(:)
330 integer,
parameter :: fatal_tag = 32767
335 no_lines_ = current_line
336 if (
present(no_lines)) no_lines_ = no_lines
340 if (
present(only_root_writes))
then
341 should_write =
mpi_grp_is_root(msg_mpi_grp) .or. (.not. only_root_writes)
342 only_root_writes_ = only_root_writes
344 should_write = .
true.
345 only_root_writes_ = .false.
354 if (.not. only_root_writes_)
then
355 if (msg_mpi_grp%rank == 0)
then
361 call mpi_recv_init(recv_buf(ii), 1, mpi_integer, ii, fatal_tag, msg_mpi_grp%comm, recv_req(ii),
mpi_err)
370 call mpi_send_init(1, 1, mpi_integer, 0, fatal_tag, msg_mpi_grp%comm, send_req,
mpi_err)
375 call mpi_test(send_req, received, mpi_status_ignore,
mpi_err)
377 should_write = .false.
391 write(msg,
'(a)')
'*** Fatal Error (description follows)'
394 if (
present(namespace))
then
395 if (len_trim(namespace%get()) > 0)
then
396 write(msg,
'(3a)')
'* In namespace ', trim(namespace%get()),
':'
402 if (.not. only_root_writes_ .or. .not.
mpi_grp_is_root(msg_mpi_grp))
then
404 write(msg,
'(a,i4)')
"* From node = ", msg_mpi_grp%rank
410 write(msg,
'(a,1x,a)')
'*', trim(message(ii))
417 if (
debug%trace)
then
420 write(msg,
'(a)')
'* Stack: '
423 write(msg,
'(a,a)')
' > ', trim(
sub_stack(ii))
429 if (should_write)
then
445 integer,
optional,
intent(in) :: no_lines
446 logical,
optional,
intent(in) :: all_nodes
447 type(
namespace_t),
optional,
intent(in) :: namespace
449 integer :: il, no_lines_
450 integer :: iunit_namespace
451 logical :: have_to_write, all_nodes_
454 no_lines_ = current_line
455 if (
present(no_lines)) no_lines_ = no_lines
457 warnings = warnings + 1
465 if (
present(all_nodes))
then
466 have_to_write = have_to_write .or. all_nodes
467 all_nodes_ = all_nodes
470 if (have_to_write)
then
473 if (iunit_namespace /= stdout)
then
476 write(msg,
'(a)')
'** Warning:'
478 if (iunit_namespace /= stdout)
then
482 if (
present(namespace))
then
483 if (len_trim(namespace%get()) > 0)
then
484 write(msg,
'(3a)')
'** In namespace ', trim(namespace%get()),
':'
491 write(msg ,
'(a,i4)')
'** From node = ',
mpi_world%rank
493 if (iunit_namespace /= stdout)
then
500 write(msg ,
'(a,3x,a)')
'**', trim(message(il))
502 if (iunit_namespace /= stdout)
then
507 if (iunit_namespace /= stdout)
then
513 if (iunit_namespace /= stdout)
then
514 flush(iunit_namespace)
525 subroutine messages_info(no_lines, iunit, verbose_limit, stress, all_nodes, namespace)
526 integer,
optional,
intent(in) :: no_lines
527 integer,
optional,
intent(in) :: iunit
528 logical,
optional,
intent(in) :: verbose_limit
529 logical,
optional,
intent(in) :: stress
530 logical,
optional,
intent(in) :: all_nodes
531 type(
namespace_t),
optional,
intent(in) :: namespace
533 integer :: il, no_lines_
537 assert(.not. (
present(iunit) .and.
present(namespace)))
539 if (
present(iunit))
then
551 no_lines_ = current_line
552 if (
present(no_lines)) no_lines_ = no_lines
554 if (
present(stress))
then
559 if (.not.
present(verbose_limit) .or.
debug%info)
then
560 write(msg,
'(a)') trim(message(il))
564 if (
present(stress))
then
579 character(len=*),
intent(in) :: status
585 call loct_rm(
'exec/oct-status-running')
586 call loct_rm(
'exec/oct-status-finished')
587 call loct_rm(
'exec/oct-status-aborted')
588 if (oct_status /=
'walltimer-aborted')
then
589 call loct_rm(
'exec/oct-status-walltimer-aborted')
595 open(unit=
iunit_err, file=
'exec/oct-status-'//trim(status), &
596 action=
'write', status=
'unknown')
603 integer(i8),
intent(in) :: size
604 character(len=*),
intent(in) :: file
605 integer,
intent(in) :: line
607 write(message(1),
'(a,i18,3a,i5)')
"Failed to allocate ",
size,
" words in file '", trim(file),
"' line ", line
614 integer(i8),
intent(in) :: size
615 character(len=*),
intent(in) :: file
616 integer,
intent(in) :: line
618 write(message(1),
'(a,i18,3a,i5)')
"Failed to deallocate array of ",
size,
" words in file '", trim(file),
"' line ", line
626 character(len=*),
intent(in) :: var
627 character(len=*),
optional,
intent(in) :: details
628 integer,
optional,
intent(in) :: row
629 integer,
optional,
intent(in) :: column
631 character(len=10) :: row_str, column_str
633 call messages_write(
'Input error in the input variable '// trim(var))
635 if (
present(row))
then
639 write(row_str,
'(I10)') row + 1
641 if (
present(column))
then
642 write(column_str,
'(I10)') column + 1
646 if (
present(details))
then
655 call messages_write(
'You can get the documentation of the variable with the command:', new_line = .
true.)
663 character(len=*),
intent(in) :: var
664 integer,
intent(in) :: val
665 integer,
optional,
intent(in) :: iunit
666 type(
namespace_t),
optional,
intent(in) :: namespace
668 character(len=10) :: intstring
670 assert(.not. (
present(iunit) .and.
present(namespace)))
672 write(intstring,
'(i10)') val
673 message(1) =
'Input: ['//trim(var)//
' = '//trim(adjustl(intstring))//
']'
680 character(len=*),
intent(in) :: var
681 character(len=*),
intent(in) :: val
682 integer,
optional,
intent(in) :: iunit
683 type(
namespace_t),
optional,
intent(in) :: namespace
685 assert(.not. (
present(iunit) .and.
present(namespace)))
687 message(1) =
'Input: ['//trim(var)//
' = '//trim(val)//
']'
694 character(len=*),
intent(in) :: var
695 float,
intent(in) :: val
696 type(
unit_t),
optional,
intent(in) :: unit
697 integer,
optional,
intent(in) :: iunit
700 character(len=11) :: floatstring
702 assert(.not. (
present(iunit) .and.
present(namespace)))
704 if (.not.
present(unit))
then
705 write(floatstring,
'(g11.4)') val
706 message(1) =
'Input: ['//trim(var)//
' = '//trim(adjustl(floatstring))//
']'
709 message(1) =
'Input: ['//trim(var)//
' = '//trim(adjustl(floatstring))//
' '//trim(
units_abbrev(unit))//
']'
717 character(len=*),
intent(in) :: var
718 logical,
intent(in) :: val
719 integer,
optional,
intent(in) :: iunit
720 type(
namespace_t),
optional,
intent(in) :: namespace
722 character(len=3) :: lstring
724 assert(.not. (
present(iunit) .and.
present(namespace)))
731 message(1) =
'Input: ['//trim(var)//
' = '//trim(lstring)//
']'
738 character(len=*),
intent(in) :: var
739 float,
intent(in) :: val(:)
740 type(
unit_t),
optional,
intent(in) :: unit
741 integer,
optional,
intent(in) :: iunit
742 type(
namespace_t),
optional,
intent(in) :: namespace
745 character(len=11) :: floatstring
747 assert(.not. (
present(iunit) .and.
present(namespace)))
751 write(floatstring,
'(g11.4)') val(ii)
756 if (
present(unit))
then
767 character(len=*),
intent(in) :: var
768 integer,
optional,
intent(in) :: iunit
769 type(
namespace_t),
optional,
intent(in) :: namespace
774 assert(.not. (
present(iunit) .and.
present(namespace)))
780 if (
present(iunit))
then
791 character(len=*),
intent(in) :: var
792 integer(i8),
intent(in) :: option
793 character(len=*),
optional,
intent(in) :: pre
794 integer,
optional,
intent(in) :: iunit
795 type(
namespace_t),
optional,
intent(in) :: namespace
797 integer :: option4, iunit_
800 assert(.not. (
present(iunit) .and.
present(namespace)))
806 option4 = int(option)
808 if (
present(iunit))
then
819 character(len=*),
intent(in) :: var
820 integer(i4),
intent(in) :: option
821 character(len=*),
optional,
intent(in) :: pre
822 integer,
optional,
intent(in) :: iunit
823 type(
namespace_t),
optional,
intent(in) :: namespace
825 assert(.not. (
present(iunit) .and.
present(namespace)))
833 character(len=*),
optional,
intent(in) :: msg
834 integer,
optional,
intent(in) :: iunit
835 type(
namespace_t),
optional,
intent(in) :: namespace
837 integer,
parameter :: max_len = 70
839 integer :: ii, jj, length
841 character(len=70) :: str
842 character(len=max_len) :: msg_combined
845 if (
present(iunit))
then
854 if (
present(msg))
then
856 if (len_trim(msg) > max_len)
then
857 msg_combined = trim(msg(1:max_len))
859 msg_combined = trim(msg)
861 length = len_trim(msg_combined)
866 do ii = 1, (max_len - (length + 2))/2
875 str(jj:jj) = msg_combined(ii:ii)
905 character(len = *),
intent(in) :: str
906 integer,
intent(in) :: iunit
907 character(len = *),
optional,
intent(in) :: adv
909 character(len = 20) :: adv_
912 if (
present(adv)) adv_ = trim(adv)
914 write(iunit,
'(a)', advance=adv_) trim(str)
920 character(len = *),
intent(in) :: str
924 call date_and_time(
values=val)
926 write(message(3),
'(a,i4,a1,i2.2,a1,i2.2,a,i2.2,a1,i2.2,a1,i2.2)') &
927 str , val(1),
"/", val(2),
"/", val(3), &
928 " at ", val(5),
":", val(6),
":", val(7)
938 subroutine time_sum(sec1, usec1, sec2, usec2)
939 integer,
intent(in) :: sec1
940 integer,
intent(in) :: usec1
941 integer,
intent(inout) :: sec2
942 integer,
intent(inout) :: usec2
947 usec2 = usec1 + usec2
950 if (usec2 >= 1000000)
then
952 usec2 = usec2 - 1000000
961 character(len=*),
intent(in) :: sub_name
963 integer iunit, sec, usec
965 if (.not.
debug%trace)
return
973 message(1) =
'Too many recursion levels (max=50)'
980 if (
debug%trace_file)
then
995 integer,
intent(in) :: iunit_out
998 character(len=1000) :: tmpstr
1000 write(tmpstr,
'(a,i6,a,i6.6,f20.6,i8,a)')
"* I ", &
1005 write(tmpstr,
'(2a)') trim(tmpstr),
"..|"
1016 character(len=*),
intent(in) :: sub_name
1018 character(len=80) :: sub_name_short
1019 integer iunit, sec, usec
1021 if (.not.
debug%trace)
return
1029 message(1) =
'Too few recursion levels.'
1038 write (message(1),
'(a)')
'Wrong sub name on pop_sub :'
1039 write (message(2),
'(2a)')
' got : ', sub_name_short
1044 if (
debug%trace_file)
then
1064 character(len=1000) :: tmpstr
1066 write(tmpstr,
'(a,i6,a,i6.6,f20.6,i8, a)')
"* O ", &
1071 write(tmpstr,
'(2a)') trim(tmpstr),
"..|"
1084 character(len=*),
intent(in) :: name
1085 character(len=*),
optional,
intent(in) :: rep
1089 write(message(1),
'(a)')
'Input variable '//trim(name)//
' is obsolete.'
1091 if (
present(rep))
then
1092 write(message(2),
'(a)')
' '
1093 write(message(3),
'(a)')
'Equivalent functionality can be obtained with the '//trim(rep)
1094 write(message(4),
'(a)')
'variable. Check the documentation for details.'
1095 write(message(5),
'(a)')
'(You can use the `oct-help -p '//trim(rep)//
'` command).'
1108 character(len=*),
intent(in) :: name
1112 write(message(1),
'(a)')
'Input variable `'//trim(name)//
'` must be defined as a block.'
1113 write(message(2),
'(a)')
'Please check the documentation for details.'
1114 write(message(3),
'(a)')
'(You can use the `oct-help -p '//trim(name)//
'` command).'
1123 character(len=*),
intent(in) :: name
1124 type(
namespace_t),
optional,
intent(in) :: namespace
1126 experimentals = experimentals + 1
1128 if (.not.
conf%devel_version)
then
1132 call messages_write(
'If you still want to use this feature (at your own risk), check:')
1135 call messages_write(
'http://octopus-code.org/experimental_features')
1139 write(message(1),
'(a)') trim(name)//
' is under development.'
1140 write(message(2),
'(a)')
'It might not work or produce wrong results.'
1144 warnings = warnings - 1
1151 character(len=*),
intent(in) :: feature
1152 type(
namespace_t),
optional,
intent(in) :: namespace
1156 message(1) = trim(feature)//
" not implemented."
1173 current_line = current_line + 1
1174 message(current_line) =
''
1176 if (current_line > max_lines) stop
'Too many message lines.'
1182 float,
intent(in) :: val
1183 character(len=*),
optional,
intent(in) :: fmt
1184 logical,
optional,
intent(in) :: new_line
1185 type(
unit_t),
optional,
intent(in) :: units
1186 logical,
optional,
intent(in) :: align_left
1187 logical,
optional,
intent(in) :: print_units
1189 character(len=30) :: number
1195 if (
present(fmt))
then
1196 write(number,
'('//trim(fmt)//
')') tval
1198 write(number,
'(f12.6)') tval
1202 number = adjustl(number)
1203 number(1:len(number)) =
' '//number(1:len(number)-1)
1206 write(message(current_line),
'(a, a)') trim(message(current_line)), trim(number)
1209 write(message(current_line),
'(a, a, a)') trim(message(current_line)),
' ', trim(
units_abbrev(units))
1218 integer(i8),
intent(in) :: val
1219 character(len=*),
optional,
intent(in) :: fmt
1220 logical,
optional,
intent(in) :: new_line
1221 type(
unit_t),
optional,
intent(in) :: units
1222 logical,
optional,
intent(in) :: print_units
1224 character(len=20) :: number
1225 float :: val_conv_float
1227 if (
present(units))
then
1230 if (
present(fmt))
then
1231 write(message(current_line),
'(a, '//trim(fmt)//
')') trim(message(current_line)), val_conv_float
1233 write(number,
'(f15.3)') val_conv_float
1234 write(message(current_line),
'(3a)') trim(message(current_line)),
' ', trim(adjustl(number))
1239 if (
present(fmt))
then
1240 write(message(current_line),
'(a, '//trim(fmt)//
')') trim(message(current_line)), val
1242 write(number,
'(i12)') val
1243 write(message(current_line),
'(3a)') trim(message(current_line)),
' ', trim(adjustl(number))
1250 write(message(current_line),
'(a, a, a)') trim(message(current_line)),
' ', trim(adjustl(
units_abbrev(units)))
1253 if (
present(new_line))
then
1261 integer(i4),
intent(in) :: val
1262 character(len=*),
optional,
intent(in) :: fmt
1263 logical,
optional,
intent(in) :: new_line
1264 type(
unit_t),
optional,
intent(in) :: units
1265 logical,
optional,
intent(in) :: print_units
1273 character(len=*),
intent(in) :: val
1274 character(len=*),
optional,
intent(in) :: fmt
1275 logical,
optional,
intent(in) :: new_line
1277 character(len=100) :: fmt_
1279 if (len(trim(message(current_line))) + len(trim(val)) > len(message(current_line)))
then
1282 write(0, *)
"Exceeded message line length limit, to write string:", trim(val)
1285 write(message(current_line),
'(a, '//trim(fmt_)//
')') trim(message(current_line)), trim(val)
1288 if (
present(new_line))
then
1296 logical,
intent(in) :: val
1297 logical,
optional,
intent(in) :: new_line
1299 character(len=3) :: text
1307 if (len(trim(message(current_line))) + len(trim(text)) > len(message(current_line)))
then
1308 write(message(current_line + 1),
'(3a)')
"Exceeded message line length limit, to write logical value '", trim(text),
"'"
1312 write(message(current_line),
'(a,1x,a)') trim(message(current_line)), trim(text)
1314 if (
present(new_line))
then
1322 character(len=*),
intent(in) :: filename
1324 integer :: pos, start
1326 pos = index(filename,
'src/', back = .
true.)
1334 clean_path = filename(start:)
1339 integer,
intent(in) :: isignal
1342 character(len=300) :: description
1346 write(msg,
'(a,i2)')
''
1348 write(msg,
'(a,i2)')
'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%'
1350 write(msg,
'(a,i2)')
''
1352 write(msg,
'(a,i2,2a)')
' Octopus was killed by signal ', isignal,
': ', trim(description)
1354 write(msg,
'(a,i2)')
''
1356 write(msg,
'(a)')
' Note: Octopus is currently trapping signals. This might prevent the'
1358 write(msg,
'(a)')
' use of debuggers or the generation of core dumps. To change this'
1360 write(msg,
'(a)')
' behavior, use the DebugTrapSignals input option.'
1362 write(msg,
'(a,i2)')
''
1364 write(msg,
'(a,i2)')
'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%'
1367 if (
debug%trace)
then
1370 write(msg,
'(a)')
'Octopus debug trace: '
1373 write(msg,
'(a,a)')
' > ', trim(
sub_stack(ii))
1378 write(msg,
'(a)')
" Octopus debug trace not available. You can enable it with 'Debug = trace'."
1396 character(len=*),
intent(in) :: s, f
1397 integer,
intent(in) :: l
1422 integer(c_int),
intent(in) :: isignal
Prints out to iunit a message in the form: ["InputVariable" = value] where "InputVariable" is given b...
subroutine handle_segv(isignal)
subroutine push_sub_write(iunit_out)
subroutine assert_die(s, f, l)
This subroutine is called by the assert macro, it is not in a module so it can be called from any fil...
subroutine pop_sub_write(iunit_out)
type(debug_t), save, public debug
subroutine, public debug_open_trace(iunit)
subroutine, public epoch_time_diff(sec, usec)
subroutine, public debug_init(this, namespace)
integer, public no_sub_stack
character(len=80), dimension(50), public sub_stack
The stack.
type(conf_t), public conf
real(8), dimension(50), public time_stack
subroutine, public io_close(iunit, grp)
subroutine, public io_mkdir(fname, namespace, parents)
integer, parameter, public iunit_out
integer, parameter, public iunit_err
integer function, public io_open(file, namespace, action, status, form, position, die, recl, grp)
subroutine, public alloc_error(size, file, line)
subroutine, public messages_end()
character(len=max_path_len) function, public messages_clean_path(filename)
subroutine messages_write_integer8(val, fmt, new_line, units, print_units)
subroutine, public messages_print_with_emphasis(msg, iunit, namespace)
subroutine, public messages_not_implemented(feature, namespace)
subroutine messages_print_var_option_8(var, option, pre, iunit, namespace)
subroutine messages_print_var_valuear(var, val, unit, iunit, namespace)
subroutine, public messages_variable_is_block(namespace, name)
subroutine, public push_sub(sub_name)
subroutine, public messages_warning(no_lines, all_nodes, namespace)
subroutine messages_write_integer(val, fmt, new_line, units, print_units)
subroutine, public time_sum(sec1, usec1, sec2, usec2)
Computes t2 <- t1+t2. Parameters as in time_diff Assert: t1,2 <= 0.
subroutine, public messages_init()
subroutine messages_print_var_option_4(var, option, pre, iunit, namespace)
subroutine, public messages_obsolete_variable(namespace, name, rep)
subroutine, public messages_switch_status(status)
create status file for asynchronous communication
subroutine, public print_date(str)
subroutine flush_msg(str, iunit, adv)
subroutine, public messages_print_var_info(var, iunit, namespace)
subroutine, public messages_update_mpi_grp(namespace, mpigrp)
subroutine, public messages_info(no_lines, iunit, verbose_limit, stress, all_nodes, namespace)
subroutine, public messages_new_line()
subroutine, public dealloc_error(size, file, line)
subroutine messages_print_var_values(var, val, iunit, namespace)
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
subroutine, public pop_sub(sub_name)
subroutine messages_print_var_valuei(var, val, iunit, namespace)
subroutine, public messages_input_error(namespace, var, details, row, column)
subroutine messages_print_var_valuer(var, val, unit, iunit, namespace)
integer, parameter, private sleepytime_nonwriters
seconds
subroutine, public messages_experimental(name, namespace)
subroutine messages_print_var_valuel(var, val, iunit, namespace)
subroutine messages_write_logical(val, new_line)
subroutine messages_write_str(val, fmt, new_line)
type(mpi_grp_t) function messages_get_mpi_grp(namespace)
subroutine, public messages_dump_stack(isignal)
integer function messages_get_unit(namespace)
subroutine messages_write_float(val, fmt, new_line, units, align_left, print_units)
subroutine messages_reset_lines()
logical function mpi_grp_is_root(grp)
type(mpi_grp_t), public mpi_world
integer, public mpi_err
used to store return values of mpi calls
type(namespace_t), public global_namespace
logical function, public parse_is_defined(namespace, name)
This module implements a simple hash table for string valued keys and integer values using the C++ ST...
subroutine, public sihash_insert(h, key, val)
Insert a (key, val) pair into the hash table h.
subroutine, public sihash_init(h)
Initialize a hash table h with size entries. Since we use separate chaining, the number of entries in...
integer function, public sihash_lookup(h, key, found)
Look up a value in the hash table h. If found is present, it indicates if key could be found in the t...
subroutine, public sihash_end(h)
Free a hash table.
This module implements a simple hash table for string valued keys and integer values using the C++ ST...
subroutine, public sphash_init(h)
Initialize a hash table h with size entries. Since we use separate chaining, the number of entries in...
subroutine, public sphash_insert(h, key, val, clone)
Insert a (key, val) pair into the hash table h. If clone=.true., the object will be copied.
subroutine, public sphash_end(h)
Free a hash table.
class(*) function, pointer, public sphash_lookup(h, key, found)
Look up a value in the hash table h. If found is present, it indicates if key could be found in the t...
character(len=80) function, public str_center(s_in, l_in)
puts space around string, so that it is centered
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
character(len=20) pure function, public units_abbrev(this)
subroutine, public varinfo_print_option(iunit, var, option, pre)
subroutine, public varinfo_print(iunit, var, ierr)
This is defined even when running serial.
real(8) function values(xx)