Go to the documentation of this file.
37 subroutine warn_msg(code, warning_msg, already_warned)
40 integer,
intent(in) :: code
42 character(len=*),
intent(in) :: warning_msg
44 logical,
intent(inout),
optional :: already_warned
46 if (
present(already_warned))
then
47 if (already_warned)
return
49 already_warned = .true.
52 //
'): ' // trim(warning_msg)
62 integer,
intent(in) :: code
64 logical,
intent(in) :: condition_ok
66 character(len=*),
intent(in) :: warning_msg
68 if (.not. condition_ok)
then
80 integer,
intent(in) :: code
82 logical,
intent(in) :: condition_ok
84 character(len=*),
intent(in) :: error_msg
88 if (.not. condition_ok)
then
90 //
'): ' // trim(error_msg)
92 call mpi_abort(mpi_comm_world, code, ierr)
106 integer,
intent(in) :: code
108 logical,
intent(in) :: condition_ok
110 if (.not. condition_ok)
then
114 call assert_msg(code, condition_ok,
'assertion failed')
125 integer,
intent(in) :: code
127 call assert(code, .false.)
137 integer,
intent(in) :: code
139 character(len=*),
intent(in) :: error_msg
160 if (.not. found_unit)
then
162 'no more units available - need to free_unit()')
174 integer,
intent(in) :: unit
188 character(len=*),
intent(in) :: filename
190 integer,
intent(out) :: unit
195 open(unit=unit, file=filename, status=
'old', action=
'read', iostat=ios)
196 call assert_msg(544344918, ios == 0,
'unable to open file ' &
209 character(len=*),
intent(in) :: filename
211 integer,
intent(out) :: unit
216 open(unit=unit, file=filename, status=
'replace', action=
'write', &
218 call assert_msg(609624199, ios == 0,
'unable to open file ' &
229 integer,
intent(in) :: unit
243 real(kind=
dp),
intent(in) :: v
255 real(kind=
dp),
intent(in) :: r
268 real(kind=
dp),
intent(in) :: r
280 real(kind=
dp),
intent(in) :: d
292 real(kind=
dp),
intent(in) :: temp
294 real(kind=
dp),
intent(in) :: pressure
296 real(kind=
dp) :: boltz, avogad, mwair, rgas, rhoair, viscosd, &
299 boltz =
const%boltzmann
300 avogad =
const%avagadro
301 mwair =
const%air_molec_weight
302 rgas =
const%univ_gas_const
304 rhoair = (pressure * mwair) / (rgas * temp)
306 viscosd = (1.8325d-5 * (296.16d0 + 120d0) / (temp + 120d0)) &
307 * (temp / 296.16d0)**1.5d0
308 viscosk = viscosd / rhoair
309 gasspeed = sqrt(8d0 * boltz * temp * avogad / (
const%pi * mwair))
321 real(kind=
dp),
intent(in) :: d1
323 real(kind=
dp),
intent(in) :: d2
326 real(kind=
dp),
parameter :: eps = 1d-8
332 if (abs(d1 - d2) / (abs(d1) + abs(d2)) .lt. eps)
then
348 real(kind=
dp),
intent(in) :: d1
350 real(kind=
dp),
intent(in) :: d2
352 real(kind=
dp),
intent(in) :: abs_tol
355 real(kind=
dp),
parameter :: eps = 1d-8
361 if ((abs(d1 - d2) .lt. abs_tol) .or. &
362 (abs(d1 - d2) / (abs(d1) + abs(d2)) .lt. eps))
then
376 second_name, second_time)
379 character(len=*),
intent(in) :: first_name
381 real(kind=
dp),
intent(in) :: first_time
383 character(len=*),
intent(in) :: second_name
385 real(kind=
dp),
intent(in) :: second_time
387 real(kind=
dp) :: ratio
389 ratio = first_time / second_time
390 if (abs(ratio - aint(ratio)) > 1d-6)
then
391 call warn_msg(952299377, trim(first_name) &
392 //
" is not an integer multiple of " // trim(second_name))
410 real(kind=
dp),
intent(in) :: time
412 real(kind=
dp),
intent(in) :: timestep
414 real(kind=
dp),
intent(in) :: interval
416 real(kind=
dp),
intent(inout) :: last_time
418 logical,
intent(out) :: do_event
421 real(kind=
dp),
parameter :: tolerance = 1d-6
423 real(kind=
dp) closest_interval_time
426 if (time .eq. 0d0)
then
430 if ((time - last_time) .lt. interval * (1d0 - tolerance))
then
434 if ((time - last_time) .ge. interval)
then
439 closest_interval_time = anint(time / interval) * interval
440 if (abs(time - closest_interval_time) &
441 .lt. abs(time + timestep - closest_interval_time)) &
463 real(kind=
dp),
intent(in) :: min_x
465 real(kind=
dp),
intent(in) :: max_x
467 integer,
intent(in) :: n
476 call assert(999299119, n >= 0)
478 a = real(i - 1, kind=
dp) / real(n - 1, kind=
dp)
479 linspace(i) = (1d0 - a) * min_x + a * max_x
495 real(kind=
dp),
intent(in) :: min_x
497 real(kind=
dp),
intent(in) :: max_x
499 integer,
intent(in) :: n
504 real(kind=
dp),
allocatable :: log_x(:)
508 call assert(804623592, n >= 0)
510 call assert(548290438, min_x > 0d0)
511 call assert(805259035, max_x > 0d0)
512 log_x =
linspace(log(min_x), log(max_x), n)
535 real(kind=
dp),
intent(in) :: min_x
537 real(kind=
dp),
intent(in) :: max_x
539 integer,
intent(in) :: n
541 real(kind=
dp),
intent(in) :: x
548 * real(n - 1, kind=
dp)) + 1
569 real(kind=
dp),
intent(in) :: min_x
571 real(kind=
dp),
intent(in) :: max_x
573 integer,
intent(in) :: n
575 real(kind=
dp),
intent(in) :: x
595 integer,
intent(in) :: n
597 real(kind=
dp),
intent(in) :: x_vals(n)
599 real(kind=
dp),
intent(in) :: x
608 do while (x >= x_vals(p))
629 real(kind=
dp),
intent(in) :: x_vals(:)
631 real(kind=
dp),
intent(in) :: y_vals(
size(x_vals))
633 real(kind=
dp),
intent(in) :: x
636 real(kind=
dp) :: y, alpha
645 if (y_vals(p) == y_vals(p+1))
then
648 alpha = (x - x_vals(p)) / (x_vals(p+1) - x_vals(p))
649 y = (1d0 - alpha) * y_vals(p) + alpha * y_vals(p+1)
666 real(kind=
dp),
intent(in) :: x_1
668 real(kind=
dp),
intent(in) :: x_n
670 integer,
intent(in) :: n
672 integer,
intent(in) :: i
674 real(kind=
dp) :: alpha
679 alpha = real(i - 1, kind=
dp) / real(n - 1, kind=
dp)
691 character(len=*),
intent(in) :: string
695 character(len=len(string)+300) :: error_msg
697 call assert_msg(447772570, len_trim(string) <= 20, &
698 'error converting "' // trim(string) &
699 //
'" to integer: string too long')
700 read(string,
'(i20)', iostat=ios) val
702 'error converting "' // trim(string) &
714 character(len=*),
intent(in) :: string
718 character(len=len(string)+300) :: error_msg
720 call assert_msg(733728030, len_trim(string) <= 30, &
721 'error converting "' // trim(string) //
'" to real: string too long')
722 read(string,
'(f30.0)', iostat=ios) val
724 'error converting "' // trim(string) &
736 character(len=*),
intent(in) :: string
740 character(len=len(string)+300) :: error_msg
743 if ((trim(string) ==
'yes') &
744 .or. (trim(string) ==
'y') &
745 .or. (trim(string) ==
'true') &
746 .or. (trim(string) ==
't') &
747 .or. (trim(string) ==
'1'))
then
749 elseif ((trim(string) ==
'no') &
750 .or. (trim(string) ==
'n') &
751 .or. (trim(string) ==
'false') &
752 .or. (trim(string) ==
'f') &
753 .or. (trim(string) ==
'0'))
then
756 call die_msg(985010153,
'error converting "' // trim(string) &
769 integer,
intent(in) :: val
771 character(len=PMC_UTIL_CONVERT_STRING_LEN) :: ret_val
774 write(ret_val,
'(i30)') val
785 integer(kind=8),
intent(in) :: val
787 character(len=PMC_UTIL_CONVERT_STRING_LEN) :: ret_val
790 write(ret_val,
'(i30)') val
801 real(kind=
dp),
intent(in) :: val
803 character(len=PMC_UTIL_CONVERT_STRING_LEN) :: ret_val
806 write(ret_val,
'(g30.20)') val
817 logical,
intent(in) :: val
819 character(len=PMC_UTIL_CONVERT_STRING_LEN) :: ret_val
837 complex(kind=dc),
intent(in) :: val
839 character(len=PMC_UTIL_CONVERT_STRING_LEN) :: ret_val
851 character(len=PMC_UTIL_CONVERT_STRING_LEN) &
855 integer,
intent(in) :: val
857 integer,
intent(in) :: max_len
859 character(len=PMC_UTIL_CONVERT_STRING_LEN) :: ret_val
862 if (len_trim(ret_val) > max_len)
then
872 character(len=PMC_UTIL_CONVERT_STRING_LEN) &
876 real(kind=
dp),
intent(in) :: val
878 integer,
intent(in) :: max_len
880 character(len=PMC_UTIL_CONVERT_STRING_LEN) :: ret_val, exp_str, frac_str
881 integer :: exp_val, exp_len, frac_len, use_frac_len, min_frac_len, i
882 real(kind=
dp) :: frac_val
886 if (max_len >= 3)
then
897 exp_val = floor(log10(abs(val)))
898 frac_val = val / 10d0**exp_val
902 exp_len = len_trim(exp_str)
903 frac_len = len_trim(frac_str)
904 use_frac_len = max_len - 1 - exp_len
905 if (use_frac_len > frac_len)
then
906 use_frac_len = frac_len
913 if (use_frac_len < min_frac_len)
then
918 ret_val = frac_str(1:use_frac_len) //
"e" // trim(exp_str)
927 character(len=PMC_UTIL_CONVERT_STRING_LEN) &
931 real(kind=
dp),
intent(in) :: time
933 integer,
intent(in) :: max_len
935 integer,
dimension(4),
parameter :: scale = (/ 1, 60, 60, 24 /)
936 character,
dimension(4),
parameter :: unit = (/
"s",
"m",
"h",
"d" /)
938 character(len=PMC_UTIL_CONVERT_STRING_LEN) :: ret_val
941 real(kind=
dp) :: scaled_time
946 scaled_time = scaled_time / real(scale(i), kind=
dp)
948 if (len_trim(ret_val) <= max_len)
then
953 if (.not. len_ok)
then
972 integer,
intent(in) :: n
974 real(kind=
dp),
intent(in) :: vec_cts(n)
976 integer,
intent(in) :: n_samp
978 integer,
intent(out) :: vec_disc(n)
981 real(kind=
dp) :: vec_tot
983 vec_tot = sum(vec_cts)
986 vec_disc = nint(vec_cts / vec_tot * real(n_samp, kind=
dp))
989 do while (sum(vec_disc) < n_samp)
990 k = minloc(abs(real(vec_disc + 1, kind=
dp) - vec_cts) &
991 - abs(real(vec_disc, kind=
dp) - vec_cts))
992 vec_disc(k) = vec_disc(k) + 1
996 do while (sum(vec_disc) > n_samp)
997 k = minloc(abs(real(vec_disc - 1, kind=
dp) - vec_cts) &
998 - abs(real(vec_disc, kind=
dp) - vec_cts))
999 vec_disc(k) = vec_disc(k) - 1
1002 call assert_msg(323412496, sum(vec_disc) == n_samp, &
1003 'generated incorrect number of samples')
1013 integer,
intent(in) :: int_vec(:)
1015 integer,
intent(out) :: int_avg
1017 int_avg = sum(int_vec) /
size(int_vec)
1027 real(kind=
dp),
intent(in) :: real_vec(:)
1029 real(kind=
dp),
intent(out) :: real_avg
1031 real_avg = sum(real_vec) / real(
size(real_vec), kind=
dp)
1042 character(len=*),
intent(in) :: array(:)
1044 character(len=*),
intent(in) :: val
1060 real(kind=
dp),
intent(inout),
allocatable :: x(:)
1062 integer,
intent(in) :: n
1064 logical,
intent(in),
optional :: only_grow
1067 real(kind=
dp),
allocatable :: tmp_x(:)
1069 if (
allocated(x))
then
1071 if (
present(only_grow))
then
1072 new_n = max(new_n,
size(x))
1074 if (
size(x) /= new_n)
then
1075 allocate(tmp_x(new_n))
1077 tmp_x(1:min(new_n,
size(x))) = x(1:min(new_n,
size(x)))
1078 call move_alloc(tmp_x, x)
1094 real(kind=
dp),
intent(inout),
allocatable :: x(:, :)
1096 integer,
intent(in) :: n1
1098 integer,
intent(in) :: n2
1100 logical,
intent(in),
optional :: only_grow
1102 integer :: new_n1, new_n2, n1_min, n2_min
1103 real(kind=
dp),
allocatable :: tmp_x(:, :)
1105 if (
allocated(x))
then
1108 if (
present(only_grow))
then
1109 new_n1 = max(new_n1,
size(x, 1))
1110 new_n2 = max(new_n2,
size(x, 2))
1112 if ((
size(x, 1) /= new_n1) .or. (
size(x, 2) /= new_n2))
then
1113 allocate(tmp_x(new_n1, new_n2))
1114 n1_min = min(new_n1,
size(x, 1))
1115 n2_min = min(new_n2,
size(x, 2))
1117 tmp_x(1:n1_min, 1:n2_min) = x(1:n1_min, 1:n2_min)
1118 call move_alloc(tmp_x, x)
1134 real(kind=
dp),
intent(inout),
allocatable :: x(:, :, :)
1136 integer,
intent(in) :: n1
1138 integer,
intent(in) :: n2
1140 integer,
intent(in) :: n3
1142 logical,
intent(in),
optional :: only_grow
1144 integer :: new_n1, new_n2, new_n3, n1_min, n2_min, n3_min
1145 real(kind=
dp),
allocatable :: tmp_x(:, :, :)
1147 if (
allocated(x))
then
1151 if (
present(only_grow))
then
1152 new_n1 = max(new_n1,
size(x, 1))
1153 new_n2 = max(new_n2,
size(x, 2))
1154 new_n3 = max(new_n3,
size(x, 3))
1156 if ((
size(x, 1) /= new_n1) .or. (
size(x, 2) /= new_n2) &
1157 .or. (
size(x,3) /= new_n3))
then
1158 allocate(tmp_x(new_n1, new_n2, new_n3))
1159 n1_min = min(new_n1,
size(x, 1))
1160 n2_min = min(new_n2,
size(x, 2))
1161 n3_min = min(new_n3,
size(x, 3))
1163 tmp_x(1:n1_min, 1:n2_min, 1:n3_min) = x(1:n1_min, 1:n2_min, 1:n3_min)
1164 call move_alloc(tmp_x, x)
1167 allocate(x(n1, n2, n3))
1180 real(kind=
dp),
intent(inout),
allocatable :: x(:, :, :, :)
1182 integer,
intent(in) :: n1
1184 integer,
intent(in) :: n2
1186 integer,
intent(in) :: n3
1188 integer,
intent(in) :: n4
1190 logical,
intent(in),
optional :: only_grow
1192 integer :: new_n1, new_n2, new_n3, new_n4, n1_min, n2_min, n3_min, n4_min
1193 real(kind=
dp),
allocatable :: tmp_x(:, :, :, :)
1195 if (
allocated(x))
then
1200 if (
present(only_grow))
then
1201 new_n1 = max(new_n1,
size(x, 1))
1202 new_n2 = max(new_n2,
size(x, 2))
1203 new_n3 = max(new_n3,
size(x, 3))
1204 new_n4 = max(new_n4,
size(x, 4))
1206 if ((
size(x, 1) /= new_n1) .or. (
size(x, 2) /= new_n2) &
1207 .or. (
size(x, 3) /= new_n3) .or. (
size(x, 4) /= new_n4))
then
1208 allocate(tmp_x(new_n1, new_n2, new_n3, new_n4))
1209 n1_min = min(new_n1,
size(x, 1))
1210 n2_min = min(new_n2,
size(x, 2))
1211 n3_min = min(new_n3,
size(x, 3))
1212 n4_min = min(new_n4,
size(x, 4))
1214 tmp_x(1:n1_min, 1:n2_min, 1:n3_min, 1:n4_min) = x(1:n1_min, &
1215 1:n2_min, 1:n3_min, 1:n4_min)
1216 call move_alloc(tmp_x, x)
1219 allocate(x(n1, n2, n3, n4))
1232 integer,
intent(inout),
allocatable :: x(:)
1234 integer,
intent(in) :: n
1236 logical,
intent(in),
optional :: only_grow
1239 integer,
allocatable :: tmp_x(:)
1241 if (
allocated(x))
then
1243 if (
present(only_grow))
then
1244 new_n = max(new_n,
size(x))
1246 if (
size(x) /= new_n)
then
1247 allocate(tmp_x(new_n))
1249 tmp_x(1:min(new_n,
size(x))) = x(1:min(new_n,
size(x)))
1250 call move_alloc(tmp_x, x)
1266 integer(kind=8),
intent(inout),
allocatable :: x(:)
1268 integer,
intent(in) :: n
1270 logical,
intent(in),
optional :: only_grow
1273 integer(kind=8),
allocatable :: tmp_x(:)
1275 if (
allocated(x))
then
1277 if (
present(only_grow))
then
1278 new_n = max(new_n,
size(x))
1280 if (
size(x) /= new_n)
then
1281 allocate(tmp_x(new_n))
1283 tmp_x(1:min(new_n,
size(x))) = x(1:min(new_n,
size(x)))
1284 call move_alloc(tmp_x, x)
1300 complex(kind=dc),
intent(inout),
allocatable :: x(:)
1302 integer,
intent(in) :: n
1304 logical,
intent(in),
optional :: only_grow
1307 complex(kind=dc),
allocatable :: tmp_x(:)
1309 if (
allocated(x))
then
1311 if (
present(only_grow))
then
1312 new_n = max(new_n,
size(x))
1314 if (
size(x) /= new_n)
then
1315 allocate(tmp_x(new_n))
1317 tmp_x(1:min(new_n,
size(x))) = x(1:min(new_n,
size(x)))
1318 call move_alloc(tmp_x, x)
1334 integer,
intent(inout),
allocatable :: x(:, :)
1336 integer,
intent(in) :: n1
1338 integer,
intent(in) :: n2
1340 logical,
intent(in),
optional :: only_grow
1342 integer :: new_n1, new_n2, n1_min, n2_min
1343 integer,
allocatable :: tmp_x(:, :)
1345 if (
allocated(x))
then
1348 if (
present(only_grow))
then
1349 new_n1 = max(new_n1,
size(x, 1))
1350 new_n2 = max(new_n2,
size(x, 2))
1352 if ((
size(x, 1) /= new_n1) .or. (
size(x, 2) /= new_n2))
then
1353 allocate(tmp_x(new_n1, new_n2))
1354 n1_min = min(new_n1,
size(x, 1))
1355 n2_min = min(new_n2,
size(x, 2))
1357 tmp_x(1:n1_min, 1:n2_min) = x(1:n1_min, 1:n2_min)
1358 call move_alloc(tmp_x, x)
1374 integer,
intent(inout),
allocatable :: x(:, :, :)
1376 integer,
intent(in) :: n1
1378 integer,
intent(in) :: n2
1380 integer,
intent(in) :: n3
1382 logical,
intent(in),
optional :: only_grow
1384 integer :: new_n1, new_n2, new_n3, n1_min, n2_min, n3_min
1385 integer,
allocatable :: tmp_x(:, :, :)
1387 if (
allocated(x))
then
1391 if (
present(only_grow))
then
1392 new_n1 = max(new_n1,
size(x, 1))
1393 new_n2 = max(new_n2,
size(x, 2))
1394 new_n3 = max(new_n2,
size(x, 3))
1396 if ((
size(x, 1) /= new_n1) .or. (
size(x, 2) /= new_n2) &
1397 .or. (
size(x,3) /= new_n3))
then
1398 allocate(tmp_x(new_n1, new_n2, new_n3))
1399 n1_min = min(new_n1,
size(x, 1))
1400 n2_min = min(new_n2,
size(x, 2))
1401 n3_min = min(new_n3,
size(x, 3))
1403 tmp_x(1:n1_min, 1:n2_min, 1:n3_min) = x(1:n1_min, 1:n2_min, 1:n3_min)
1404 call move_alloc(tmp_x, x)
1407 allocate(x(n1, n2, n3))
1420 integer,
intent(inout),
allocatable :: x(:, :, :, :)
1422 integer,
intent(in) :: n1
1424 integer,
intent(in) :: n2
1426 integer,
intent(in) :: n3
1428 integer,
intent(in) :: n4
1430 logical,
intent(in),
optional :: only_grow
1432 integer :: new_n1, new_n2, new_n3, new_n4, n1_min, n2_min, n3_min, n4_min
1433 integer,
allocatable :: tmp_x(:, :, :, :)
1435 if (
allocated(x))
then
1440 if (
present(only_grow))
then
1441 new_n1 = max(new_n1,
size(x, 1))
1442 new_n2 = max(new_n2,
size(x, 2))
1443 new_n3 = max(new_n3,
size(x, 3))
1444 new_n4 = max(new_n4,
size(x, 4))
1446 if ((
size(x, 1) /= new_n1) .or. (
size(x, 2) /= new_n2) &
1447 .or. (
size(x, 3) /= new_n3) .or. (
size(x, 4) /= new_n4))
then
1448 allocate(tmp_x(new_n1, new_n2, new_n3, new_n4))
1449 n1_min = min(new_n1,
size(x, 1))
1450 n2_min = min(new_n2,
size(x, 2))
1451 n3_min = min(new_n3,
size(x, 3))
1452 n4_min = min(new_n4,
size(x, 4))
1454 tmp_x(1:n1_min, 1:n2_min, 1:n3_min, 1:n4_min) = x(1:n1_min, &
1455 1:n2_min, 1:n3_min, 1:n4_min)
1456 call move_alloc(tmp_x, x)
1459 allocate(x(n1, n2, n3, n4))
1472 character(len=*),
intent(inout),
allocatable :: x(:)
1474 integer,
intent(in) :: n
1476 if (
allocated(x))
then
1477 if (
size(x) /= n)
then
1497 character(len=*),
intent(in) :: filename
1499 character(len=*),
intent(out) :: basename
1502 logical :: found_period
1505 i = len_trim(basename)
1506 found_period = .false.
1507 do while ((i > 0) .and. (.not. found_period))
1512 if (basename(i:i) ==
".")
then
1513 found_period = .true.
1530 character(len=*),
intent(out) :: date_time
1532 character(len=10) :: date, time, zone
1534 call assert_msg(893219839, len(date_time) >= 29, &
1535 "date_time string must have length at least 29")
1536 call date_and_time(date, time, zone)
1538 write(date_time,
'(14a)') date(1:4),
"-", date(5:6),
"-", &
1539 date(7:8),
"T", time(1:2),
":", time(3:4),
":", &
1540 time(5:10), zone(1:3),
":", zone(4:5)
1550 real(kind=
dp),
intent(in) :: deg
1562 real(kind=
dp),
intent(in) :: rad
1578 integer,
intent(inout) :: data(:)
1580 integer,
intent(out) :: perm(size(data))
1582 #ifdef PMC_USE_C_SORT
1583 integer(kind=c_int) :: n_c
1584 integer(kind=c_int),
target :: data_c(size(data))
1585 integer(kind=c_int),
target :: perm_c(size(data))
1586 type(c_ptr) :: data_ptr, perm_ptr
1588 #ifndef DOXYGEN_SKIP_DOC
1592 integer(kind=c_int),
value :: n_c
1593 type(c_ptr),
value :: data_ptr, perm_ptr
1598 data_c = int(
data, kind=c_int)
1600 n_c = int(
size(data), kind=c_int)
1601 data_ptr = c_loc(data_c)
1602 perm_ptr = c_loc(perm_c)
1615 real(kind=
dp),
intent(inout) ::
data(:)
1617 integer,
intent(out) :: perm(size(data))
1619 #ifdef PMC_USE_C_SORT
1620 integer(kind=c_int) :: n_c
1621 real(kind=c_double),
target :: data_c(
size(data))
1622 integer(kind=c_int),
target :: perm_c(size(data))
1623 type(c_ptr) :: data_ptr, perm_ptr
1625 #ifndef DOXYGEN_SKIP_DOC
1629 integer(kind=c_int),
value :: n_c
1630 type(c_ptr),
value :: data_ptr, perm_ptr
1634 data_c = real(
data, kind=c_double)
1636 n_c = int(
size(data), kind=c_int)
1637 data_ptr = c_loc(data_c)
1638 perm_ptr = c_loc(perm_c)
1652 character(len=*),
intent(in) :: filename
1654 real(kind=
dp),
intent(inout),
allocatable ::
data(:,:)
1656 integer :: unit, row, col
1658 character(len=1000) :: word
1667 do while (.not. eof)
1669 if (len_trim(word) > 0)
then
1671 if (col >
size(
data, 2))
then
1675 if (col >
size(
data, 2))
then
1676 call assert_msg(516120334, col <=
size(
data, 2), &
1677 trim(filename) //
": line " &
1681 if (row >
size(
data, 1))
then
1687 if (eol .or. eof)
then
1692 (col == 1) .or. (col ==
size(
data, 2) + 1), &
1693 trim(filename) //
": line " &
1716 character(len=*),
intent(in) :: filename
1718 real(kind=
dp),
intent(in) ::
data(:)
1724 write(unit,
'(e30.15e3)')
data(i)
1736 character(len=*),
intent(in) :: filename
1738 real(kind=
dp),
intent(in) ::
data(:,:)
1740 integer :: unit, i, j
1743 do i = 1,
size(
data, 1)
1744 do j = 1,
size(
data, 2)
1745 write(unit,
'(e30.15e3)', advance=
'no')
data(i, j)
1759 real(kind=
dp),
allocatable,
intent(inout) ::
data(:,:)
1761 integer,
intent(in) :: rows
1763 integer,
intent(in) :: cols
1765 real(kind=
dp) :: tmp_data(rows, cols)
1766 integer :: data_rows, data_cols
1768 data_rows = min(rows,
size(
data, 1))
1769 data_cols = min(cols,
size(
data, 2))
1770 tmp_data(1:data_rows, 1:data_cols) =
data(1:data_rows, 1:data_cols)
1772 allocate(
data(rows, cols))
1773 data(1:data_rows, 1:data_cols) = tmp_data(1:data_rows, 1:data_cols)
1807 integer,
intent(in) :: unit
1809 character,
intent(out) :: char
1811 logical,
intent(out) :: eol
1813 logical,
intent(out) :: eof
1815 integer :: ios, n_read
1816 character(len=1) :: read_char
1822 read(unit=unit, fmt=
'(a)', advance=
'no',
end=100, eor=110, &
1823 iostat=ios) read_char
1825 write(0,*)
'ERROR: reading file: IOSTAT = ', ios
1851 integer,
intent(in) :: unit
1853 character(len=*),
intent(out) :: word
1855 logical,
intent(out) :: eol
1857 logical,
intent(out) :: eof
1866 do while (((ichar(char) == 9) .or. (ichar(char) == 32)) &
1867 .and. (.not. eol) .and. (.not. eof))
1870 if (eol .or. eof)
return
1876 do while ((ichar(char) /= 9) .and. (ichar(char) /= 32) &
1877 .and. (.not. eol) .and. (.not. eof) .and. (i < len(word)))
1880 if (i < len(word))
then
1896 character(len=*),
intent(in) :: string
1898 character(len=*),
intent(in) :: start_string
1900 if (len(string) < len(start_string))
then
1904 if (string(1:len(start_string)) == start_string)
then
1918 real(kind=
dp),
intent(in) :: x1
1920 real(kind=
dp),
intent(in) :: x2
1932 real(kind=
dp),
intent(in) :: p
1949 real(kind=
dp),
intent(in) :: p(:)
1961 integer,
intent(in) :: n
1969 pow2_above = ibset(0, bit_size(n) - leadz(n - 1))
1979 integer(kind=8) :: clock_count, clock_count_rate
1981 call system_clock(clock_count, clock_count_rate)
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).
subroutine ensure_real_array_3d_size(x, n1, n2, n3, only_grow)
Allocate or reallocate the given array to ensure it is of the given size, preserving any data and/or ...
character(len=pmc_util_convert_string_len) function complex_to_string(val)
Convert a complex to a string format.
subroutine real_sort(data, perm)
real(kind=dp) function system_clock_time()
Returns the current system clock time in seconds.
logical function starts_with(string, start_string)
Checks whether a string starts with a given other string.
subroutine ensure_integer_array_4d_size(x, n1, n2, n3, n4, only_grow)
Allocate or reallocate the given array to ensure it is of the given size, preserving any data and/or ...
subroutine integer_sort(data, perm)
Sort the given data array and return the permutation defining the sort.
character(len=pmc_util_convert_string_len) function integer64_to_string(val)
Convert an integer64 to a string format.
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 pmc_stop(code)
Stops the program.
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.
subroutine ensure_real_array_4d_size(x, n1, n2, n3, n4, only_grow)
Allocate or reallocate the given array to ensure it is of the given size, preserving any data and/or ...
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).
subroutine ensure_integer_array_3d_size(x, n1, n2, n3, 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 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.
subroutine ensure_integer64_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 ...
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 ensure_complex_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 ...
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.
int double_sort_c(int n, double *data, int *perm)