FMS  2024.03
Flexible Modeling System
random_numbers.F90
1 !***********************************************************************
2 !* GNU Lesser General Public License
3 !*
4 !* This file is part of the GFDL Flexible Modeling System (FMS).
5 !*
6 !* FMS is free software: you can redistribute it and/or modify it under
7 !* the terms of the GNU Lesser General Public License as published by
8 !* the Free Software Foundation, either version 3 of the License, or (at
9 !* your option) any later version.
10 !*
11 !* FMS is distributed in the hope that it will be useful, but WITHOUT
12 !* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 !* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 !* for more details.
15 !*
16 !* You should have received a copy of the GNU Lesser General Public
17 !* License along with FMS. If not, see <http://www.gnu.org/licenses/>.
18 !***********************************************************************
19 
20 !> @defgroup random_numbers_mod random_numbers_mod
21 !> @ingroup random_numbers
22 !> @brief Generic module to wrap random number generators.
23 !!
24 !> The module defines a type that identifies the particular stream of random
25 !! numbers, and has procedures for initializing it and getting real numbers
26 !! in the range 0 to 1.
27 !! This version uses the Mersenne Twister to generate random numbers on [0, 1].
28 
29 module random_numbers_mod
30 
31  use mersennetwister_mod, only: randomnumbersequence, & ! The random number engine.
32  new_randomnumbersequence, getrandomreal
33  use time_manager_mod, only: time_type, get_date
34  use platform_mod, only: r4_kind, r8_kind
35 
36  implicit none
37  private
38 
39  !> @brief Type to hold a stream of randomly generated numbers
40  !> @ingroup random_numbers_mod
42  type(randomNumberSequence) :: theNumbers
43  end type randomnumberstream
44 
45  !> Returns scalar, 1 or 2 D random real numbers
46  !!
47  !> @param stream @ref randomNumberStream to generate from
48  !> @param[out] number output number(s)
49  !> @ingroup random_numbers_mod
50  interface getrandomnumbers
51  module procedure :: get_random_number_0d_r4, get_random_number_0d_r8
52  module procedure :: get_random_number_1d_r4, get_random_number_1d_r8
53  module procedure :: get_random_number_2d_r4, get_random_number_2d_r8
54  end interface getrandomnumbers
55 
56  !> Initializes stream for generating random numbers.
57  !> @ingroup random_numbers_mod
59  module procedure initializerandomnumberstream_s, initializerandomnumberstream_v
60  end interface initializerandomnumberstream
61 
62  public :: randomnumberstream, &
65 
66 !> @addtogroup random_numbers_mod
67 !> @{
68 
69 contains
70 
71  !> Initialization
72  function initializerandomnumberstream_s(seed) result(new)
73  integer, intent( in) :: seed
74  type(randomnumberstream) :: new
75 
76  new%theNumbers = new_randomnumbersequence(seed)
77 
79 
80  function initializerandomnumberstream_v(seed) result(new)
81  integer, dimension(:), intent( in) :: seed
82  type(randomnumberstream) :: new
83 
84  new%theNumbers = new_randomnumbersequence(seed)
85  end function initializerandomnumberstream_v
86 
87  !> Constructs a unique seed from grid cell index and model date/time
88  !! The perm is supplied we generate a different seed by
89  !! circularly shifting the bits of the seed - this is useful
90  !! if we want to create more than one seed for a given
91  !! column and model date/time.
92  !! Note that abs(perm) must be <= the number of bits used
93  !! to represent the default integer (likely 32)
94  function constructseed(i, j, time, perm) result(seed)
95  integer, intent( in) :: i, j
96  type(time_type), intent( in) :: time
97  integer, optional, intent( in) :: perm
98  integer, dimension(8) :: seed
99 
100  ! Local variables
101  integer :: year, month, day, hour, minute, second
102 
103 
104  call get_date(time, year, month, day, hour, minute, second)
105  seed = (/ i, j, year, month, day, hour, minute, second /)
106  if(present(perm)) seed = ishftc(seed, perm)
107  end function constructseed
108 
109 #include "random_numbers_r4.fh"
110 #include "random_numbers_r8.fh"
111 
112 end module random_numbers_mod
113 
114 !> @}
115 ! close documentation grouping
The type containing the state variable.
integer function, dimension(8), public constructseed(i, j, time, perm)
Constructs a unique seed from grid cell index and model date/time The perm is supplied we generate a ...
type(randomnumberstream) function initializerandomnumberstream_s(seed)
Initialization.
Returns scalar, 1 or 2 D random real numbers.
Initializes stream for generating random numbers.
Type to hold a stream of randomly generated numbers.
subroutine, public get_date(time, year, month, day, hour, minute, second, tick, err_msg)
Gets the date for different calendar types. Given a time_interval, returns the corresponding date und...
Type to represent amounts of time. Implemented as seconds and days to allow for larger intervals.