38 integer,
parameter :: rk=kind(1.0d0)
40 integer,
intent(in) :: nrhs
41 real(kind=rk),
dimension(state_dim,nrhs),
intent(in) :: x
43 real(kind=rk),
dimension(state_dim,nrhs),
intent(out) :: px
46 real(kind=rk),
dimension(state_dim,pf%count) :: Xp_p
47 real(kind=rk),
dimension(obs_dim,pf%count) :: yf_p
48 real(kind=rk),
dimension(obs_dim,pf%nens) :: yf,Ysf
49 real(kind=rk),
dimension(obs_dim_g,pf%nens) :: Ysf_g
50 real(kind=rk),
dimension(obs_dim) :: mean_yf
51 integer,
dimension(npfs) :: start_var,stop_var
53 real(kind=rk),
dimension(:,:),
allocatable :: Xp
54 real(kind=rk),
dimension(:,:),
allocatable :: Xa
56 integer :: i,j,number_gridpoints
59 real(kind=rk),
allocatable,
dimension(:,:) :: Ysf_red
63 real(kind=rk),
dimension(:,:),
allocatable :: V
64 real(kind=rk),
dimension(:),
allocatable :: S
65 real(kind=rk),
dimension(pf%nens,pf%nens) :: UT
67 real(kind=rk),
dimension(:),
allocatable :: WORK
71 real(kind=rk),
dimension(state_dim,pf%count) :: x_p
73 integer :: ensemble_comm
76 call
qhalf(nrhs,x,xp_p)
78 if(comm_version .eq. 1 .or. comm_version .eq. 2)
then
79 ensemble_comm = pf_mpi_comm
80 elseif(comm_version .eq. 3)
then
81 ensemble_comm = pf_ens_comm
83 write(emp_e,*)
'EMPIRE VERSION ',comm_version,
' NOT SUPPORTED IN phalf_etkf'
84 write(emp_e,*)
'THIS IS AN ERROR. STOPPING'
100 call
h(obs_dim,pf%count,x_p,yf_p,pf%timestep)
105 call mpi_allgatherv(yf_p,pf%count*obs_dim,mpi_double_precision,yf&
106 &,gblcount*obs_dim,gbldisp*obs_dim,mpi_double_precision&
107 &,ensemble_comm,mpi_err)
110 mean_yf = sum(yf,dim=2)/
real(pf%nens,rk)
112 yf(:,i) = yf(:,i) - mean_yf
116 yf = yf/sqrt(
real(pf%nens-1,rk))
118 call
solve_rhalf(obs_dim,pf%nens,yf,ysf,pf%timestep)
124 start_var(i) = ((i-1)*state_dim)/npfs + 1
125 stop_var(i) = (i*state_dim)/npfs
129 allocate(xp(stop_var(pfrank+1)-start_var(pfrank+1)+1,pf%nens))
130 allocate(xa(stop_var(pfrank+1)-start_var(pfrank+1)+1,pf%nens))
134 number_gridpoints = stop_var(i)-start_var(i)+1
136 call mpi_gatherv(xp_p(start_var(i):stop_var(i),:),&
137 pf%count*number_gridpoints,&
138 mpi_double_precision,&
140 gblcount*number_gridpoints,&
141 gbldisp*number_gridpoints,&
142 mpi_double_precision,&
152 if(comm_version .eq. 1 .or. comm_version .eq. 2)
then
154 elseif(comm_version .eq. 3)
then
155 call mpi_allgatherv(ysf,obs_dim*pf%nens,mpi_double_precision&
156 &,ysf_g,obs_dims*pf%nens,obs_displacements*pf%nens&
157 &,mpi_double_precision,pf_member_comm,mpi_err)
159 print*,
'should not enter here. error. stopping :o('
163 number_gridpoints = stop_var(pfrank+1)-start_var(pfrank+1)+1
168 do j = 1,number_gridpoints
173 red_obsdim = obs_dim_g
176 allocate(ysf_red(red_obsdim,pf%nens))
180 ysf_red(:,i) = ysf_g(:,i)
184 r = min(red_obsdim,pf%nens)
185 allocate(v(red_obsdim,r))
187 lwork = 2*max( 3*r+max(red_obsdim,pf%nens), 5*r )
189 allocate(work(lwork))
191 call dgesvd(
'S',
'A',red_obsdim,pf%nens,ysf_red,red_obsdim,s,v,red_obsdim,ut,pf%nens,work,lwork,info)
193 write(emp_e,*)
'EMPIRE ERROR in phalf_etkf.f90 with the SVD'
194 write(emp_e,*)
'SVD failed with INFO = ',info
195 write(emp_e,*)
'FYI WORK(1) = ',work(1)
196 write(emp_e,*)
'STOPPING'
205 call dgemm(
'N',
'T',statedim,pf%nens,pf%nens,1.0d0,xp(j,:),statedim,ut,pf%nens,0.0d0,xa(j,:),statedim)
210 xa(j,i) = xa(j,i) / sqrt(1.0_rk + s(i)**2)
212 call dgemm(
'N',
'N',statedim,pf%nens,pf%nens,1.0d0,xa(j,:),statedim,ut,pf%nens,0.0d0,xp(j,:),statedim)
230 number_gridpoints = stop_var(i)-start_var(i)+1
232 call mpi_scatterv(xa,&
233 gblcount*number_gridpoints,&
234 gbldisp*number_gridpoints,&
235 mpi_double_precision,&
236 px(start_var(i):stop_var(i),:),&
237 pf%count*number_gridpoints,&
238 mpi_double_precision,&
Module containing EMPIRE coupling data.
Module that stores the information about the outputting from empire.
Module that stores the dimension of observation and state spaces.
subroutine h(obsDim, nrhs, x, hx, t)
subroutine to take a full state vector x and return H(x) in observation space.
subroutine phalf_etkf(nrhs, x, px)
Subroutine to go from N(0,Q) to N(0,P)
subroutine solve_rhalf(obsdim, nrhs, y, v, t)
subroutine to take an observation vector y and return v in observation space.
module pf_control holds all the information to control the the main program
subroutine qhalf(nrhs, x, Qx)
subroutine to take a full state vector x and return in state space.