FV3 Bundle
ioda/src/ioda/random_vectors_mod.f90
Go to the documentation of this file.
1 ! (C) Copyright 2009-2016 ECMWF.
2 !
3 ! This software is licensed under the terms of the Apache Licence Version 2.0
4 ! which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
5 ! In applying this licence, ECMWF does not waive the privileges and immunities
6 ! granted to it by virtue of its status as an intergovernmental organisation nor
7 ! does it submit to any jurisdiction.
8 
9 !> Fortran module for generating random vectors
10 module random_vectors_mod
11 
12 use, intrinsic :: iso_c_binding
13 use kinds
14 
15 implicit none
16 private
17 public :: random_vector
18 
19 ! ------------------------------------------------------------------------------
20 !> Fortran generic for generating random 1d, 2d and 3d arrays
21 interface random_vector
23 end interface
24 ! ------------------------------------------------------------------------------
25 
26 !-------------------------------------------------------------------------------
27 interface
28 subroutine random_c(kk, pp) bind(C,name='random_f')
29  use, intrinsic :: iso_c_binding
30  implicit none
31  integer(c_int), intent(in) :: kk
32  real(kind=c_double), intent(out) :: pp(*)
33 ! The line below:
34 ! real(kind=c_double), intent(out) :: pp(:)
35 ! would not work because then fortran passes an array descriptor
36 ! (somebody could pass a non-contiguous array using array syntax)
37 ! instead of the address of the first element of the array. YT
38 end subroutine random_c
39 end interface
40 !-------------------------------------------------------------------------------
41 
42 ! ------------------------------------------------------------------------------
43 contains
44 ! ------------------------------------------------------------------------------
45 
46 !> Generate a random 1d array of reals
47 subroutine random_vector_1(xx)
48 implicit none
49 real(kind=kind_real), intent(inout) :: xx(:)
50 real(kind=c_double) :: zz(size(xx))
51 integer(c_int) :: nn
52 
53 nn = size(xx)
54 if (size(zz) > 0) call random_c(nn, zz(1))
55 xx(:)=zz(:)
56 
57 end subroutine random_vector_1
58 
59 ! ------------------------------------------------------------------------------
60 
61 !> Generate a random 2d array of reals
62 subroutine random_vector_2(xx)
63 implicit none
64 real(kind=kind_real), intent(inout) :: xx(:,:)
65 real(kind=c_double) :: zz(size(xx))
66 integer(c_int) :: nn
67 
68 nn = size(xx)
69 if (size(zz) > 0) call random_c(nn, zz(1))
70 xx = reshape(zz, shape(xx))
71 
72 end subroutine random_vector_2
73 
74 ! ------------------------------------------------------------------------------
75 
76 !> Generate a random 3d array of reals
77 subroutine random_vector_3(xx)
78 implicit none
79 real(kind=kind_real), intent(inout) :: xx(:,:,:)
80 real(kind=c_double) :: zz(size(xx))
81 integer(c_int) :: nn
82 
83 nn = size(xx)
84 if (size(zz) > 0) call random_c(nn, zz(1))
85 xx = reshape(zz, shape(xx))
86 
87 end subroutine random_vector_3
88 
89 ! ------------------------------------------------------------------------------
90 
91 end module random_vectors_mod
Fortran generic for generating random 1d, 2d and 3d arrays.
subroutine random_vector_3(xx)
Generate a random 3d array of reals.
subroutine random_vector_2(xx)
Generate a random 2d array of reals.
subroutine random_vector_1(xx)
Generate a random 1d array of reals.
Fortran module for generating random vectors.