other/m_common.F90
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | !> @brief Common module for the BSpline FEEC package | ||
| 2 | !> | ||
| 3 | !> This module contains common definitions, constants, and interfaces used throughout the package. | ||
| 4 | module m_common | ||
| 5 | |||
| 6 | private | ||
| 7 | public :: wp, pi, factorial, levi_civita, set_union, sort, sort_perm, uppercase, to_lower, zero_function, cumsum, prime_factors, balanced_split | ||
| 8 | public :: user_function_1d_interface, user_function_3d_interface, user_function_3d_vec_interface, user_function_3d_mat_interface | ||
| 9 | public :: cartesian_to_linear, brent | ||
| 10 | public :: init_random_seed | ||
| 11 | public :: linear_solve_3x3_transpose | ||
| 12 | public :: VERBOSITY_WARN_NEVER, VERBOSITY_WARN_ON_FAILURE, & | ||
| 13 | VERBOSITY_WARN_ALWAYS, VERBOSITY_ERROR_ON_FAILURE | ||
| 14 | |||
| 15 | !> Single precision real numbers | ||
| 16 | integer, parameter :: single = selected_real_kind(6) | ||
| 17 | |||
| 18 | !> Double precision real numbers | ||
| 19 | integer, parameter :: double = selected_real_kind(15) | ||
| 20 | |||
| 21 | !> Default value which unused if CMake is used | ||
| 22 | #ifndef CMAKE_BSPLINE_FEEC_PRECISION | ||
| 23 | #define CMAKE_BSPLINE_FEEC_PRECISION double | ||
| 24 | #endif | ||
| 25 | |||
| 26 | !> The working precision for real-valued numbers | ||
| 27 | integer, parameter :: wp = CMAKE_BSPLINE_FEEC_PRECISION | ||
| 28 | |||
| 29 | !> The value of pi (3.14159...) | ||
| 30 | real(wp), parameter :: pi = 3.1415926535897932384626433832795028841971_wp | ||
| 31 | |||
| 32 | !> Interface for user-defined functions | ||
| 33 | abstract interface | ||
| 34 | pure function user_function_1d_interface(x) result(ans) | ||
| 35 | import wp | ||
| 36 | implicit none | ||
| 37 | real(wp), intent(in) :: x | ||
| 38 | real(wp) :: ans | ||
| 39 | end function | ||
| 40 | |||
| 41 | pure function user_function_3d_interface(x, y, z) result(ans) | ||
| 42 | import wp | ||
| 43 | implicit none | ||
| 44 | real(wp), intent(in) :: x, y, z | ||
| 45 | real(wp) :: ans | ||
| 46 | end function | ||
| 47 | |||
| 48 | pure function user_function_3d_vec_interface(ind, x, y, z) result(ans) | ||
| 49 | import wp | ||
| 50 | implicit none | ||
| 51 | integer, intent(in) :: ind | ||
| 52 | real(wp), intent(in) :: x, y, z | ||
| 53 | real(wp) :: ans | ||
| 54 | end function | ||
| 55 | |||
| 56 | pure function user_function_3d_mat_interface(s1, s2, x, y, z) result(ans) | ||
| 57 | import wp | ||
| 58 | implicit none | ||
| 59 | integer, intent(in) :: s1, s2 | ||
| 60 | real(wp), intent(in) :: x, y, z | ||
| 61 | real(wp) :: ans | ||
| 62 | end function | ||
| 63 | end interface | ||
| 64 | |||
| 65 | ! TODO use enums or some other type for verbosity levels | ||
| 66 | !> Verbosity levels for warnings and errors | ||
| 67 | integer, parameter :: VERBOSITY_WARN_NEVER = 0 | ||
| 68 | integer, parameter :: VERBOSITY_WARN_ON_FAILURE = 1 | ||
| 69 | integer, parameter :: VERBOSITY_WARN_ALWAYS = 2 | ||
| 70 | integer, parameter :: VERBOSITY_ERROR_ON_FAILURE = 3 | ||
| 71 | |||
| 72 | ! Module procedure interfaces for submodules | ||
| 73 | interface | ||
| 74 | !> @brief Sort an array of integers using the quicksort algorithm | ||
| 75 | !> | ||
| 76 | !> @param[inout] array The array of integers to be sorted | ||
| 77 | !> @param[in] inverse _(optional)_ If true, sort in descending order; otherwise, ascending order (default: false) | ||
| 78 | module pure subroutine sort_int(array, inverse) | ||
| 79 | integer, intent(inout) :: array(:) | ||
| 80 | logical, intent(in), optional :: inverse | ||
| 81 | end subroutine | ||
| 82 | |||
| 83 | !> @brief Sort an array of real numbers using the quicksort algorithm | ||
| 84 | !> | ||
| 85 | !> @param[inout] array The array of real numbers to be sorted | ||
| 86 | !> @param[in] inverse _(optional)_ If true, sort in descending order; otherwise, ascending order (default: false) | ||
| 87 | !> @param[in] sort_fun _(optional)_ A function to determine the sorting order | ||
| 88 | module subroutine sort_real(array, inverse, sort_fun) | ||
| 89 | real(wp), intent(inout) :: array(:) | ||
| 90 | logical, intent(in), optional :: inverse | ||
| 91 | procedure(user_function_1d_interface), optional :: sort_fun | ||
| 92 | end subroutine | ||
| 93 | |||
| 94 | !> @brief Compute the union of two sets of integers | ||
| 95 | !> | ||
| 96 | !> @param[out] union The resulting union of the two sets | ||
| 97 | !> @param[in] set1 The first set of integers | ||
| 98 | !> @param[in] set2 The second set of integers | ||
| 99 | module subroutine set_union(union, set1, set2) | ||
| 100 | integer, allocatable, intent(out) :: union(:) | ||
| 101 | integer, intent(in) :: set1(0:), set2(0:) | ||
| 102 | end subroutine | ||
| 103 | |||
| 104 | !> @brief Compute the prime factorization of an integer | ||
| 105 | !> | ||
| 106 | !> @param[in] n The integer to factorize | ||
| 107 | !> @param[out] factors Array containing the prime factors (with repetition) | ||
| 108 | module pure subroutine prime_factors(n, factors) | ||
| 109 | integer, intent(in) :: n | ||
| 110 | integer, allocatable, intent(out) :: factors(:) | ||
| 111 | end subroutine | ||
| 112 | |||
| 113 | !> @brief Split an integer into two factors that are as close as possible | ||
| 114 | !> | ||
| 115 | !> Given an integer N, find n1 and n2 such that N = n1 * n2 and |n1 - n2| is minimized. | ||
| 116 | !> The result satisfies n1 <= n2. | ||
| 117 | !> | ||
| 118 | !> @param[in] n The integer to split | ||
| 119 | !> @param[out] n1 The smaller factor | ||
| 120 | !> @param[out] n2 The larger factor | ||
| 121 | module pure subroutine balanced_split_2(n, n1, n2) | ||
| 122 | integer, intent(in) :: n | ||
| 123 | integer, intent(out) :: n1, n2 | ||
| 124 | end subroutine | ||
| 125 | |||
| 126 | !> @brief Split an integer into three factors that are as close as possible | ||
| 127 | !> | ||
| 128 | !> Given an integer N, find n1, n2, and n3 such that N = n1 * n2 * n3 and the factors are as balanced as possible. | ||
| 129 | !> The result satisfies n1 <= n2 <= n3. | ||
| 130 | !> | ||
| 131 | !> @param[in] n The integer to split | ||
| 132 | !> @param[out] n1 The smallest factor | ||
| 133 | !> @param[out] n2 The middle factor | ||
| 134 | !> @param[out] n3 The largest factor | ||
| 135 | module pure subroutine balanced_split_3(n, n1, n2, n3) | ||
| 136 | integer, intent(in) :: n | ||
| 137 | integer, intent(out) :: n1, n2, n3 | ||
| 138 | end subroutine | ||
| 139 | |||
| 140 | |||
| 141 | !> @brief Find a root of a function using Brent's method | ||
| 142 | !> | ||
| 143 | !> @param[in] fun The function for which to find a root | ||
| 144 | !> @param[in] xa_in The lower bound of the interval | ||
| 145 | !> @param[in] xb_in The upper bound of the interval | ||
| 146 | !> @param[in] x_tol The tolerance for convergence | ||
| 147 | !> @param[in] max_iter The maximum number of iterations to perform | ||
| 148 | !> @param[in] fa_in _(optional)_ The value of the function at xa_in (if not provided, it will be computed) | ||
| 149 | !> @param[in] fb_in _(optional)_ The value of the function at xb_in (if not provided, it will be computed) | ||
| 150 | !> @param[out] success _(optional)_ A logical flag indicating whether the method converged successfully | ||
| 151 | !> | ||
| 152 | !> @return The estimated root of the function | ||
| 153 | module real(wp) function brent(fun, xa_in, xb_in, x_tol, max_iter, fa_in, fb_in, success) result(xsol) | ||
| 154 | implicit none | ||
| 155 | |||
| 156 | procedure(user_function_1d_interface) :: fun | ||
| 157 | real(wp), intent(in) :: xa_in, xb_in, x_tol | ||
| 158 | integer, intent(in) :: max_iter | ||
| 159 | real(wp), intent(in), optional :: fa_in, fb_in | ||
| 160 | logical, intent(out), optional :: success | ||
| 161 | |||
| 162 | end function brent | ||
| 163 | end interface | ||
| 164 | |||
| 165 | !> @brief Generic interface for sorting arrays | ||
| 166 | interface sort | ||
| 167 | module procedure sort_int, sort_real | ||
| 168 | end interface sort | ||
| 169 | |||
| 170 | interface | ||
| 171 | !> @brief Compute a sort permutation of an array of real numbers (descending, high to low) | ||
| 172 | !> | ||
| 173 | !> @param[in] array The array of real numbers to rank | ||
| 174 | !> @param[out] perm The permutation indices such that array(perm) is sorted descending | ||
| 175 | !> @param[in] sort_fun _(optional)_ Applied to each element before comparison | ||
| 176 | module subroutine sort_perm(array, perm, sort_fun) | ||
| 177 | real(wp), intent(in) :: array(:) | ||
| 178 | integer, intent(out) :: perm(:) | ||
| 179 | procedure(user_function_1d_interface), optional :: sort_fun | ||
| 180 | end subroutine | ||
| 181 | end interface | ||
| 182 | |||
| 183 | !> @brief Generic interface for balanced splitting of integers | ||
| 184 | interface balanced_split | ||
| 185 | module procedure balanced_split_2, balanced_split_3 | ||
| 186 | end interface balanced_split | ||
| 187 | |||
| 188 | contains | ||
| 189 | |||
| 190 | !> @brief A function that always returns zero | ||
| 191 | !> | ||
| 192 | !> @param[in] xp The x-coordinate | ||
| 193 | !> @param[in] yp The y-coordinate | ||
| 194 | !> @param[in] zp The z-coordinate | ||
| 195 | !> | ||
| 196 | !> @return Always returns 0.0 | ||
| 197 | 37888032 | pure real(wp) function zero_function(xp, yp, zp) result(val) | |
| 198 | real(wp), intent(in) :: xp, yp, zp | ||
| 199 | |||
| 200 | val = 0._wp | ||
| 201 | 37888032 | end function zero_function | |
| 202 | |||
| 203 | !> @brief Compute the factorial of a non-negative integer n | ||
| 204 | !> | ||
| 205 | !> @param[in] n The non-negative integer for which to compute the factorial | ||
| 206 | !> | ||
| 207 | !> @return The factorial of n | ||
| 208 | 16 | pure integer function factorial(n) result(ans) | |
| 209 | implicit none | ||
| 210 | |||
| 211 | integer, intent(in) :: n | ||
| 212 | |||
| 213 | integer :: i | ||
| 214 | |||
| 215 | ans = 1 | ||
| 216 |
2/2✓ Branch 3 → 4 taken 120 times.
✓ Branch 3 → 5 taken 16 times.
|
136 | do i = 2, n |
| 217 | 136 | ans = ans * i | |
| 218 | end do | ||
| 219 | 16 | end function | |
| 220 | |||
| 221 | !> @brief Compute the Levi-Civita symbol for three indices | ||
| 222 | !> | ||
| 223 | !> The Levi-Civita symbol is defined as: | ||
| 224 | !> +1 if (i, j, k) is an even permutation of (1, 2, 3) | ||
| 225 | !> -1 if (i, j, k) is an odd permutation of (1, 2, 3) | ||
| 226 | !> | ||
| 227 | !> @param[in] i The first index | ||
| 228 | !> @param[in] j The second index | ||
| 229 | !> @param[in] k The third index | ||
| 230 | !> | ||
| 231 | !> @return The value of the Levi-Civita symbol | ||
| 232 | 74223 | pure integer function levi_civita(i, j, k) | |
| 233 | !$acc routine seq | ||
| 234 | implicit none | ||
| 235 | |||
| 236 | integer, intent(in) :: i, j, k | ||
| 237 | |||
| 238 |
6/6✓ Branch 2 → 3 taken 73974 times.
✓ Branch 2 → 24 taken 249 times.
✓ Branch 3 → 4 taken 49316 times.
✓ Branch 3 → 24 taken 24658 times.
✓ Branch 4 → 5 taken 24658 times.
✓ Branch 4 → 24 taken 24658 times.
|
74223 | if (i == j .or. j == k .or. i == k) then |
| 239 | levi_civita = 0 | ||
| 240 | else if ((i == 1 .and. j == 2 .and. k == 3) .or. & | ||
| 241 |
15/18✓ Branch 5 → 6 taken 8204 times.
✓ Branch 5 → 8 taken 16454 times.
✓ Branch 6 → 7 taken 4124 times.
✓ Branch 6 → 8 taken 4080 times.
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 24 taken 4124 times.
✓ Branch 8 → 9 taken 8205 times.
✓ Branch 8 → 11 taken 12329 times.
✓ Branch 9 → 10 taken 4080 times.
✓ Branch 9 → 11 taken 4125 times.
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 24 taken 4080 times.
✓ Branch 11 → 12 taken 8249 times.
✓ Branch 11 → 14 taken 8205 times.
✓ Branch 12 → 13 taken 4125 times.
✓ Branch 12 → 14 taken 4124 times.
✗ Branch 13 → 14 not taken.
✓ Branch 13 → 24 taken 4125 times.
|
24658 | & (i == 2 .and. j == 3 .and. k == 1) .or. & |
| 242 | & (i == 3 .and. j == 1 .and. k == 2)) then | ||
| 243 | levi_civita = 1 | ||
| 244 | else if ((i == 1 .and. j == 3 .and. k == 2) .or. & | ||
| 245 |
11/18✓ Branch 14 → 15 taken 4080 times.
✓ Branch 14 → 17 taken 8249 times.
✓ Branch 15 → 16 taken 4080 times.
✗ Branch 15 → 17 not taken.
✗ Branch 16 → 17 not taken.
✓ Branch 16 → 23 taken 4080 times.
✓ Branch 17 → 18 taken 4125 times.
✓ Branch 17 → 20 taken 4124 times.
✓ Branch 18 → 19 taken 4125 times.
✗ Branch 18 → 20 not taken.
✗ Branch 19 → 20 not taken.
✓ Branch 19 → 23 taken 4125 times.
✓ Branch 20 → 21 taken 4124 times.
✗ Branch 20 → 24 not taken.
✓ Branch 21 → 22 taken 4124 times.
✗ Branch 21 → 24 not taken.
✓ Branch 22 → 23 taken 4124 times.
✗ Branch 22 → 24 not taken.
|
12329 | & (i == 2 .and. j == 1 .and. k == 3) .or. & |
| 246 | & (i == 3 .and. j == 2 .and. k == 1)) then | ||
| 247 | levi_civita = -1 | ||
| 248 | else | ||
| 249 | ! error stop "invalid indices for Levi-Civita symbol" | ||
| 250 | levi_civita = 0 | ||
| 251 | end if | ||
| 252 | |||
| 253 | 74223 | end function levi_civita | |
| 254 | |||
| 255 | !> @brief Solve the 3x3 linear system A^T x = b using a provided determinant | ||
| 256 | !> | ||
| 257 | !> @param[in] A The 3x3 matrix | ||
| 258 | !> @param[in] detA The determinant of A | ||
| 259 | !> @param[in] b The right-hand-side vector | ||
| 260 | !> @param[out] x The solution vector | ||
| 261 | 1002 | pure subroutine linear_solve_3x3_transpose(A, detA, b, x) | |
| 262 | !$acc routine seq | ||
| 263 | implicit none | ||
| 264 | |||
| 265 | real(wp), intent(in) :: A(3, 3) | ||
| 266 | real(wp), intent(in) :: detA | ||
| 267 | real(wp), intent(in) :: b(3) | ||
| 268 | real(wp), intent(out) :: x(3) | ||
| 269 | |||
| 270 | real(wp) :: c11, c12, c13 | ||
| 271 | real(wp) :: c21, c22, c23 | ||
| 272 | real(wp) :: c31, c32, c33 | ||
| 273 | |||
| 274 |
2/2✓ Branch 2 → 3 taken 1 time.
✓ Branch 2 → 4 taken 1001 times.
|
1002 | if (abs(detA) == 0._wp) then |
| 275 | 1 | x = 0._wp | |
| 276 | 1 | return | |
| 277 | end if | ||
| 278 | |||
| 279 | ! Cofactors C_ij of A; (A^T)^(-1) = C / det(A) | ||
| 280 | 1001 | c11 = A(2, 2) * A(3, 3) - A(2, 3) * A(3, 2) | |
| 281 | 1001 | c12 = A(2, 3) * A(3, 1) - A(2, 1) * A(3, 3) | |
| 282 | 1001 | c13 = A(2, 1) * A(3, 2) - A(2, 2) * A(3, 1) | |
| 283 | |||
| 284 | 1001 | c21 = A(1, 3) * A(3, 2) - A(1, 2) * A(3, 3) | |
| 285 | 1001 | c22 = A(1, 1) * A(3, 3) - A(1, 3) * A(3, 1) | |
| 286 | 1001 | c23 = A(1, 2) * A(3, 1) - A(1, 1) * A(3, 2) | |
| 287 | |||
| 288 | 1001 | c31 = A(1, 2) * A(2, 3) - A(1, 3) * A(2, 2) | |
| 289 | 1001 | c32 = A(1, 3) * A(2, 1) - A(1, 1) * A(2, 3) | |
| 290 | 1001 | c33 = A(1, 1) * A(2, 2) - A(1, 2) * A(2, 1) | |
| 291 | |||
| 292 | 1001 | x(1) = (c11 * b(1) + c12 * b(2) + c13 * b(3)) / detA | |
| 293 | 1001 | x(2) = (c21 * b(1) + c22 * b(2) + c23 * b(3)) / detA | |
| 294 | 1001 | x(3) = (c31 * b(1) + c32 * b(2) + c33 * b(3)) / detA | |
| 295 | end subroutine linear_solve_3x3_transpose | ||
| 296 | |||
| 297 | !> @brief Convert a string to uppercase | ||
| 298 | !> | ||
| 299 | !> @param[in] in The input string to be converted | ||
| 300 | !> | ||
| 301 | !> @return The uppercase version of the input string | ||
| 302 | ✗ | function uppercase(in) result(out) | |
| 303 | implicit none | ||
| 304 | |||
| 305 | character(len=*), intent(in) :: in | ||
| 306 | character(len=len(in)) :: out | ||
| 307 | integer :: i, j | ||
| 308 | |||
| 309 | ✗ | do i = 1, len(in) | |
| 310 | ✗ | j = iachar(in(i:i)) | |
| 311 | ✗ | if (j >= iachar("a") .and. j <= iachar("z")) then | |
| 312 | ✗ | out(i:i) = achar(iachar(in(i:i)) - 32) | |
| 313 | else | ||
| 314 | ✗ | out(i:i) = in(i:i) | |
| 315 | end if | ||
| 316 | end do | ||
| 317 | |||
| 318 | ✗ | end function uppercase | |
| 319 | |||
| 320 | !> @brief Convert a string to lowercase | ||
| 321 | !> | ||
| 322 | !> @param[in] in The input string to be converted | ||
| 323 | !> | ||
| 324 | !> @return The lowercase version of the input string | ||
| 325 | 28 | pure function to_lower(in) result(out) | |
| 326 | implicit none | ||
| 327 | |||
| 328 | character(len=*), intent(in) :: in | ||
| 329 | character(len=len(in)) :: out | ||
| 330 | integer :: i, j | ||
| 331 | |||
| 332 |
2/2✓ Branch 3 → 4 taken 132 times.
✓ Branch 3 → 8 taken 28 times.
|
160 | do i = 1, len(in) |
| 333 | 132 | j = iachar(in(i:i)) | |
| 334 |
1/2✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 132 times.
|
160 | if (j >= iachar('A') .and. j <= iachar('Z')) then |
| 335 | ✗ | out(i:i) = achar(j + 32) | |
| 336 | else | ||
| 337 | 132 | out(i:i) = in(i:i) | |
| 338 | end if | ||
| 339 | end do | ||
| 340 | 28 | end function to_lower | |
| 341 | |||
| 342 | !> @brief Compute the cumulative sum of an array | ||
| 343 | !> | ||
| 344 | !> @param[out] out The output array containing the cumulative sums | ||
| 345 | !> @param[in] in The input array | ||
| 346 |
1/2✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 249 times.
|
249 | subroutine cumsum(out, in) |
| 347 | implicit none | ||
| 348 | |||
| 349 | real(wp), intent(in) :: in(:) | ||
| 350 | real(wp), intent(out) :: out(size(in) + 1) | ||
| 351 | |||
| 352 | integer :: i | ||
| 353 | |||
| 354 | 249 | out(1) = 0 | |
| 355 |
2/2✓ Branch 5 → 6 taken 5435 times.
✓ Branch 5 → 7 taken 249 times.
|
5684 | do i = 1, size(in) |
| 356 | 5684 | out(i + 1) = out(i) + in(i) | |
| 357 | end do | ||
| 358 | 249 | end subroutine cumsum | |
| 359 | |||
| 360 | !> @brief Convert multi-dimensional Cartesian indices to a linear index (0-based) | ||
| 361 | !> | ||
| 362 | !> @param[in] indices The array of Cartesian indices | ||
| 363 | !> @param[in] dims The dimensions of the multi-dimensional array | ||
| 364 | !> | ||
| 365 | !> @return The corresponding linear index | ||
| 366 |
2/4✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 2134 times.
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 2134 times.
|
2134 | pure integer function cartesian_to_linear(indices, dims) result(linear_index) |
| 367 | implicit none | ||
| 368 | |||
| 369 | integer, intent(in) :: indices(:) | ||
| 370 | integer, intent(in) :: dims(:) | ||
| 371 | integer :: i, stride | ||
| 372 | |||
| 373 | linear_index = 0 | ||
| 374 | stride = 1 | ||
| 375 |
2/2✓ Branch 7 → 8 taken 3201 times.
✓ Branch 7 → 9 taken 2134 times.
|
5335 | do i = size(dims), 1, -1 |
| 376 | 3201 | linear_index = linear_index + indices(i) * stride | |
| 377 | 5335 | stride = stride * dims(i) | |
| 378 | end do | ||
| 379 | |||
| 380 | 2134 | end function cartesian_to_linear | |
| 381 | |||
| 382 | !> @brief Initialize the random seed with a fixed value for reproducibility | ||
| 383 | !> | ||
| 384 | !> @param[in] random_seed_value An optional integer | ||
| 385 | !> @note This functionality is normally available by means of the random_init intrinsic, but NVHPC does not support it on a single | ||
| 386 | !> image | ||
| 387 | 22 | subroutine init_random_seed(random_seed_value) | |
| 388 | implicit none | ||
| 389 | integer, optional, intent(in) :: random_seed_value | ||
| 390 | integer :: seed_size | ||
| 391 | 22 | integer, allocatable :: seed(:) | |
| 392 | |||
| 393 | 22 | call random_seed(size=seed_size) | |
| 394 |
7/14✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 22 times.
✓ Branch 5 → 4 taken 22 times.
✗ Branch 5 → 6 not taken.
✓ Branch 6 → 7 taken 22 times.
✗ Branch 6 → 8 not taken.
✓ Branch 8 → 9 taken 22 times.
✗ Branch 8 → 10 not taken.
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 12 taken 22 times.
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 14 taken 22 times.
✗ Branch 14 → 15 not taken.
✓ Branch 14 → 16 taken 22 times.
|
66 | allocate (seed(seed_size)) |
| 395 |
1/2✓ Branch 16 → 17 taken 22 times.
✗ Branch 16 → 18 not taken.
|
22 | if (present(random_seed_value)) then |
| 396 | ✗ | seed = random_seed_value | |
| 397 | else | ||
| 398 |
2/2✓ Branch 21 → 22 taken 176 times.
✓ Branch 21 → 23 taken 22 times.
|
198 | seed = 42 ! default seed value |
| 399 | end if | ||
| 400 | 22 | call random_seed(put=seed) | |
| 401 |
1/2✗ Branch 24 → 25 not taken.
✓ Branch 24 → 26 taken 22 times.
|
22 | deallocate (seed) |
| 402 | 22 | end subroutine init_random_seed | |
| 403 | |||
| 404 | end module m_common | ||
| 405 |