SABER
tools_wrfda.F90
Go to the documentation of this file.
1 # 1 "/Users/miesch/JEDI/code/working_copy/internal/mpas-bundle/saber/src/saber/external/tools_wrfda.fypp"
2 # 1 "/Users/miesch/JEDI/code/working_copy/internal/mpas-bundle/saber/src/saber/external/../instrumentation.fypp" 1
3 # 1 "/Users/miesch/JEDI/code/working_copy/internal/mpas-bundle/saber/src/saber/external/../subr_list.fypp" 1
4 !----------------------------------------------------------------------
5 ! Header: subr_list
6 !> Subroutines/functions list
7 ! Author: Benjamin Menetrier
8 ! Licensing: this code is distributed under the CeCILL-C license
9 ! Copyright 2015-... UCAR, CERFACS, METEO-FRANCE and IRIT
10 !----------------------------------------------------------------------
11 
12 # 926 "/Users/miesch/JEDI/code/working_copy/internal/mpas-bundle/saber/src/saber/external/../subr_list.fypp"
13 # 2 "/Users/miesch/JEDI/code/working_copy/internal/mpas-bundle/saber/src/saber/external/../instrumentation.fypp" 2
14 !----------------------------------------------------------------------
15 ! Header: instrumentation
16 !> Instrumentation functions
17 ! Author: Benjamin Menetrier
18 ! Licensing: this code is distributed under the CeCILL-C license
19 ! Copyright 2015-... UCAR, CERFACS, METEO-FRANCE and IRIT
20 !----------------------------------------------------------------------
21 
22 # 112 "/Users/miesch/JEDI/code/working_copy/internal/mpas-bundle/saber/src/saber/external/../instrumentation.fypp"
23 # 2 "/Users/miesch/JEDI/code/working_copy/internal/mpas-bundle/saber/src/saber/external/tools_wrfda.fypp" 2
24 !----------------------------------------------------------------------
25 ! Module: tools_wrfda
26 !> WRFDA functions
27 ! Source: https://github.com/wrf-model/WRFDA
28 ! Author: This routine is from WRFDA
29 ! Original licensing: none
30 ! Modified by Benjamin Menetrier for BUMP
31 ! Licensing: this code is distributed under the CeCILL-C license
32 ! Copyright 2015-... UCAR, CERFACS, METEO-FRANCE and IRIT
33 !----------------------------------------------------------------------
35 
36 use tools_const, only: zero,one
37 use tools_kinds, only: kind_real
38 use type_mpl, only: mpl_type
39 
40 
41 implicit none
42 
43 interface pseudoinv
44  module procedure wrfda_pseudoinv
45 end interface
47  module procedure wrfda_da_eof_decomposition
48 end interface
50  module procedure wrfda_da_eof_dominant_mode
51 end interface
53  module procedure wrfda_da_eof_recomposition
54 end interface
55 
56 private
58 
59 contains
60 
61 !----------------------------------------------------------------------
62 ! Subroutine: wrfda_pseudoinv
63 !> Compute the pseudo-inverse of a covariance matrix
64 !----------------------------------------------------------------------
65 subroutine wrfda_pseudoinv(mpl,n,a,ainv,mmax,var_th)
66 
67 implicit none
68 
69 ! Passed variables
70 type(mpl_type),intent(inout) :: mpl !< MPI data
71 integer,intent(in) :: n !< Matrix size
72 real(kind_real),intent(in) :: a(n,n) !< Matrix
73 real(kind_real),intent(out) :: ainv(n,n) !< Matrix inverse
74 integer,intent(in),optional :: mmax !< Dominant mode
75 real(kind_real),intent(in),optional :: var_th !< Variance threshold
76 
77 ! Local variables
78 integer :: i,lmmax
79 real(kind_real) :: evec(n,n),eval(n),evalinv(n)
80 
81 ! Set name
82 
83 
84 ! Probe in
85 
86 
87 ! EOF decomposition
88 call da_eof_decomposition(mpl,n,a,evec,eval)
89 
90 ! Select dominant mode
91 if (present(mmax)) then
92  ! Input argument
93  lmmax = mmax
94 else
95  if (present(var_th)) then
96  ! Based on variance threshold
97  lmmax = da_eof_dominant_mode(n,eval,var_th)
98  else
99  call mpl%abort('wrfda_pseudoinv','either dominant mode or variance threshold should be specified')
100  end if
101 end if
102 if (lmmax>n) call mpl%abort('wrfda_pseudoinv','dominant mode should smaller than the matrix rank')
103 
104 ! Inverse eigenvalues
105 do i=1,n
106  if (abs(eval(i))>zero) then
107  evalinv(i) = one/eval(i)
108  else
109  evalinv(i) = zero
110  end if
111 end do
112 
113 ! Rebuild inverse
114 call da_eof_recomposition(n,lmmax,evec,evalinv,ainv)
115 
116 ! Probe out
117 
118 
119 end subroutine wrfda_pseudoinv
120 
121 !----------------------------------------------------------------------
122 ! Subroutine: wrfda_da_eof_decomposition
123 !> Compute eigenvectors and eigenvalues of a covariance matrix
124 !----------------------------------------------------------------------
125 subroutine wrfda_da_eof_decomposition(mpl,n,a,evec,eval)
126 
127 implicit none
128 
129 ! Passed variables
130 type(mpl_type),intent(inout) :: mpl !< MPI data
131 integer, intent(in) :: n !< Matrix size
132 real(kind_real),intent(in) :: a(n,n) !< Matrix
133 real(kind_real),intent(out) :: evec(n,n) !< Eigenvectors
134 real(kind_real),intent(out) :: eval(n) !< Eigenvalues
135 
136 ! Local variables
137 integer :: work,ierr,i
138 real(kind_real) :: work_array(3*n-1),evec_copy(n,n),eval_copy(n)
139 
140 ! Set name
141 
142 
143 ! Probe in
144 
145 
146 ! Initialization
147 work = 3*n-1
148 evec_copy = a
149 eval_copy = zero
150 
151 ! Perform global eigenvalue decomposition using LAPACK software
152 call dsyev('V','U',n,evec_copy,n,eval_copy,work_array,work,ierr)
153 if (ierr/=0) call mpl%abort('wrfda_da_eof_decomposition','dsyev failed')
154 
155 ! Swap order of eigenvalues, vectors so 1st is one with most variance
156 do i=1,n
157  eval(i) = eval_copy(n+1-i)
158  evec(:,i) = evec_copy(:,n+1-i)
159 end do
160 
161 ! Probe out
162 
163 
164 end subroutine wrfda_da_eof_decomposition
165 
166 !----------------------------------------------------------------------
167 ! Function: wrfda_da_eof_dominant_mode
168 !> Compute dominant mode given a variance threshold
169 !----------------------------------------------------------------------
170 function wrfda_da_eof_dominant_mode(n,eval,var_th) result(lmmax)
171 
172 implicit none
173 
174 ! Passed variables
175 integer, intent(in) :: n !< Number of eigenvalues
176 real(kind_real),intent(in) :: eval(n) !< Eigenvalues
177 real(kind_real),intent(in) :: var_th !< Variance threshold
178 
179 ! Returned variable
180 integer :: lmmax
181 
182 ! Local variables
183 integer :: i
184 real(kind_real) :: total_variance,cumul_variance
185 
186 ! Set name
187 
188 
189 ! Probe in
190 
191 
192 ! Total variance
193 total_variance = sum(eval)
194 
195 ! Cumulated variance
196 cumul_variance = zero
197 lmmax = n
198 do i=1,n
199  cumul_variance = cumul_variance+eval(i)/total_variance
200  if (cumul_variance>one-var_th) then
201  lmmax = i-1
202  exit
203  end if
204 end do
205 
206 ! Probe out
207 
208 
209 end function wrfda_da_eof_dominant_mode
210 
211 !----------------------------------------------------------------------
212 ! Subroutine: wrfda_da_eof_recomposition
213 !> Recompute covariance matrix from a subset of eigenvectors and eigenvalues
214 !----------------------------------------------------------------------
215 subroutine wrfda_da_eof_recomposition(n,mmax,evec,eval,a)
216 
217 implicit none
218 
219 ! Passed variables
220 integer, intent(in) :: n !< Matrix size
221 integer, intent(in) :: mmax !< Dominant mode
222 real(kind_real),intent(in) :: evec(n,n) !< Eigenvectors of a
223 real(kind_real),intent(in) :: eval(n) !< Eigenvalues of a
224 real(kind_real),intent(out) :: a(n,n) !< Matrix
225 
226 ! Local variables
227 integer :: i,j
228 real(kind_real) :: tmp(n,n)
229 
230 ! Set name
231 
232 
233 ! Probe in
234 
235 
236 ! First matrix product
237 tmp = zero
238 do i=1,n
239  do j=1,mmax
240  tmp(j,i) = evec(i,j)*eval(j)
241  end do
242 end do
243 
244 ! Second matrix product
245 do i=1,n
246  do j=1,i
247  a(i,j) = sum(evec(i,:)*tmp(:,j))
248  end do
249 end do
250 
251 ! Symmetry
252 do i=1,n
253  do j=i+1,n
254  a(i,j) = a(j,i)
255  end do
256 end do
257 
258 ! Probe out
259 
260 
261 end subroutine wrfda_da_eof_recomposition
262 
263 end module tools_wrfda
Subroutines/functions list.
Definition: tools_const.F90:31
real(kind_real), parameter, public one
One.
Definition: tools_const.F90:42
real(kind_real), parameter, public zero
Zero.
Definition: tools_const.F90:37
Kinds definition.
Definition: tools_kinds.F90:9
integer, parameter, public kind_real
Real kind alias for the whole code.
Definition: tools_kinds.F90:31
Subroutines/functions list.
Definition: tools_wrfda.F90:34
subroutine wrfda_pseudoinv(mpl, n, a, ainv, mmax, var_th)
Compute the pseudo-inverse of a covariance matrix.
Definition: tools_wrfda.F90:66
subroutine wrfda_da_eof_decomposition(mpl, n, a, evec, eval)
Compute eigenvectors and eigenvalues of a covariance matrix.
subroutine wrfda_da_eof_recomposition(n, mmax, evec, eval, a)
Recompute covariance matrix from a subset of eigenvectors and eigenvalues.
integer function wrfda_da_eof_dominant_mode(n, eval, var_th)
Compute dominant mode given a variance threshold.
Generic ranks, dimensions and types.
Definition: type_mpl.F90:42