1 subroutine da_get_innov_vector_gpspw (it,num_qcstat_conv, grid, ob, iv)
3 !----------------------------------------------------------------
5 ! Updated for Analysis on Arakawa-C grid
6 ! Author: Syed RH Rizvi, MMM/ESSL/NCAR, Date: 10/22/2008
7 !----------------------------------------------------------------
11 integer, intent(in) :: it ! External iteration.
12 type(domain), intent(in) :: grid ! first guess state.
13 type(y_type), intent(inout) :: ob ! Observation structure.
14 type(iv_type), intent(inout) :: iv ! O-B structure.
15 integer, intent(inout) :: num_qcstat_conv(:,:,:,:)
18 integer :: n ! Loop counter.
19 integer :: i, j ! Index dimension.
20 real :: dx, dxm ! Interpolation weights.
21 real :: dy, dym ! Interpolation weights.
22 real :: model_tpw! Model value u at oblocation.
24 !--------------------------------------------------------------------------
25 integer :: k ! Index dimension
26 real :: dpw, ddpw ! adjustment pw [mm]
27 real :: obs_terr ! real terrain height at GPS site [m]
28 real :: model_terr ! model terrain height at GPS site[m]
29 real :: model_q(kts:kte) ! model q at GPS site [kg/kg]
30 real :: model_z(kts:kte) ! model z at GPS site [m]
31 real :: model_rho(kts:kte) ! model rho at GPS site [kg/m^3]
33 if (trace_use_dull) call da_trace_entry("da_get_innov_vector_gpspw")
35 ! unit_gps = myproc + 140
36 !---------------------------------------------------------------------------
38 if (iv%info(gpspw)%nlocal > 0) then
41 do n=iv%info(gpspw)%n1,iv%info(gpspw)%n2
43 if( iv % gpspw(n) % tpw % qc == fails_error_max .and. it > 1) &
44 iv % gpspw(n) % tpw % qc = 0
46 ! [1.1] Get horizontal interpolation weights:
48 i = iv%info(gpspw)%i(1,n)
49 j = iv%info(gpspw)%j(1,n)
50 dx = iv%info(gpspw)%dx(1,n)
51 dy = iv%info(gpspw)%dy(1,n)
52 dxm = iv%info(gpspw)%dxm(1,n)
53 dym = iv%info(gpspw)%dym(1,n)
55 model_tpw = dym*(dxm*grid%xb%tpw(i,j) + dx*grid%xb%tpw(i+1,j)) + &
56 dy *(dxm*grid%xb%tpw(i,j+1) + dx*grid%xb%tpw(i+1,j+1))
58 ! To compute the 'inv':
59 if ( .not. pseudo_tpw ) iv % gpspw(n) % tpw % inv = 0.0
60 if (ob % gpspw(n) % tpw > missing_r .AND. &
61 iv % gpspw(n) % tpw % qc >= obs_qc_pointer) then
63 obs_terr = iv%info(gpspw)%elv(n)
64 model_terr = dym*(dxm*grid%xb%terr(i,j) + dx*grid%xb%terr(i+1,j)) + &
65 dy *(dxm*grid%xb%terr(i,j+1) + dx*grid%xb%terr(i+1,j+1))
66 if (obs_terr <= model_terr) then
67 model_q(1) = dym*(dxm*grid%xb%q(i,j,1) + dx*grid%xb%q(i+1,j,1)) + &
68 dy *(dxm*grid%xb%q(i,j+1,1) + dx*grid%xb%q(i+1,j+1,1))
69 model_rho(1) = dym*(dxm*grid%xb%rho(i,j,1) + dx*grid%xb%rho(i+1,j,1)) + &
70 dy *(dxm*grid%xb%rho(i,j+1,1) + dx*grid%xb%rho(i+1,j+1,1))
71 dpw = model_rho(1) * model_q(1) *( obs_terr - model_terr)
73 model_z(1) = dym*(dxm*grid%xb%hf(i,j,1) + dx*grid%xb%hf(i+1,j,1)) + &
74 dy *(dxm*grid%xb%hf(i,j+1,1) + dx*grid%xb%hf(i+1,j+1,1))
76 if (model_z(k) >= obs_terr) exit
78 model_z(k+1) = dym*(dxm*grid%xb%hf(i,j,k+1) + dx*grid%xb%hf(i+1,j,k+1)) + &
79 dy *(dxm*grid%xb%hf(i,j+1,k+1) + dx*grid%xb%hf(i+1,j+1,k+1))
80 model_q(k) = dym*(dxm*grid%xb%q(i,j,k) + dx*grid%xb%q(i+1,j,k)) + &
81 dy *(dxm*grid%xb%q(i,j+1,k) + dx*grid%xb%q(i+1,j+1,k))
82 model_rho(k) = dym*(dxm*grid%xb%rho(i,j,k) + dx*grid%xb%rho(i+1,j,k)) + &
83 dy *(dxm*grid%xb%rho(i,j+1,k) + dx*grid%xb%rho(i+1,j+1,k))
85 if (model_z(k+1) <= obs_terr) then
86 ddpw = model_rho(k) * model_q(k) *( model_z(k+1) - model_z(k))
88 ddpw = model_rho(k) * model_q(k) *( obs_terr - model_z(k))
94 if ( pseudo_tpw .and. it == 1 ) then
95 ! To compute the 'ob':
96 ob % gpspw(n) % tpw = iv % gpspw(n) % tpw % inv + model_tpw - 0.1*dpw
98 iv % gpspw(n) % tpw % inv = ob % gpspw(n) % tpw - model_tpw + 0.1*dpw
104 !------------------------------------------------------------------------
105 ! [5.0] Perform optional maximum error check:
106 !------------------------------------------------------------------------
107 if ( .not. pseudo_tpw .and. check_max_iv ) &
108 call da_check_max_iv_gpspw(iv, it, num_qcstat_conv)
110 if (trace_use_dull) call da_trace_exit("da_get_innov_vector_gpspw")
112 end subroutine da_get_innov_vector_gpspw