EMPIRE DA  v1.9.1
Data assimilation codes using EMPIRE communication
 All Classes Files Functions Variables Pages
genQ.f90
Go to the documentation of this file.
1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2 !!! Time-stamp: <2015-03-23 15:54:58 pbrowne>
3 !!!
4 !!! A subroutine to estimate Q from a long model run
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 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
28 subroutine genq
29  use sizes
30  use pf_control
31  use comms
32  implicit none
33  include 'mpif.h'
34  integer, parameter :: rk=(kind(1.0d0))
35 
36 ! integer, dimension(a_nxn,a_nyn,a_levels) :: a_u_vec,a_v_vec,a_theta_vec,a_q_vec
37 ! integer, dimension(a_nxn,a_nyn) :: a_pstar_vec
38 ! integer, dimension(o_nxn,o_nyn,o_levels) :: o_u_vec,o_v_vec,o_theta_vec,o_sal_vec
39  integer :: i,counter,radius,nnz!,j,k
40  integer, parameter :: n = 426655238
41  integer, allocatable, dimension(:) :: row,col
42  real(kind=rk), allocatable, dimension(:) :: val
43  integer :: ne,iter,day,tag,mpi_err,days
44  integer :: mpi_status(mpi_status_size)
45  real(kind=rk), dimension(state_dim) :: x
46  real(kind=rk) :: start_t,end_t
47 
48  stop 'IS GENQ DESIGNED FOR THIS SPECIFIC MODEL??'
49 
50  allocate(pf%mean(state_dim),row(n),col(n),val(n))
51  print*,'Going to generate Q ~ the model error covariance matrix'
52 
53 
54 
55  start_t = mpi_wtime()
56  !let us calculate the position vectors: put everything in its place:
57  counter = 0
58 !!$ !first is PSTAR (2d)
59 !!$ do j = 1,a_nyn
60 !!$ do i = 1,a_nxn
61 !!$ counter = counter + 1
62 !!$ a_pstar_vec(i,j) = counter
63 !!$ end do
64 !!$ end do
65 !!$ print*,'a_pstar finishes on the ',counter,' element'
66 !!$ !second is U
67 !!$ do k = 1,a_levels
68 !!$ do j = 1,a_nyn
69 !!$ do i = 1,a_nxn
70 !!$ counter = counter + 1
71 !!$ a_u_vec(i,j,k) = counter
72 !!$ end do
73 !!$ end do
74 !!$ end do
75 !!$ print*,'a_u finishes on the ',counter,' element'
76 !!$ !FINISHED COMPUTING THE VECTOR POSITIONS OF EACH COMPONENT
77 !!$ print*,'FINISHED COMPUTING THE VECTOR POSITIONS OF EACH COMPONENT'
78 
79  end_t = mpi_wtime()
80  print*,'and it took ',end_t-start_t,' seconds'
81 ! stop
82  !initialise the value thingy
83  val = 0.0_rk
84 
85  !initialise the mean
86  pf%mean = 0.0_rk
87  tag = 1
88  print*,'first recv...'
89  call mpi_recv(pf%psi(:,1), state_dim, mpi_double_precision, &
90  0, tag, cpl_mpi_comm,mpi_status, mpi_err)
91  print*,'.............recvd'
92 
93  !loop for 5 years:
94  days = 360*5
95  do day = 1,days
96  start_t = mpi_wtime()
97  print*,'day = ',day
98  !update by a day, or 72 iterations:
99  do iter = 1,72
100  call mpi_send(pf%psi(:,1), state_dim , mpi_double_precision, &
101  0, tag, cpl_mpi_comm, mpi_err)
102  print*,'iter = ',iter
103  call mpi_recv(pf%psi(:,1), state_dim, mpi_double_precision, &
104  0, tag, cpl_mpi_comm,mpi_status, mpi_err)
105  end do
106  end_t = mpi_wtime()
107  print*,'72 model runs on ',day,' took ',end_t-start_t,' seconds'
108  !update the mean:
109  pf%mean = pf%mean + pf%psi(:,1)
110 
111  x = pf%psi(:,1)
112 
113  radius = 2
114  start_t = mpi_wtime()
115 
116  ! call genQ_at2d_at2d(ne,row,col,val,n,radius,field1,field2,x)
117 
118  print*,'finished genQ_order at the end of the day with ne = ',ne
119  end_t = mpi_wtime()
120  print*,'generating Q on ',day,' took ',end_t-start_t,' seconds.'
121 
122  end do !end of the daily loop
123 
124 
125 
126  !now we should divide the value by N-1 = 360*5-1...
127  val = val/real(days-1,rk)
128 
129 
130  !now subtract off the mean components:
131  pf%mean = pf%mean/real(days,rk)
132 
133 
134  val = -1.0_rk*val
135  x = pf%mean
136 
137 ! call genQ_at2d_at2d(ne,row,col,val,n,radius,field1,field2,x)
138 
139  val = -1.0_rk*val
140 
141 
142  print*,'MAXIMUM COVARIANCE VALUE = ',maxval(val)
143  print*,'MIMINUM COVARIANCE VALUE = ',minval(val)
144  print*,'MINIMUM ABSOLUTE C VALUE = ',minval(abs(val))
145 
146 
147 
148 
149 
150 
151 
152  !do the final mpi send to end model cleanly
153  call mpi_send(pf%psi(:,1), state_dim , mpi_double_precision, &
154  0, tag, cpl_mpi_comm, mpi_err)
155 
156 
157  !now let us scale Q
158  val = val/1.0d4
159 
160 
161 
162 
163 
164 
165 
166  nnz = 0
167  do i = 1,ne
168  if(row(i) .eq. col(i) .or. abs(val(i)) .gt. 1.0d-13) nnz = nnz + 1
169  end do
170 
171  open(2,file='Qdata.dat',action='write',status='replace',form='unformatted')
172  write(2) state_dim
173  write(2) nnz
174 
175  do i = 1,ne
176  if(row(i) .eq. col(i) .or. abs(val(i)) .gt. 1.0d-13) write(2) val(i)
177  end do
178  do i = 1,ne
179  if(row(i) .eq. col(i) .or. abs(val(i)) .gt. 1.0d-13) write(2) row(i)
180  end do
181  do i = 1,ne
182  if(row(i) .eq. col(i) .or. abs(val(i)) .gt. 1.0d-13) write(2) col(i)
183  end do
184  close(2)
185  print*,'finished generating Q'
186 
187  deallocate(pf%mean,row,col,val)
188 
189 
190 
191 
192 
193 
194 end subroutine genq
195 
196 
197 !!$subroutine genQ_at2d_at2d(ne,row,col,val,n,radius,field1,field2,x)
198 !!$ use hadcm3_config
199 !!$ use sizes
200 !!$ implicit none
201 !!$ integer, parameter :: rk = kind(1.0d0)
202 !!$ integer, intent(inout) :: ne
203 !!$ integer, intent(in) :: n,radius
204 !!$ integer, dimension(n), intent(inout) :: row,col
205 !!$ real(kind=rk), dimension(n), intent(inout) :: val
206 !!$ real(kind=rk), dimension(state_dim), intent(in) :: x
207 !!$ integer, dimension(a_nxn,a_nyn), intent(in) :: field1,field2
208 !!$ integer :: i,j,ii,jj
209 !!$
210 !!$ do j = 1,a_nyn
211 !!$ do i = 1,a_nxn
212 !!$ do jj = max(1,j-radius),min(a_nyn,j+radius)
213 !!$ do ii = max(1,i-radius),min(a_nxn,i+radius)
214 !!$ if(field1(i,j) .le. field2(ii,jj)) then
215 !!$ ne = ne + 1
216 !!$ row(ne) = field1(i,j)
217 !!$ col(ne) = field2(ii,jj)
218 !!$ val(ne) = val(ne)+x(row(ne))*x(col(ne))
219 !!$ end if
220 !!$ end do
221 !!$ if(i .le. radius) then
222 !!$ do ii = a_nxn-radius+i,a_nxn
223 !!$ if(field1(i,j) .le. field2(ii,jj)) then
224 !!$ ne = ne + 1
225 !!$ row(ne) = field1(i,j)
226 !!$ col(ne) = field2(ii,jj)
227 !!$ val(ne) = val(ne)+x(row(ne))*x(col(ne))
228 !!$ end if
229 !!$ end do
230 !!$ end if
231 !!$ if(i+radius .gt. a_nxn) then
232 !!$ do ii = 1,i+radius-a_nxn
233 !!$ if(field1(i,j) .le. field2(ii,jj)) then
234 !!$ ne = ne + 1
235 !!$ row(ne) = field1(i,j)
236 !!$ col(ne) = field2(ii,jj)
237 !!$ val(ne) = val(ne)+x(row(ne))*x(col(ne))
238 !!$ end if
239 !!$ end do
240 !!$ end if
241 !!$ end do
242 !!$ end do
243 !!$ end do
244 !!$end subroutine genQ_at2d_at2d
245 
246 
Module containing EMPIRE coupling data.
Definition: comms.f90:57
Module that stores the dimension of observation and state spaces.
Definition: sizes.f90:29
module pf_control holds all the information to control the the main program
Definition: pf_control.f90:29
subroutine genq
Subroutine to estimate Q from a long model run.
Definition: genQ.f90:28