EMPIRE DA  v1.9.1
Data assimilation codes using EMPIRE communication
 All Classes Files Functions Variables Pages
operator_wrappers.f90
Go to the documentation of this file.
1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2 !!! Time-stamp: <2016-11-23 11:07:26 pbrowne>
3 !!!
4 !!! Collection of combinations of other subroutines
5 !!! Copyright (C) 2014 Philip A. Browne
6 !!!
7 !!! This program is free software: you can redistribute it and/or modify
8 !!! it under the terms of the GNU General Public License as published by
9 !!! the Free Software Foundation, either version 3 of the License, or
10 !!! (at your option) any later version.
11 !!!
12 !!! This program is distributed in the hope that it will be useful,
13 !!! but WITHOUT ANY WARRANTY; without even the implied warranty of
14 !!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 !!! GNU General Public License for more details.
16 !!!
17 !!! You should have received a copy of the GNU General Public License
18 !!! along with this program. If not, see <http://www.gnu.org/licenses/>.
19 !!!
20 !!! Email: p.browne @ reading.ac.uk
21 !!! Mail: School of Mathematical and Physical Sciences,
22 !!! University of Reading,
23 !!! Reading, UK
24 !!! RG6 6BB
25 !!!
26 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
27 
32 subroutine k(y,x)
33  !subroutine to apply the operator K to a vector y in obs space and return
34  !the vector x in full state space.
35  use pf_control
36  use sizes
37  implicit none
38  integer, parameter :: rk=kind(1.0d+0)
39  real(kind=rk), dimension(state_dim,pf%count), intent(out) :: x
40  real(kind=rk), dimension(obs_dim,pf%count), intent(in) :: y
41 
42  real(kind=rk), dimension(obs_dim,pf%count) :: v
43  real(kind=rk), dimension(state_dim,pf%count) :: vv
44  ! real(kind=rk) :: dnrm2
45  integer :: i
46  ! print*,'||y||_2 = ',dnrm2(obs_dim,y,1)
47 
48  do i = 1,pf%count
49  call solve_hqht_plus_r(obs_dim,y(:,i),v(:,i),pf%timestep)
50  end do
51 
52  ! print*,'||(HQHT+R)^(-1)y||_2 = ',dnrm2(obs_dim,v,1)
53  call ht(obs_dim,pf%count,v,vv,pf%timestep)
54  ! print*,'||HTv||_2 = ',dnrm2(state_dim,vv,1)
55  call q(pf%count,vv,x)
56  ! print*,'||Qvv||_2 = ',dnrm2(state_dim,x,1)
57  call flush(6)
58 end subroutine k
59 
60 
61 
62 
63 !!$subroutine B(y,x)
64 !!$use pf_control
65 !!$use sizes
66 !!$implicit none
67 !!$integer, parameter :: rk = kind(1.0D0)
68 !!$real(kind=rk), dimension(obs_dim), intent(in) :: y
69 !!$real(kind=rk), dimension(state_dim), intent(out) :: x
70 !!$real(kind=rk), dimension(obs_dim) :: R_1y
71 !!$real(kind=rk), dimension(state_dim) :: HtR_1y,QHtR_1y
72 !!$real(kind=rk) :: freetime,p,tau
73 !!$
74 !!$freetime = 0.6_rk
75 !!$
76 !!$tau = real(modulo(pf%timestep,pf%time_bwn_obs),rk)/real(pf&
77 !!$ &%time_bwn_obs,rk)
78 !!$
79 !!$if(tau .lt. freetime) then
80 !!$ x = 0.0_rk
81 !!$else
82 !!$
83 !!$ call solve_r(y,R_1y)
84 !!$
85 !!$ call HT(R_1y,HtR_1y)
86 !!$
87 !!$ call Q(HtR_1y,QHtR_1y)
88 !!$
89 !!$ p = pf%nudgefac*(tau-freetime)/(1.0_rk-freetime)
90 !!$
91 !!$ x = p*QHtR_1y
92 !!$end if
93 !!$
94 !!$end subroutine B
95 
96 
109 subroutine bprime(y,x,QHtR_1y,normaln,betan)
110  !this is B but with separate Q multiplication
111  use timestep_data
112  use pf_control
113  use sizes
114  implicit none
115  integer, parameter :: rk = kind(1.0d0)
116  real(kind=rk), dimension(obs_dim,pf%count), intent(in) :: y
117  real(kind=rk), dimension(state_dim,pf%count), intent(out) :: x
118  real(kind=rk), dimension(obs_dim,pf%count) :: R_1y
119  real(kind=rk), dimension(state_dim,pf%count) :: HtR_1y
120  real(kind=rk), dimension(state_dim,pf%count), intent(out) :: QHtR_1y
121  real(kind=rk), dimension(state_dim,pf%count), intent(in) :: normaln
122  real(kind=rk), dimension(state_dim,pf%count), intent(out) :: betan
123  real(kind=rk), dimension(state_dim,2*pf%count) :: temp1,temp2
124  real(kind=rk) :: freetime,p,tau
125  real(kind=rk) :: t
126  real(kind=rk), dimension(7) :: ti
127  logical, parameter :: time = .false.
128  logical :: zero
129  include 'mpif.h'
130  if(time) t = mpi_wtime()
131  freetime = 0.6_rk
132 
133  tau = real(tsdata%tau,rk)/real(pf%time_bwn_obs,rk)
134 
135  call relaxation_profile(tau,p,zero)
136 
137  !this is when the nudging term is zero
138  if(zero) then
139  x = 0.0_rk
140  if(time) ti(1:3) = mpi_wtime()
141  qhtr_1y = 0.0_rk
142  if(time) ti(4) = mpi_wtime()
143  call qhalf(pf%count,normaln,betan)
144  if(time) ti(5:7) = mpi_wtime()
145  else !this is when the nudging term is nonzero
146 
147  call solve_r(obs_dim,pf%count,y,r_1y,pf%timestep)
148  if(time) ti(1) = mpi_wtime()
149  call ht(obs_dim,pf%count,r_1y,htr_1y,pf%timestep)
150  if(time) ti(2) = mpi_wtime()
151 
152  !p = pf%nudgefac*(tau-freetime)/(1.0d0-freetime)
153 
154  x = p*htr_1y
155  if(time) ti(3) = mpi_wtime()
156  temp1(:,1:pf%count) = x
157  temp1(:,pf%count+1:2*pf%count) = normaln
158  if(time) ti(4) = mpi_wtime()
159  call qhalf(2*pf%count,temp1,temp2)
160  if(time) ti(5) = mpi_wtime()
161  betan = temp2(:,pf%count+1:2*pf%count)
162  !x = temp2(:,1:pf%count)
163  if(time) ti(6) = mpi_wtime()
164  call qhalf(pf%count,temp2(:,1:pf%count),qhtr_1y)
165  if(time) ti(7) = mpi_wtime()
166 
167  end if
168  if(time) then
169  ti(7) = ti(7) - ti(6)
170  ti(6) = ti(6) - ti(5)
171  ti(5) = ti(5) - ti(4)
172  ti(4) = ti(4) - ti(3)
173  ti(3) = ti(3) - ti(2)
174  ti(2) = ti(2) - ti(1)
175  ti(1) = ti(1) - t
176 
177  print*,'Bprime times =',ti
178  print*,'_______'
179  end if
180 
181 
182 end subroutine bprime
183 
184 !!$subroutine Qhalf(x,y)
185 !!$
186 !!$ ! Simple code to illustrate row entry to hsl_ea20
187 !!$! use pf_control
188 !!$ use HSL_EA20_double
189 !!$ use sizes
190 !!$ implicit none
191 !!$
192 !!$ ! Derived types
193 !!$ type (ea20_control) :: cntl
194 !!$ type (ea20_info) :: info
195 !!$ type (ea20_reverse) :: rev
196 !!$
197 !!$ ! Parameters
198 !!$
199 !!$ integer, parameter :: wp = kind(0.0d0)
200 !!$ integer :: ido
201 !!$ real(kind=kind(1.0D0)), dimension(state_dim), intent(out) :: y
202 !!$ real(kind=kind(1.0D0)), dimension(state_dim), intent(in) :: x
203 !!$ real(kind=kind(1.0D0)), allocatable :: w(:,:)
204 !!$ real(kind=kind(1.0D0)) :: s
205 !!$
206 !!$ !! set u
207 !!$ y = x
208 !!$
209 !!$ !! set data
210 !!$ s = 0.5d0
211 !!$
212 !!$ !! set cntl
213 !!$ cntl%d = 3 !! delay
214 !!$ cntl%tol = 1.d-2 !! convergece tolerance
215 !!$ cntl%maxit = 20 !! max number iteration
216 !!$
217 !!$ cntl%diagnostics_level = 1 !! full error check
218 !!$
219 !!$ ido = -1
220 !!$
221 !!$ do while ( ido .ne. 0 .and. info%flag == 0)
222 !!$
223 !!$ call EA20(state_dim,y,s,ido,w,cntl,info,rev)
224 !!$
225 !!$ select case ( ido )
226 !!$
227 !!$ case (0)
228 !!$ exit
229 !!$
230 !!$ case (1) !! Matrix-Vector product w_out = A w(:,1)
231 !!$ call Q(w(:,1),w(:,2))
232 !!$
233 !!$! if(maxval(abs(w(:,1)-w(:,2))) .gt. 1.0D-10) then
234 !!$! print*,'shaft! ',maxval(abs(w(:,1)-w(:,2)))
235 !!$! end if
236 !!$
237 !!$ case (2) !! Matrix-Vector product w(:,2) = M w(:,1)
238 !!$ w(:,2) = w(:,1)
239 !!$
240 !!$ case (3) !! Matrix-Vector product w_out = inv(M) w(:,1)
241 !!$ w(:,2) = w(:,1)
242 !!$
243 !!$ end select
244 !!$
245 !!$ end do
246 !!$
247 !!$
248 !!$ if (info%flag .ge. 0) then
249 !!$! write(*,'(a,i5)') 'error code = ',info%flag
250 !!$ !! print the final solution
251 !!$! write(*,'(a,i5)') 'number of iterations = ',info%iter
252 !!$! write(*,'(a,1x,1pe14.2)') 'estimated final error = ',info%error
253 !!$! write(*,'(a)') ' i X(i)'
254 !!$! write(*,'(i5,1x,1pe14.3)') (i,y(i), i=1,state_dim)
255 !!$
256 !!$ else
257 !!$! write(*,'(i5,1x,1pe14.3)') (i,x(i), i=1,state_dim)
258 !!$ print*,'EA20 broke: max x = ',maxval(x),' min x = ',minval(x)
259 !!$! write(filename,'(A,i0)') 'data',pf%timestep
260 !!$! open(20,file=filename,action='write')
261 !!$! do ido = 1,state_dim
262 !!$! write(20,*) x(ido)
263 !!$! end do
264 !!$! close(20)
265 !!$
266 !!$! stop
267 !!$ end if
268 !!$
269 !!$
270 !!$end subroutine Qhalf
271 
272 
273 
subroutine solve_r(obsDim, nrhs, y, v, t)
subroutine to take an observation vector y and return v in observation space.
Module that stores the information about the timestepping process.
subroutine bprime(y, x, QHtR_1y, normaln, betan)
subroutine to calculate nudging term and correlated random errors efficiently
Module that stores the dimension of observation and state spaces.
Definition: sizes.f90:29
subroutine ht(obsDim, nrhs, y, x, t)
subroutine to take an observation vector y and return x in full state space.
module pf_control holds all the information to control the the main program
Definition: pf_control.f90:29
subroutine solve_hqht_plus_r(obsdim, y, v, t)
subroutine to take an observation vector y and return v in observation space.
subroutine qhalf(nrhs, x, Qx)
subroutine to take a full state vector x and return in state space.
subroutine k(y, x)
Subroutine to apply to a vector y in observation space where .
subroutine q(nrhs, x, Qx)
subroutine to take a full state vector x and return Qx in state space.
subroutine relaxation_profile(tau, p, zero)
subroutine to compute the relaxation strength