1 subroutine da_transform_xtoy_gpsztd ( grid, iv, y )
2 !----------------------------------------------------------------
3 ! Purpose: To calculate the observed ZTD with the height
4 ! correction in considering the differexbnce between
5 ! the model terrain height and receiver height.
7 ! The logic is similar to the Gpspw:
9 ! when the receiver below the model surface, a correction,
10 ! "dzd" should be subtructed from the observed ZTD;
11 ! when the receiver higher than the model suface, a
12 ! correction "ztd" should be added to the observed ZTD.
14 !----------------------------------------------------------------
18 type (domain), intent(in) :: grid
19 type (iv_type), intent(in) :: iv ! Innovation vector (O-B).
20 type (y_type), intent(INOUT) :: y ! y = h (xa)
22 INTEGER :: n ! Loop counter.
23 INTEGER :: i, j ! Index dimension.
27 INTEGER :: k ! Index dimension.
28 REAL :: dzd, ddzd ! adjustment pw [mm]
29 REAL :: obs_terr ! real terrain height at GPS site [m]
30 REAL :: model_terr ! model terrain height at GPS site[m]
31 REAL,DIMENSION(kts:kte):: model_ztd ! model ztd at GPS site [m]
32 REAL,DIMENSION(kts:kte):: model_z ! model height at GPS site [m]
34 if (trace_use_dull) call da_trace_entry("da_transform_xtoy_gpsztd")
36 !bugfix-for-4dvar y % gpspw(:)% tpw = 0.0
38 do n=iv%info(gpspw)%n1,iv%info(gpspw)%n2
40 i = iv%info(gpspw)%i(1,n)
41 dy = iv%info(gpspw)%dy(1,n)
42 dym = iv%info(gpspw)%dym(1,n)
43 j = iv%info(gpspw)%j(1,n)
44 dx = iv%info(gpspw)%dx(1,n)
45 dxm = iv%info(gpspw)%dxm(1,n)
47 ! Mathematical transformation:
50 obs_terr = iv%info(gpspw)%elv(n)
51 model_terr = dym*(dxm*grid%xb%terr(i,j) + dx*grid%xb%terr(i+1,j)) + &
52 dy *(dxm*grid%xb%terr(i,j+1) + dx*grid%xb%terr(i+1,j+1))
54 if ( obs_terr <= model_terr ) then
56 model_ztd(1) = dym*(dxm*grid%xa%ref(i,j,1) + dx*grid%xa%ref(i+1,j,1)) + &
57 dy *(dxm*grid%xa%ref(i,j+1,1) + dx*grid%xa%ref(i+1,j+1,1))
59 dzd = model_ztd(1) * ( obs_terr - model_terr )
63 model_z(1) = dym*(dxm*grid%xb%hf(i,j,1) + dx*grid%xb%hf(i+1,j,1)) + &
64 dy *(dxm*grid%xb%hf(i,j+1,1) + dx*grid%xb%hf(i+1,j+1,1))
68 if (model_z(k) >= obs_terr ) exit
70 model_z(k+1) = dym*(dxm*grid%xb%hf(i,j,k+1) + dx*grid%xb%hf(i+1,j,k+1)) + &
71 dy *(dxm*grid%xb%hf(i,j+1,k+1) + dx*grid%xb%hf(i+1,j+1,k+1))
73 model_ztd(k) = dym*(dxm*grid%xa%ref(i,j,k) + dx*grid%xa%ref(i+1,j,k)) + &
74 dy *(dxm*grid%xa%ref(i,j+1,k) + dx*grid%xa%ref(i+1,j+1,k))
76 ! Here assumed that "model_z" is constant, i.e. grid%xa%hf=0.0. With MM5,
77 ! this is true, but with WRF, grid%xa%hf may not be zero (?). In the WRF
78 ! model space (x,y,znu), only the "znu" is constant, but all variables
79 ! including height could be changed at the "znu" levels. So here is only
80 ! an approximation for WRF. The following few lines of code is written
81 ! by Y.-R. Guo 07/16/2004.
83 if ( model_z(k+1) <= obs_terr ) then
84 ddzd = model_ztd(k) * ( model_z(k+1) - model_z(k) )
86 ddzd = model_ztd(k) * ( obs_terr - model_z(k) )
94 y % gpspw(n)% tpw = dym* ( dxm * grid%xa%ztd(i,j) + &
95 dx * grid%xa%ztd(i+1,j) ) + &
96 dy * ( dxm * grid%xa%ztd(i,j+1) + &
97 dx * grid%xa%ztd(i+1,j+1) ) &
102 if (trace_use_dull) call da_trace_exit("da_transform_xtoy_gpsztd")
104 end subroutine da_transform_xtoy_gpsztd