Go to the documentation of this file.
36 subroutine warn_msg(code, warning_msg, already_warned)
39 integer,
intent(in) :: code
41 character(len=*),
intent(in) :: warning_msg
43 logical,
intent(inout),
optional :: already_warned
45 if (
present(already_warned))
then
46 if (already_warned)
return
48 already_warned = .true.
51 //
'): ' // trim(warning_msg)
61 integer,
intent(in) :: code
63 logical,
intent(in) :: condition_ok
65 character(len=*),
intent(in) :: warning_msg
67 if (.not. condition_ok)
then
79 integer,
intent(in) :: code
81 logical,
intent(in) :: condition_ok
83 character(len=*),
intent(in) :: error_msg
87 if (.not. condition_ok)
then
89 //
'): ' // trim(error_msg)
91 call mpi_abort(mpi_comm_world, code, ierr)
105 integer,
intent(in) :: code
107 logical,
intent(in) :: condition_ok
109 if (.not. condition_ok)
then
113 call assert_msg(code, condition_ok,
'assertion failed')
124 integer,
intent(in) :: code
126 call assert(code, .false.)
136 integer,
intent(in) :: code
138 character(len=*),
intent(in) :: error_msg
159 if (.not. found_unit)
then
161 'no more units available - need to free_unit()')
173 integer,
intent(in) :: unit
187 character(len=*),
intent(in) :: filename
189 integer,
intent(out) :: unit
194 open(unit=unit, file=filename, status=
'old', action=
'read', iostat=ios)
195 call assert_msg(544344918, ios == 0,
'unable to open file ' &
208 character(len=*),
intent(in) :: filename
210 integer,
intent(out) :: unit
215 open(unit=unit, file=filename, status=
'replace', action=
'write', &
217 call assert_msg(609624199, ios == 0,
'unable to open file ' &
228 integer,
intent(in) :: unit
242 real(kind=
dp),
intent(in) :: v
254 real(kind=
dp),
intent(in) :: r
267 real(kind=
dp),
intent(in) :: r
279 real(kind=
dp),
intent(in) :: d
291 real(kind=
dp),
intent(in) :: temp
293 real(kind=
dp),
intent(in) :: pressure
295 real(kind=
dp) :: boltz, avogad, mwair, rgas, rhoair, viscosd, &
298 boltz =
const%boltzmann
299 avogad =
const%avagadro
300 mwair =
const%air_molec_weight
301 rgas =
const%univ_gas_const
303 rhoair = (pressure * mwair) / (rgas * temp)
305 viscosd = (1.8325d-5 * (296.16d0 + 120d0) / (temp + 120d0)) &
306 * (temp / 296.16d0)**1.5d0
307 viscosk = viscosd / rhoair
308 gasspeed = sqrt(8d0 * boltz * temp * avogad / (
const%pi * mwair))
320 real(kind=
dp),
intent(in) :: d1
322 real(kind=
dp),
intent(in) :: d2
325 real(kind=
dp),
parameter :: eps = 1d-8
331 if (abs(d1 - d2) / (abs(d1) + abs(d2)) .lt. eps)
then
347 real(kind=
dp),
intent(in) :: d1
349 real(kind=
dp),
intent(in) :: d2
351 real(kind=
dp),
intent(in) :: abs_tol
354 real(kind=
dp),
parameter :: eps = 1d-8
360 if ((abs(d1 - d2) .lt. abs_tol) .or. &
361 (abs(d1 - d2) / (abs(d1) + abs(d2)) .lt. eps))
then
375 second_name, second_time)
378 character(len=*),
intent(in) :: first_name
380 real(kind=
dp),
intent(in) :: first_time
382 character(len=*),
intent(in) :: second_name
384 real(kind=
dp),
intent(in) :: second_time
386 real(kind=
dp) :: ratio
388 ratio = first_time / second_time
389 if (abs(ratio - aint(ratio)) > 1d-6)
then
390 call warn_msg(952299377, trim(first_name) &
391 //
" is not an integer multiple of " // trim(second_name))
409 real(kind=
dp),
intent(in) :: time
411 real(kind=
dp),
intent(in) :: timestep
413 real(kind=
dp),
intent(in) :: interval
415 real(kind=
dp),
intent(inout) :: last_time
417 logical,
intent(out) :: do_event
420 real(kind=
dp),
parameter :: tolerance = 1d-6
422 real(kind=
dp) closest_interval_time
425 if (time .eq. 0d0)
then
429 if ((time - last_time) .lt. interval * (1d0 - tolerance))
then
433 if ((time - last_time) .ge. interval)
then
438 closest_interval_time = anint(time / interval) * interval
439 if (abs(time - closest_interval_time) &
440 .lt. abs(time + timestep - closest_interval_time)) &
462 real(kind=
dp),
intent(in) :: min_x
464 real(kind=
dp),
intent(in) :: max_x
466 integer,
intent(in) :: n
475 call assert(999299119, n >= 0)
477 a = real(i - 1, kind=
dp) / real(n - 1, kind=
dp)
478 linspace(i) = (1d0 - a) * min_x + a * max_x
494 real(kind=
dp),
intent(in) :: min_x
496 real(kind=
dp),
intent(in) :: max_x
498 integer,
intent(in) :: n
503 real(kind=
dp),
allocatable :: log_x(:)
507 call assert(804623592, n >= 0)
509 call assert(548290438, min_x > 0d0)
510 call assert(805259035, max_x > 0d0)
511 log_x =
linspace(log(min_x), log(max_x), n)
534 real(kind=
dp),
intent(in) :: min_x
536 real(kind=
dp),
intent(in) :: max_x
538 integer,
intent(in) :: n
540 real(kind=
dp),
intent(in) :: x
547 * real(n - 1, kind=
dp)) + 1
568 real(kind=
dp),
intent(in) :: min_x
570 real(kind=
dp),
intent(in) :: max_x
572 integer,
intent(in) :: n
574 real(kind=
dp),
intent(in) :: x
594 integer,
intent(in) :: n
596 real(kind=
dp),
intent(in) :: x_vals(n)
598 real(kind=
dp),
intent(in) :: x
607 do while (x >= x_vals(p))
628 real(kind=
dp),
intent(in) :: x_vals(:)
630 real(kind=
dp),
intent(in) :: y_vals(
size(x_vals))
632 real(kind=
dp),
intent(in) :: x
635 real(kind=
dp) :: y, alpha
644 if (y_vals(p) == y_vals(p+1))
then
647 alpha = (x - x_vals(p)) / (x_vals(p+1) - x_vals(p))
648 y = (1d0 - alpha) * y_vals(p) + alpha * y_vals(p+1)
665 real(kind=
dp),
intent(in) :: x_1
667 real(kind=
dp),
intent(in) :: x_n
669 integer,
intent(in) :: n
671 integer,
intent(in) :: i
673 real(kind=
dp) :: alpha
678 alpha = real(i - 1, kind=
dp) / real(n - 1, kind=
dp)
690 character(len=*),
intent(in) :: string
694 character(len=len(string)+300) :: error_msg
696 call assert_msg(447772570, len_trim(string) <= 20, &
697 'error converting "' // trim(string) &
698 //
'" to integer: string too long')
699 read(string,
'(i20)', iostat=ios) val
701 'error converting "' // trim(string) &
713 character(len=*),
intent(in) :: string
717 character(len=len(string)+300) :: error_msg
719 call assert_msg(733728030, len_trim(string) <= 30, &
720 'error converting "' // trim(string) //
'" to real: string too long')
721 read(string,
'(f30.0)', iostat=ios) val
723 'error converting "' // trim(string) &
735 character(len=*),
intent(in) :: string
739 character(len=len(string)+300) :: error_msg
742 if ((trim(string) ==
'yes') &
743 .or. (trim(string) ==
'y') &
744 .or. (trim(string) ==
'true') &
745 .or. (trim(string) ==
't') &
746 .or. (trim(string) ==
'1'))
then
748 elseif ((trim(string) ==
'no') &
749 .or. (trim(string) ==
'n') &
750 .or. (trim(string) ==
'false') &
751 .or. (trim(string) ==
'f') &
752 .or. (trim(string) ==
'0'))
then
755 call die_msg(985010153,
'error converting "' // trim(string) &
768 integer,
intent(in) :: val
770 character(len=PMC_UTIL_CONVERT_STRING_LEN) :: ret_val
773 write(ret_val,
'(i30)') val
784 real(kind=
dp),
intent(in) :: val
786 character(len=PMC_UTIL_CONVERT_STRING_LEN) :: ret_val
789 write(ret_val,
'(g30.20)') val
800 logical,
intent(in) :: val
802 character(len=PMC_UTIL_CONVERT_STRING_LEN) :: ret_val
820 complex(kind=dc),
intent(in) :: val
822 character(len=PMC_UTIL_CONVERT_STRING_LEN) :: ret_val
834 character(len=PMC_UTIL_CONVERT_STRING_LEN) &
838 integer,
intent(in) :: val
840 integer,
intent(in) :: max_len
842 character(len=PMC_UTIL_CONVERT_STRING_LEN) :: ret_val
845 if (len_trim(ret_val) > max_len)
then
855 character(len=PMC_UTIL_CONVERT_STRING_LEN) &
859 real(kind=
dp),
intent(in) :: val
861 integer,
intent(in) :: max_len
863 character(len=PMC_UTIL_CONVERT_STRING_LEN) :: ret_val, exp_str, frac_str
864 integer :: exp_val, exp_len, frac_len, use_frac_len, min_frac_len, i
865 real(kind=
dp) :: frac_val
869 if (max_len >= 3)
then
880 exp_val = floor(log10(abs(val)))
881 frac_val = val / 10d0**exp_val
885 exp_len = len_trim(exp_str)
886 frac_len = len_trim(frac_str)
887 use_frac_len = max_len - 1 - exp_len
888 if (use_frac_len > frac_len)
then
889 use_frac_len = frac_len
896 if (use_frac_len < min_frac_len)
then
901 ret_val = frac_str(1:use_frac_len) //
"e" // trim(exp_str)
910 character(len=PMC_UTIL_CONVERT_STRING_LEN) &
914 real(kind=
dp),
intent(in) :: time
916 integer,
intent(in) :: max_len
918 integer,
dimension(4),
parameter :: scale = (/ 1, 60, 60, 24 /)
919 character,
dimension(4),
parameter :: unit = (/
"s",
"m",
"h",
"d" /)
921 character(len=PMC_UTIL_CONVERT_STRING_LEN) :: ret_val
924 real(kind=
dp) :: scaled_time
929 scaled_time = scaled_time / real(scale(i), kind=
dp)
931 if (len_trim(ret_val) <= max_len)
then
936 if (.not. len_ok)
then
955 integer,
intent(in) :: n
957 real(kind=
dp),
intent(in) :: vec_cts(n)
959 integer,
intent(in) :: n_samp
961 integer,
intent(out) :: vec_disc(n)
964 real(kind=
dp) :: vec_tot
966 vec_tot = sum(vec_cts)
969 vec_disc = nint(vec_cts / vec_tot * real(n_samp, kind=
dp))
972 do while (sum(vec_disc) < n_samp)
973 k = minloc(abs(real(vec_disc + 1, kind=
dp) - vec_cts) &
974 - abs(real(vec_disc, kind=
dp) - vec_cts))
975 vec_disc(k) = vec_disc(k) + 1
979 do while (sum(vec_disc) > n_samp)
980 k = minloc(abs(real(vec_disc - 1, kind=
dp) - vec_cts) &
981 - abs(real(vec_disc, kind=
dp) - vec_cts))
982 vec_disc(k) = vec_disc(k) - 1
985 call assert_msg(323412496, sum(vec_disc) == n_samp, &
986 'generated incorrect number of samples')
996 integer,
intent(in) :: int_vec(:)
998 integer,
intent(out) :: int_avg
1000 int_avg = sum(int_vec) /
size(int_vec)
1010 real(kind=
dp),
intent(in) :: real_vec(:)
1012 real(kind=
dp),
intent(out) :: real_avg
1014 real_avg = sum(real_vec) / real(
size(real_vec), kind=
dp)
1025 character(len=*),
intent(in) :: array(:)
1027 character(len=*),
intent(in) :: val
1043 real(kind=
dp),
intent(inout),
allocatable :: x(:)
1045 integer,
intent(in) :: n
1047 logical,
intent(in),
optional :: only_grow
1050 real(kind=
dp),
allocatable :: tmp_x(:)
1052 if (
allocated(x))
then
1054 if (
present(only_grow))
then
1055 new_n = max(new_n,
size(x))
1057 if (
size(x) /= new_n)
then
1058 allocate(tmp_x(new_n))
1060 tmp_x(1:min(new_n,
size(x))) = x(1:min(new_n,
size(x)))
1061 call move_alloc(tmp_x, x)
1077 real(kind=
dp),
intent(inout),
allocatable :: x(:, :)
1079 integer,
intent(in) :: n1
1081 integer,
intent(in) :: n2
1083 logical,
intent(in),
optional :: only_grow
1085 integer :: new_n1, new_n2, n1_min, n2_min
1086 real(kind=
dp),
allocatable :: tmp_x(:, :)
1088 if (
allocated(x))
then
1091 if (
present(only_grow))
then
1092 new_n1 = max(new_n1,
size(x, 1))
1093 new_n2 = max(new_n2,
size(x, 2))
1095 if ((
size(x, 1) /= new_n1) .or. (
size(x, 2) /= new_n2))
then
1096 allocate(tmp_x(new_n1, new_n2))
1097 n1_min = min(new_n1,
size(x, 1))
1098 n2_min = min(new_n2,
size(x, 2))
1100 tmp_x(1:n1_min, 1:n2_min) = x(1:n1_min, 1:n2_min)
1101 call move_alloc(tmp_x, x)
1117 integer,
intent(inout),
allocatable :: x(:)
1119 integer,
intent(in) :: n
1121 logical,
intent(in),
optional :: only_grow
1124 integer,
allocatable :: tmp_x(:)
1126 if (
allocated(x))
then
1128 if (
present(only_grow))
then
1129 new_n = max(new_n,
size(x))
1131 if (
size(x) /= new_n)
then
1132 allocate(tmp_x(new_n))
1134 tmp_x(1:min(new_n,
size(x))) = x(1:min(new_n,
size(x)))
1135 call move_alloc(tmp_x, x)
1151 integer,
intent(inout),
allocatable :: x(:, :)
1153 integer,
intent(in) :: n1
1155 integer,
intent(in) :: n2
1157 logical,
intent(in),
optional :: only_grow
1159 integer :: new_n1, new_n2, n1_min, n2_min
1160 integer,
allocatable :: tmp_x(:, :)
1162 if (
allocated(x))
then
1165 if (
present(only_grow))
then
1166 new_n1 = max(new_n1,
size(x, 1))
1167 new_n2 = max(new_n2,
size(x, 2))
1169 if ((
size(x, 1) /= new_n1) .or. (
size(x, 2) /= new_n2))
then
1170 allocate(tmp_x(new_n1, new_n2))
1171 n1_min = min(new_n1,
size(x, 1))
1172 n2_min = min(new_n2,
size(x, 2))
1174 tmp_x(1:n1_min, 1:n2_min) = x(1:n1_min, 1:n2_min)
1175 call move_alloc(tmp_x, x)
1191 character(len=*),
intent(inout),
allocatable :: x(:)
1193 integer,
intent(in) :: n
1195 if (
allocated(x))
then
1196 if (
size(x) /= n)
then
1216 character(len=*),
intent(in) :: filename
1218 character(len=*),
intent(out) :: basename
1221 logical :: found_period
1224 i = len_trim(basename)
1225 found_period = .false.
1226 do while ((i > 0) .and. (.not. found_period))
1231 if (basename(i:i) ==
".")
then
1232 found_period = .true.
1249 character(len=*),
intent(out) :: date_time
1251 character(len=10) :: date, time, zone
1253 call assert_msg(893219839, len(date_time) >= 29, &
1254 "date_time string must have length at least 29")
1255 call date_and_time(date, time, zone)
1257 write(date_time,
'(14a)') date(1:4),
"-", date(5:6),
"-", &
1258 date(7:8),
"T", time(1:2),
":", time(3:4),
":", &
1259 time(5:10), zone(1:3),
":", zone(4:5)
1269 real(kind=
dp),
intent(in) :: deg
1281 real(kind=
dp),
intent(in) :: rad
1297 integer,
intent(inout) :: data(:)
1299 integer,
intent(out) :: perm(size(data))
1301 #ifdef PMC_USE_C_SORT
1302 integer(kind=c_int) :: n_c
1303 integer(kind=c_int),
target :: data_c(size(data))
1304 integer(kind=c_int),
target :: perm_c(size(data))
1305 type(c_ptr) :: data_ptr, perm_ptr
1307 #ifndef DOXYGEN_SKIP_DOC
1311 integer(kind=c_int),
value :: n_c
1312 type(c_ptr),
value :: data_ptr, perm_ptr
1317 data_c = int(
data, kind=c_int)
1319 n_c = int(
size(data), kind=c_int)
1320 data_ptr = c_loc(data_c)
1321 perm_ptr = c_loc(perm_c)
1335 character(len=*),
intent(in) :: filename
1337 real(kind=
dp),
intent(inout),
allocatable ::
data(:,:)
1339 integer :: unit, row, col
1341 character(len=1000) :: word
1350 do while (.not. eof)
1352 if (len_trim(word) > 0)
then
1354 if (col >
size(
data, 2))
then
1358 if (col >
size(
data, 2))
then
1359 call assert_msg(516120334, col <=
size(
data, 2), &
1360 trim(filename) //
": line " &
1364 if (row >
size(
data, 1))
then
1370 if (eol .or. eof)
then
1375 (col == 1) .or. (col ==
size(
data, 2) + 1), &
1376 trim(filename) //
": line " &
1399 character(len=*),
intent(in) :: filename
1401 real(kind=
dp),
intent(in) ::
data(:)
1407 write(unit,
'(e30.15e3)')
data(i)
1419 character(len=*),
intent(in) :: filename
1421 real(kind=
dp),
intent(in) ::
data(:,:)
1423 integer :: unit, i, j
1426 do i = 1,
size(
data, 1)
1427 do j = 1,
size(
data, 2)
1428 write(unit,
'(e30.15e3)', advance=
'no')
data(i, j)
1442 real(kind=
dp),
allocatable,
intent(inout) ::
data(:,:)
1444 integer,
intent(in) :: rows
1446 integer,
intent(in) :: cols
1448 real(kind=
dp) :: tmp_data(rows, cols)
1449 integer :: data_rows, data_cols
1451 data_rows = min(rows,
size(
data, 1))
1452 data_cols = min(cols,
size(
data, 2))
1453 tmp_data(1:data_rows, 1:data_cols) =
data(1:data_rows, 1:data_cols)
1455 allocate(
data(rows, cols))
1456 data(1:data_rows, 1:data_cols) = tmp_data(1:data_rows, 1:data_cols)
1490 integer,
intent(in) :: unit
1492 character,
intent(out) :: char
1494 logical,
intent(out) :: eol
1496 logical,
intent(out) :: eof
1498 integer :: ios, n_read
1499 character(len=1) :: read_char
1505 read(unit=unit, fmt=
'(a)', advance=
'no',
end=100, eor=110, &
1506 iostat=ios) read_char
1508 write(0,*)
'ERROR: reading file: IOSTAT = ', ios
1534 integer,
intent(in) :: unit
1536 character(len=*),
intent(out) :: word
1538 logical,
intent(out) :: eol
1540 logical,
intent(out) :: eof
1549 do while (((ichar(char) == 9) .or. (ichar(char) == 32)) &
1550 .and. (.not. eol) .and. (.not. eof))
1553 if (eol .or. eof)
return
1559 do while ((ichar(char) /= 9) .and. (ichar(char) /= 32) &
1560 .and. (.not. eol) .and. (.not. eof) .and. (i < len(word)))
1563 if (i < len(word))
then
1579 character(len=*),
intent(in) :: string
1581 character(len=*),
intent(in) :: start_string
1583 if (len(string) < len(start_string))
then
1587 if (string(1:len(start_string)) == start_string)
then
1601 real(kind=
dp),
intent(in) :: x1
1603 real(kind=
dp),
intent(in) :: x2
1615 real(kind=
dp),
intent(in) :: p
1632 real(kind=
dp),
intent(in) :: p(:)
1644 integer,
intent(in) :: n
1652 pow2_above = ibset(0, bit_size(n) - leadz(n - 1))
subroutine open_file_read(filename, unit)
Open a file for reading with an automatically assigned unit and test that it succeeds....
integer function linspace_find(min_x, max_x, n, x)
Find the position of a real number in a 1D linear array.
subroutine read_char_raw(unit, char, eol, eof)
Read a single character from a file, signaling if we have hit EOL or EOF. If EOL or EOF are true then...
character(len=pmc_util_convert_string_len) function real_to_string_max_len(val, max_len)
Convert a real to a string format of maximum length.
character(len=pmc_util_convert_string_len) function time_to_string_max_len(time, max_len)
Convert a time to a string format of maximum length.
character(len=pmc_util_convert_string_len) function logical_to_string(val)
Convert a logical to a string format.
logical function string_to_logical(string)
Convert a string to a logical.
real(kind=dp) elemental function rad2diam(r)
Convert radius (m) to diameter (m).
character(len=pmc_util_convert_string_len) function complex_to_string(val)
Convert a complex to a string format.
logical function starts_with(string, start_string)
Checks whether a string starts with a given other string.
subroutine integer_sort(data, perm)
Sort the given data array and return the permutation defining the sort.
integer function get_unit()
Returns an available unit number. This should be freed by free_unit().
character(len=pmc_util_convert_string_len) function integer_to_string_max_len(val, max_len)
Convert an integer to a string format of maximum length.
elemental real(kind=dp) function nplogp(p)
Compute for computing entropy.
subroutine open_file_write(filename, unit)
Open a file for writing with an automatically assigned unit and test that it succeeds....
real(kind=dp) elemental function sphere_rad2vol(r)
Convert geometric radius (m) to mass-equivalent volume (m^3) for spherical particles.
subroutine warn_assert_msg(code, condition_ok, warning_msg)
Prints a warning message if condition_ok is false.
subroutine die_msg(code, error_msg)
Error immediately.
integer, parameter unit_offset
Minimum unit number to allocate.
integer, parameter dp
Kind of a double precision real number.
subroutine ensure_real_array_size(x, n, only_grow)
Allocate or reallocate the given array to ensure it is of the given size, preserving any data and/or ...
real(kind=dp) function interp_1d(x_vals, y_vals, x)
1D linear interpolation.
integer function pow2_above(n)
Return the least power-of-2 that is at least equal to n.
subroutine get_basename(filename, basename)
Strip the extension to find the basename.
subroutine assert(code, condition_ok)
Errors unless condition_ok is true.
int integer_sort_c(int n, int *data, int *perm)
Sort the given data array and return the permutation.
integer function string_to_integer(string)
Convert a string to an integer.
real(kind=dp) function, dimension(:), allocatable logspace(min_x, max_x, n)
Makes a logarithmically spaced array of length n from min to max.
real(kind=dp) function interp_linear_disc(x_1, x_n, n, i)
Linear interpolation over discrete indices.
subroutine reallocate_real_array2d(data, rows, cols)
Reallocate a 2D real array to the given size, preserving the contents.
real(kind=dp) elemental function sphere_vol2rad(v)
Convert mass-equivalent volume (m^3) to geometric radius (m) for spherical particles.
real(kind=dp) function, dimension(:), allocatable linspace(min_x, max_x, n)
Makes a linearly spaced array from min to max.
subroutine warn_msg(code, warning_msg, already_warned)
Prints a warning message.
elemental real(kind=dp) function harmonic_mean(x1, x2)
Compute the harmonic mean of two numbers.
subroutine ensure_real_array_2d_size(x, n1, n2, only_grow)
Allocate or reallocate the given array to ensure it is of the given size, preserving any data and/or ...
integer, parameter pmc_max_filename_len
Maximum length of filenames.
subroutine check_time_multiple(first_name, first_time, second_name, second_time)
Check that the first time interval is close to an integer multiple of the second, and warn if it is n...
character(len=pmc_util_convert_string_len) function integer_to_string(val)
Convert an integer to a string format.
character(len=pmc_util_convert_string_len) function real_to_string(val)
Convert a real to a string format.
subroutine assert_msg(code, condition_ok, error_msg)
Errors unless condition_ok is true.
real(kind=dp) elemental function diam2rad(d)
Convert diameter (m) to radius (m).
real(kind=dp) function deg2rad(deg)
Convert degrees to radians.
type(const_t), save const
Fixed variable for accessing the constant's values.
subroutine average_real(real_vec, real_avg)
Computes the average of an array of real numbers.
real(kind=dp) function rad2deg(rad)
Convert radians to degrees.
logical, dimension(max_units), save unit_used
Table of unit numbers storing allocation status.
integer function logspace_find(min_x, max_x, n, x)
Find the position of a real number in a 1D logarithmic array.
subroutine ensure_string_array_size(x, n)
Allocate or reallocate the given array to ensure it is of the given size, without preserving data.
integer, parameter max_units
Maximum number of IO units usable simultaneously.
real(kind=dp) function entropy(p)
Compute the entropy of a probability mass function (non necessarily normalized).
subroutine ensure_integer_array_2d_size(x, n1, n2, only_grow)
Allocate or reallocate the given array to ensure it is of the given size, preserving any data and/or ...
subroutine loadtxt(filename, data)
Load a real array from a text file.
Common utility subroutines.
subroutine check_event(time, timestep, interval, last_time, do_event)
Computes whether an event is scheduled to take place.
integer function string_array_find(array, val)
Return the index of the first occurance of the given value in the array, or 0 if it is not present.
logical function almost_equal(d1, d2)
Tests whether two real numbers are almost equal using only a relative tolerance.
real(kind=dp) function air_mean_free_path(temp, pressure)
Calculate air molecular mean free path (m).
subroutine average_integer(int_vec, int_avg)
Computes the average of an array of integer numbers.
subroutine free_unit(unit)
Frees a unit number returned by get_unit().
subroutine die(code)
Error immediately.
subroutine close_file(unit)
Close a file and de-assign the unit.
subroutine iso8601_date_and_time(date_time)
Current date and time in ISO 8601 format.
subroutine savetxt_2d(filename, data)
Write a real 2D array to a text file.
logical function almost_equal_abs(d1, d2, abs_tol)
Tests whether two real numbers are almost equal using an absolute and relative tolerance.
subroutine savetxt_1d(filename, data)
Write a real 1D array to a text file.
subroutine vec_cts_to_disc(n, vec_cts, n_samp, vec_disc)
Convert a real-valued vector into an integer-valued vector.
integer, parameter pmc_util_convert_string_len
Length of string for converting numbers.
real(kind=dp) function string_to_real(string)
Convert a string to a real.
subroutine read_word_raw(unit, word, eol, eof)
Read a white-space delimited word from a file, signaling if we have EOL or EOF. If EOL or EOF are tru...
subroutine ensure_integer_array_size(x, n, only_grow)
Allocate or reallocate the given array to ensure it is of the given size, preserving any data and/or ...
integer function find_1d(n, x_vals, x)
Find the position of a real number in an arbitrary 1D array.