1 subroutine da_vertical_transform(grid, string, be, vertical_wgt, vv, vp)
3 !---------------------------------------------------------------------
4 ! Purpose: perform vertical transform Uv using eigenvector/eigenvalue
5 ! of vertical covariance
7 ! Zhiquan (Jake) Liu, NCAR/MMM, 2015-09
8 ! 1. add appropriate comments on transform and variables
9 ! 2. replace inverse transform da_transform_vptovv
10 ! by da_transform_vvtovp_inv
11 !---------------------------------------------------------------------
15 type (domain), intent(in) :: grid
16 character(len=*), intent(in) :: string ! Character operation
17 type (be_type), intent(in) :: be ! Background error structure.
18 real, intent(in) :: vertical_wgt(ims:ime,jms:jme,kms:kme) ! Weighting.
19 type (vp_type), intent(inout) :: vv ! CV in gridpt/EOF space.
20 type (vp_type), intent(inout) :: vp ! CV in gridpt/level space.
22 integer :: j, m, n ! Loop counters.
23 real :: alpha_stddev_inv ! 1/ sigma_alpha
24 real :: size_inv ! 1 / size.
25 real :: alpha_me, alpha_ms, alpha_sd ! Alpha statistics.
27 if (trace_use) call da_trace_entry("da_vertical_transform")
33 !-------------------------------------------------------------------
34 ! [1.0] Perform vp(i,j,k) = E L^{1/2} vv(i,j,m) transform:
35 !-------------------------------------------------------------------
37 if (be % v1 % mz > 0) then
38 call da_transform_vvtovp (grid, be % v1 % evec, be % v1 % val, vertical_wgt, &
39 vv % v1, vp % v1, be % v1 % mz, kte) ! psi (stream function) or u (if cv7)
41 vp % v1(its:ite,jts:jte,kts:kte) = 0.0
44 if (be % v2 % mz > 0) then
45 call da_transform_vvtovp (grid, be % v2 % evec, be % v2 % val, vertical_wgt, &
46 vv % v2, vp % v2, be % v2 % mz, kte) ! chi_u (unbalanced chi) or v (if cv7)
48 vp % v2(its:ite,jts:jte,kts:kte) = 0.0
51 if (be % v3 % mz > 0) then
52 call da_transform_vvtovp (grid, be % v3 % evec, be % v3 % val, vertical_wgt, &
53 vv % v3, vp % v3, be % v3 % mz, kte) ! T_u (unbalanced T) or T (if cv7)
55 vp % v3(its:ite,jts:jte,kts:kte) = 0.0
58 if (be % v4 % mz > 0) then
59 call da_transform_vvtovp (grid, be % v4 % evec, be % v4 % val, vertical_wgt, &
60 vv % v4, vp % v4, be % v4 % mz, kte) ! pseudo rh=q/qs(background)
62 vp % v4(its:ite,jts:jte,kts:kte) = 0.0
65 if (be % v5 % mz > 0) then
67 vp % v5(its:ite,jts:jte,1) = vv % v5(its:ite,jts:jte,1)
69 call da_transform_vvtovp (grid, be % v5 % evec, be % v5 % val, vertical_wgt, &
70 vv % v5, vp % v5, be % v5 % mz, kts) ! Ps_u (unbalanced Ps) or Ps (if cv7)
73 vp % v5(its:ite,jts:jte,kts:kts) = 0.0
76 ! for cloud_cv_options<=1 and not use_cv_w
77 vp % v6 = 0.0 ! cloud water qcw
78 vp % v7 = 0.0 ! rain water qrain
79 vp % v8 = 0.0 ! cloud ice qice
80 vp % v9 = 0.0 ! snow qsnow
81 vp % v10 = 0.0 ! qgraupel
82 vp % v11 = 0.0 ! vertical velocity w
84 if ( cloud_cv_options == 2 ) then
85 if (be % v6 % mz > 0) then
86 call da_transform_vvtovp (grid, be % v6 % evec, be % v6 % val, vertical_wgt, &
87 vv % v6, vp % v6, be % v6 % mz, kte)
90 if (be % v7 % mz > 0) then
91 call da_transform_vvtovp (grid, be % v7 % evec, be % v7 % val, vertical_wgt, &
92 vv % v7, vp % v7, be % v7 % mz, kte)
95 if (be % v8 % mz > 0) then
96 call da_transform_vvtovp (grid, be % v8 % evec, be % v8 % val, vertical_wgt, &
97 vv % v8, vp % v8, be % v8 % mz, kte)
100 if (be % v9 % mz > 0) then
101 call da_transform_vvtovp (grid, be % v9 % evec, be % v9 % val, vertical_wgt, &
102 vv % v9, vp % v9, be % v9 % mz, kte)
105 if (be % v10% mz > 0) then
106 call da_transform_vvtovp (grid, be % v10 % evec, be % v10 % val, vertical_wgt, &
107 vv % v10, vp % v10, be % v10 % mz, kte)
109 else if ( cloud_cv_options == 3 ) then
110 if ( be % v6 % mz > 0) vp % v6 = vv % v6
111 if ( be % v7 % mz > 0) vp % v7 = vv % v7
112 if ( be % v8 % mz > 0) vp % v8 = vv % v8
113 if ( be % v9 % mz > 0) vp % v9 = vv % v9
114 if ( be % v10 % mz > 0) vp % v10 = vv % v10
118 if (be % v11 % mz > 0) then
119 if ( cloud_cv_options == 2 ) then
120 call da_transform_vvtovp (grid, be % v11 % evec, be % v11 % val, vertical_wgt, &
121 vv % v11, vp % v11, be % v11 % mz, kte)
122 else if ( cloud_cv_options == 3 ) then
128 if ( be % ne > 0 .and. be % alpha % mz > 0 ) then
130 if ( anal_type_hybrid_dual_res ) then
131 call da_transform_vvtovp_dual_res (grid%intermediate_grid, be % alpha % evec, be % alpha % val, vertical_wgt, &
132 vv % alpha(:,:,:,n), vp % alpha(:,:,:,n), be % alpha % mz, kte_int)
134 call da_transform_vvtovp (grid, be % alpha % evec, be % alpha % val, vertical_wgt, &
135 vv % alpha(:,:,:,n), vp % alpha(:,:,:,n), be % alpha % mz, kte_int)
139 ! Calculate alpha standard deviation diagnostic:
140 ! size_inv = 1.0 / ( (ite-its+1) * ( jte-jts+1) * be % ne * be % alpha % mz )
141 ! alpha_me = sum(vp % alpha(its:ite,jts:jte,:)) * size_inv
142 ! alpha_ms = sum(vp % alpha(its:ite,jts:jte,:) * vp % alpha(its:ite,jts:jte,:)) * &
144 ! alpha_sd = sqrt( alpha_ms - alpha_me * alpha_me )
145 ! write(6,'(a,f15.5)')' Alpha std. dev = ', alpha_sd
150 !-------------------------------------------------------------------
151 ! [2.0] Perform inverse transform: vv(i,j,m) = L^{-1/2} E^T vp(i,j,k)
152 !-------------------------------------------------------------------
154 if (be % v1 % mz > 0) then
155 call da_transform_vvtovp_inv (grid, be % v1 % evec, be % v1 % val, vertical_wgt, &
156 vp % v1, vv % v1, be % v1 % mz, kte)
159 if (be % v2 % mz > 0) then
160 call da_transform_vvtovp_inv (grid, be % v2 % evec, be % v2 % val, vertical_wgt, &
161 vp % v2, vv % v2, be % v2 % mz, kte)
164 if (be % v3 % mz > 0) then
165 call da_transform_vvtovp_inv (grid, be % v3 % evec, be % v3 % val, vertical_wgt, &
166 vp % v3, vv % v3, be % v3 % mz, kte)
169 if (be % v4 % mz > 0) then
170 call da_transform_vvtovp_inv (grid, be % v4 % evec, be % v4 % val, vertical_wgt, &
171 vp % v4, vv % v4, be % v4 % mz, kte)
174 if (be % v5 % mz > 0) then
176 vv % v5(its:ite,jts:jte,1) = vp % v5(its:ite,jts:jte,1)
178 call da_transform_vvtovp_inv (grid, be % v5 % evec, be % v5 % val, vertical_wgt, &
179 vp % v5, vv % v5, be % v5 % mz, kts)
183 if ( cloud_cv_options == 2 ) then
184 if (be % v6 % mz > 0) then
185 call da_transform_vvtovp_inv (grid, be % v6 % evec, be % v6 % val, vertical_wgt, &
186 vp % v6, vv % v6, be % v6 % mz, kte)
189 if (be % v7 % mz > 0) then
190 call da_transform_vvtovp_inv (grid, be % v7 % evec, be % v7 % val, vertical_wgt, &
191 vp % v7, vv % v7, be % v7 % mz, kte)
194 if (be % v8 % mz > 0) then
195 call da_transform_vvtovp_inv (grid, be % v8 % evec, be % v8 % val, vertical_wgt, &
196 vp % v8, vv % v8, be % v8 % mz, kte)
199 if (be % v9 % mz > 0) then
200 call da_transform_vvtovp_inv (grid, be % v9 % evec, be % v9 % val, vertical_wgt, &
201 vp % v9, vv % v9, be % v9 % mz, kte)
204 if (be % v10 % mz > 0) then
205 call da_transform_vvtovp_inv (grid, be % v10 % evec, be % v10 % val, vertical_wgt, &
206 vp % v10, vv % v10, be % v10 % mz, kte)
209 else if ( cloud_cv_options == 3 ) then
210 if (be % v6 % mz > 0) then
214 if (be % v7 % mz > 0) then
218 if (be % v8 % mz > 0) then
222 if (be % v9 % mz > 0) then
226 if (be % v10 % mz > 0) then
233 if (be % v11 % mz > 0) then
234 if ( cloud_cv_options == 2 ) then
235 call da_transform_vvtovp_inv (grid, be % v11 % evec, be % v11 % val, vertical_wgt, &
236 vp % v11, vv % v11, be % v11 % mz, kte)
237 else if ( cloud_cv_options == 3 ) then
243 if ( be % ne > 0 .and. be % alpha % mz > 0 ) then
245 ! call da_transform_vptovv (be % alpha % evec, be % alpha % val, vertical_wgt, &
246 ! vp % alpha(:,:,:,n), vv % alpha(:,:,:,n), be % alpha % mz, kds,kde, &
247 ! ims,ime, jms,jme, kms,kme, its,ite, jts,jte, kts,kte)
248 ! call da_transform_vptovv (be % alpha % evec, be % alpha % val, vertical_wgt, &
249 ! vp % alpha(:,:,:,n), vv % alpha(:,:,:,n), be % alpha % mz, kds_int,kde_int, &
250 ! ims_int,ime_int, jms_int,jme_int, kms_int,kme_int, its_int,ite_int, &
251 ! jts_int,jte_int, kts_int,kte_int)
253 call da_transform_vvtovp_inv (grid, be % alpha % evec, be % alpha % val, vertical_wgt, &
254 vp % alpha(:,:,:,n), vv % alpha(:,:,:,n), be % alpha % mz, kte)
261 !-------------------------------------------------------------------
262 ! [3.0] Perform adjoint transform: vv_adj = L^{1/2} E^T vp_adj
263 !-------------------------------------------------------------------
265 if (be % v1 % mz > 0) then
266 call da_transform_vvtovp_adj (grid, be % v1 % evec, be % v1 % val, vertical_wgt, &
267 vp % v1, vv % v1, be % v1 % mz, kte)
270 if (be % v2 % mz > 0) then
271 call da_transform_vvtovp_adj (grid, be % v2 % evec, be % v2 % val, vertical_wgt, &
272 vp % v2, vv % v2, be % v2 % mz, kte)
275 if (be % v3 % mz > 0) then
276 call da_transform_vvtovp_adj (grid, be % v3 % evec, be % v3 % val, vertical_wgt, &
277 vp % v3, vv % v3, be % v3 % mz, kte)
280 if (be % v4 % mz > 0) then
281 call da_transform_vvtovp_adj (grid, be % v4 % evec, be % v4 % val, vertical_wgt, &
282 vp % v4, vv % v4, be % v4 % mz, kte)
285 if (be % v5 % mz > 0) then
287 vv % v5(its:ite,jts:jte,1) = vp % v5(its:ite,jts:jte,1)
289 call da_transform_vvtovp_adj (grid, be % v5 % evec, be % v5 % val, vertical_wgt, &
290 vp % v5, vv % v5, be % v5 % mz, kts)
294 if ( cloud_cv_options == 2 ) then
295 if (be % v6 % mz > 0) then
296 call da_transform_vvtovp_adj (grid, be % v6 % evec, be % v6 % val, vertical_wgt, &
297 vp % v6, vv % v6, be % v6 % mz, kte)
300 if (be % v7 % mz > 0) then
301 call da_transform_vvtovp_adj (grid, be % v7 % evec, be % v7 % val, vertical_wgt, &
302 vp % v7, vv % v7, be % v7 % mz, kte)
305 if (be % v8 % mz > 0) then
306 call da_transform_vvtovp_adj (grid, be % v8 % evec, be % v8 % val, vertical_wgt, &
307 vp % v8, vv % v8, be % v8 % mz, kte)
310 if (be % v9 % mz > 0) then
311 call da_transform_vvtovp_adj (grid, be % v9 % evec, be % v9 % val, vertical_wgt, &
312 vp % v9, vv % v9, be % v9 % mz, kte)
315 if (be % v10 % mz > 0) then
316 call da_transform_vvtovp_adj (grid, be % v10 % evec, be % v10 % val, vertical_wgt, &
317 vp % v10, vv % v10, be % v10 % mz, kte)
320 else if ( cloud_cv_options == 3 ) then
321 if (be % v6 % mz > 0) then
325 if (be % v7 % mz > 0) then
329 if (be % v8 % mz > 0) then
333 if (be % v9 % mz > 0) then
337 if (be % v10 % mz > 0) then
344 if (be % v11 % mz > 0) then
345 if ( cloud_cv_options == 2 ) then
346 call da_transform_vvtovp_adj (grid, be % v11 % evec, be % v11 % val, vertical_wgt, &
347 vp % v11, vv % v11, be % v11 % mz, kte)
348 else if ( cloud_cv_options == 3 ) then
354 if ( be % ne > 0 .and. be % alpha % mz > 0 ) then
356 if ( anal_type_hybrid_dual_res ) then
357 call da_transform_vvtovp_adj_dual_res (grid%intermediate_grid, be % alpha % evec, be % alpha % val, vertical_wgt, &
358 vp % alpha(:,:,:,n), vv % alpha(:,:,:,n), be % alpha % mz, kte_int)
360 call da_transform_vvtovp_adj (grid, be % alpha % evec, be % alpha % val, vertical_wgt, &
361 vp % alpha(:,:,:,n), vv % alpha(:,:,:,n), be % alpha % mz, kte_int)
368 call da_error(__FILE__,__LINE__, &
369 (/"Invalid da_vertical_transform option "//string/))
373 if (trace_use) call da_trace_exit("da_vertical_transform")
375 end subroutine da_vertical_transform