Uses a method for getting a nice seed for the PRNG taken from gfortran documentation
function get_random_seed() result(seed)
use, intrinsic :: iso_fortran_env, only: int64
implicit none
integer :: seed
integer(int64) :: time
integer :: time_values(8)
! Convert from milliseconds to larger units
integer, parameter :: second = 1000
integer, parameter :: minute = 60*second
integer, parameter :: hour = 60*minute
integer(int64), parameter :: day = 24*hour
integer(int64), parameter :: month = 31*day
integer(int64), parameter :: year = 365_int64*day
integer, parameter :: un = 6544
integer :: istat
! First try if the OS provides a random number generator
open(unit=un, file="/dev/urandom", access="stream", &
form="unformatted", action="read", status="old", iostat=istat)
if (istat == 0) then
read(un) seed
close(un)
else
! Fallback to using current system time
call system_clock(time)
if (time == 0) then
! It's plausible the system_clock isn't POSIX/epoch time so
! let's try a different method to get the time
call date_and_time(values=time_values)
time = (time_values(1) - 1970)*year &
+ time_values(2)*month &
+ time_values(3)*day &
+ time_values(5)*hour &
+ time_values(6)*minute &
+ time_values(7)*second &
+ time_values(8)
end if
! Ideally here we'd also XOR the PID, which would help when
! launching multiple processes at the same time. Note that if
! you need a consistent UUID across MPI ranks, you'll need
! another function to generate one UUID and broadcast that
! One step of linear congruential generator
time = mod(time, 4294967296_int64)
time = mod(time*279470273_int64, 4294967291_int64)
seed = int(mod(time, int(huge(0), int64)), kind(seed))
end if
end function get_random_seed