SCALE-RM
scale_random.F90
Go to the documentation of this file.
1 !-------------------------------------------------------------------------------
13 #include "scalelib.h"
15  !-----------------------------------------------------------------------------
16  !
17  !++ used modules
18  !
19  use scale_precision
20  use scale_io
21  !-----------------------------------------------------------------------------
22  implicit none
23  private
24  !-----------------------------------------------------------------------------
25  !
26  !++ Public procedure
27  !
28  public :: random_setup
29  public :: random_uniform
30  public :: random_normal
31 
32  !-----------------------------------------------------------------------------
33  !
34  !++ Public parameters & variables
35  !
36  !-----------------------------------------------------------------------------
37  !
38  !++ Private procedure
39  !
40  private :: random_reset
41 
42  !-----------------------------------------------------------------------------
43  !
44  !++ Private parameters & variables
45  !
46  logical, private :: random_fix = .false.
47 
48  integer, private, allocatable :: random_seedvar(:)
49 
50  !-----------------------------------------------------------------------------
51 contains
52  !-----------------------------------------------------------------------------
54  subroutine random_setup
55  use scale_prc, only: &
56  prc_abort
57  implicit none
58 
59  namelist / param_random / &
60  random_fix
61 
62  integer :: nseeds, ierr
63  !---------------------------------------------------------------------------
64 
65  log_newline
66  log_info("RANDOM_setup",*) 'Setup'
67 
68  !--- read namelist
69  rewind(io_fid_conf)
70  read(io_fid_conf,nml=param_random,iostat=ierr)
71  if( ierr < 0 ) then !--- missing
72  log_info("RANDOM_setup",*) 'Not found namelist. Default used.'
73  elseif( ierr > 0 ) then !--- fatal error
74  log_error("RANDOM_setup",*) 'Not appropriate names in namelist PARAM_RANDOM. Check!'
75  call prc_abort
76  endif
77  log_nml(param_random)
78 
79  call random_seed
80  call random_seed(size=nseeds)
81 
82  allocate( random_seedvar(nseeds))
83 
84  log_newline
85  log_info("RANDOM_setup",*) 'Array size for random seed:', nseeds
86  if ( random_fix ) then
87  log_info("RANDOM_setup",*) 'random seed is fixed.'
88  endif
89 
90  call random_reset
91 
92  return
93  end subroutine random_setup
94 
95  !-----------------------------------------------------------------------------
97  subroutine random_reset
98  use scale_prc, only: &
100  implicit none
101 
102  integer :: time1(8) ! date and time information
103  real(RP) :: time2 ! CPU time
104  !---------------------------------------------------------------------------
105 
106  if ( random_fix ) then
107  ! birthday of SCALE
108  time1(1) = 2011 ! The year
109  time1(2) = 12 ! The month
110  time1(3) = 5 ! The day of the month
111  time1(4) = 9 ! Time difference with UTC in minutes
112  time1(5) = 10 ! The hour of the day
113  time1(6) = 20 ! The minutes of the hour
114  time1(7) = 41 ! The seconds of the minute
115  time1(8) = 0 ! The milliseconds of the second
116  time2 = 0.0_rp
117  else
118  call date_and_time(values=time1)
119  call cpu_time(time2)
120  endif
121 
122  random_seedvar(:) = prc_myrank &
123  + ( time1(1) - 1970 ) * 32140800 &
124  + time1(2) * 2678400 &
125  + time1(3) * 86400 &
126  + time1(5) * 60 &
127  + time1(6) * 3600 &
128  + time1(7) * 60 &
129  + time1(8) &
130  + int(time2*1.e6_rp)
131 
132  call random_seed(put=random_seedvar)
133 
134  return
135  end subroutine random_reset
136 
137  !-----------------------------------------------------------------------------
139  subroutine random_uniform( var )
140  implicit none
141 
142  real(RP), intent(out) :: var(:,:,:)
143  !---------------------------------------------------------------------------
144 
145  call random_number(var)
146 
147  return
148  end subroutine random_uniform
149 
150  !-----------------------------------------------------------------------------
152  subroutine random_normal( var )
153  implicit none
154  real(RP), intent(out) :: var(:,:,:)
155  integer :: n
156 
157  n = size(var)
158  call get_normal( n, var(:,:,:) )
159 
160  return
161  end subroutine random_normal
162 
163  ! private
164 
165  subroutine get_normal( n, var )
166  use scale_const, only: &
167  pi => const_pi
168  implicit none
169  integer, intent(in) :: n
170  real(RP), intent(out) :: var(n)
171 
172  real(RP) :: rnd(n+1)
173  real(RP) :: fact
174  real(RP) :: theta
175  integer :: i
176  !---------------------------------------------------------------------------
177 
178  call random_number(rnd)
179 
180  !$omp parallel do &
181  !$omp private(fact,theta)
182  do i = 1, n/2
183  fact = sqrt(-2.0_rp * log( rnd(i*2-1) ) )
184  theta = 2.0_rp * pi * rnd(i*2)
185  var(i*2-1) = fact * cos(theta)
186  var(i*2 ) = fact * sin(theta)
187  end do
188  if ( mod(n,2) == 1 ) then
189  fact = sqrt(-2.0_rp * log( rnd(n) ) )
190  theta = 2.0_rp * pi * rnd(n+1)
191  var(n) = fact * cos(theta)
192  end if
193 
194  return
195  end subroutine get_normal
196 
197 end module scale_random
subroutine, public random_setup
Setup.
integer, public io_fid_conf
Config file ID.
Definition: scale_io.F90:55
module PROCESS
Definition: scale_prc.F90:11
integer, public prc_myrank
process num in local communicator
Definition: scale_prc.F90:89
subroutine, public prc_abort
Abort Process.
Definition: scale_prc.F90:338
module CONSTANT
Definition: scale_const.F90:11
subroutine, public random_normal(var)
Get normal random number.
module PRECISION
real(rp), public const_pi
pi
Definition: scale_const.F90:31
subroutine, public random_uniform(var)
Get uniform random number.
module STDIO
Definition: scale_io.F90:10
module RANDOM