3 use da_gen_be
, only
: da_eof_decomposition
7 integer, parameter :: ni
= 1000
8 integer, parameter :: stdout
= 6
9 character (len
=3) :: cnk
! vertical level
10 real*8, parameter :: rscale
= 0.1
11 real*8, parameter :: var_threshold
= 0.99
13 integer :: i
, k
, k1
, m
,nk
,nk2
17 real*8 :: nk_inv
, nk3_inv
18 real*8 :: kscale
, kscale_invsq
21 real*8 :: totvar
, totvar_inv
, cumvar
22 real*8,allocatable
:: rho(:,:)
23 real*8,allocatable
:: e(:,:)
24 real,allocatable
:: cov(:,:)
25 real*8,allocatable
:: eval(:)
26 real*8,allocatable
:: evec(:,:)
27 real*8,allocatable
:: v(:)
28 real*8,allocatable
:: x(:)
34 write(stdout
,'(a,i6)') ' vertical level = ', nk2
36 allocate(rho(1:nk
,1:nk
))
37 allocate(e(1:ni
,1:nk
))
38 allocate(cov(1:nk
,1:nk
))
40 allocate(evec(1:nk
,1:nk
))
43 ni1_inv
= 1.0 / real (ni
- 1)
44 nk_inv
= 1.0 / real (nk
)
45 nk3_inv
= 1.0 / real (nk
-3)
47 ! Specify probability densities:
49 kscale
= 10.0 * real(k
) * nk_inv
! Very simple parametrization of vertical variation of localization scale.
50 ! kscale = 3.0 + 7.0 * real(k-3) * nk3_inv ! Very simple parametrization of vertical variation of localization scale.
52 kscale_invsq
= 1.0 / ( kscale
* kscale
)
55 rho(k
,k1
) = exp ( -real(kdist
* kdist
) * kscale_invsq
)
61 ! Create random variables:
65 ! call da_gauss_noise( r )
67 ! e(i,k1) = rho(k,k1) + r
68 ! write(17,'(i5,f15.5)')k1, e(i,k1)
74 ! Calculate covariance matrix:
78 ! cov(k,k1) = ni1_inv * sum( e(1:ni,k) * e(1:ni,k1) )
79 ! cov(k,k1) = rho(k,k1)
80 ! cov(k1,k) = cov(k,k1)
84 !------------------------------------------------------------------------------------------------
85 ! Calculate eigenvectors/values:
86 !------------------------------------------------------------------------------------------------
88 call da_eof_decomposition( nk
, cov
, evec
, eval
)
90 ! Eliminate negative eigenvalues:
91 totvar
= sum(eval(1:nk
))
93 if ( eval(k
) < 0.0 ) eval(k
) = 0.0
95 totvar_inv
= 1.0 / sum(eval(1:nk
))
96 eval(:) = eval(:) * totvar
* totvar_inv
! Preserve total variance before -ve values removed.
98 ! Calculate truncation:
100 totvar_inv
= 1.0 / sum(eval(1:nk
))
102 cumvar
= sum(eval(1:k
)) * totvar_inv
103 if ( nm
== 0 .and
. cumvar
>= var_threshold
) nm
= k
106 write(stdout
,'(a,f15.5,i6)')' Threshold, truncation = ', var_threshold
, nm
108 open(10, file
= 'be.vertloc.dat', status
= 'unknown', form
='unformatted')
110 eval(:) = sqrt(eval(:)) ! Write out L^{1/2} for use in WRF-Var
112 write(10)evec(1:nk
,1:nk
)
116 !------------------------------------------------------------------------------------------------
117 ! Calculate B = E L E^T = U U^T [..00100..]
118 !------------------------------------------------------------------------------------------------
126 v(m
) = eval(m
) * sum(evec(1:nk
,m
) * x(1:nk
))
131 x(k
) = sum(evec(k
,1:nm
) * eval(1:nm
) * v(1:nm
))
132 ! write(22,'(i5,2f15.5)')k, rho(ktarget,k), x(k)
143 end program gen_be_vertloc