1 subroutine da_transform_through_rf(grid,mz, rf_alpha, val,field)
3 !---------------------------------------------------------------------------
4 ! Purpose: Control variable transform through the recursive filter.
6 ! Method: 1) Transform to nondimensional v_hat space.
7 ! 2) Perform recursive filter in non-dimensional space (ds = 1).
8 ! 3) Scale recursive filter output.
9 ! 4) Transform filtered field to dimensional space.
10 ! 5) Optionally scale by background error.
11 !---------------------------------------------------------------------------
15 type(domain), intent(inout) :: grid
16 integer, intent(in) :: mz ! Vertical truncation.
17 real, intent(in) :: rf_alpha(mz) ! RF scale parameter.
18 real, intent(in) :: val(jds:jde,mz) ! Error standard deviation.
19 real, intent(inout) :: field(ims:ime,jms:jme,kms:kme) ! Field to be transformed.
21 integer :: rf_passes_over_two ! rf_passes / 2
22 integer :: i, j, m, n, pass, ij ! Loop counters.
23 real :: p_x(ims:ime,jms:jme)! sqrt(Grid box area).
24 real :: val_j(grid%xp%jtsy:grid%xp%jtey)
25 real :: val_i(grid%xp%itsx:grid%xp%itex)
27 !----------------------------------------------------------------------
29 !----------------------------------------------------------------------
31 if (trace_use_dull) call da_trace_entry("da_transform_through_rf")
33 rf_passes_over_two = rf_passes / 2
36 !$OMP PRIVATE ( ij, i, j )
37 do ij = 1 , grid%num_tiles
38 ! [1.1] Define inner product (square root of grid box area):
39 do j = grid%j_start(ij), grid%j_end(ij)
41 p_x(i,j) = sqrt(grid%xb%grid_box_area(i,j))
48 !$OMP PRIVATE ( ij, m, i, j )
49 do ij = 1 , grid%num_tiles
51 do j = grid%j_start(ij), grid%j_end(ij)
53 grid%xp%v1z(i,j,m) = 0.0
60 ! [1.2] Transform to nondimensional v_hat space:
63 !$OMP PRIVATE ( ij, m, i, j )
64 do ij = 1 , grid%num_tiles
66 do j = grid%j_start(ij), grid%j_end(ij)
68 grid%xp%v1z(i,j,m) = field(i,j,m) / p_x(i,j)
75 !-------------------------------------------------------------------------
76 ! [2.0]: Perform 1D recursive filter in x-direction:
77 !-------------------------------------------------------------------------
79 ! [2.1] Apply (i',j',k -> i,j',k') (grid%xp%v1z -> grid%xp%v1x)
80 ! convert from vertical column to x-stripe
82 call da_transpose_z2x (grid)
84 ! [2.2] Apply 1D filter in x direction:
86 n = grid%xp%itex - grid%xp%itsx + 1
88 !$OMP PRIVATE ( m, j, pass, val_i, i )
89 do m = grid%xp%ktsx, min(grid%xp%ktex,mz)
90 do j = grid%xp%jtsx, grid%xp%jtex
91 do i = grid%xp%itsx, grid%xp%itex
92 val_i(i) = grid%xp%v1x(i,j,m)
94 do pass = 1, rf_passes_over_two
95 call da_recursive_filter_1d(pass, rf_alpha(m), val_i, n)
97 do i = grid%xp%itsx, grid%xp%itex
98 grid%xp%v1x(i,j,m) = val_i(i)
102 !$OMP END PARALLEL DO
104 !-------------------------------------------------------------------------
105 ! [3.0]: Perform 1D recursive filter in y-direction:
106 !-------------------------------------------------------------------------
108 ! [3.1] Apply (i, j' ,k' -> i', j ,k') (grid%xp%v1x -> grid%xp%v1y)
109 ! convert from vertical column to y-stripe
111 call da_transpose_x2y (grid)
113 ! [3.2] Apply 1D filter in y direction:
115 n = grid%xp%jtey - grid%xp%jtsy + 1
117 !$OMP PRIVATE ( m, i, pass, val_j, j )
118 do m = grid%xp%ktsy, min(grid%xp%ktey,mz)
119 do i = grid%xp%itsy, grid%xp%itey
120 do j = grid%xp%jtsy, grid%xp%jtey
121 val_j(j) = grid%xp%v1y(i,j,m)
123 do pass = 1, rf_passes_over_two
124 call da_recursive_filter_1d(pass, rf_alpha(m), val_j, n)
126 do j = grid%xp%jtsy, grid%xp%jtey
127 grid%xp%v1y(i,j,m) = val_j(j)
131 !$OMP END PARALLEL DO
133 !-------------------------------------------------------------------------
134 ! [4.0]: Perform 1D recursive filter in y-direction:
135 !-------------------------------------------------------------------------
137 ! [4.1] Apply (i',j,k' -> i',j',k) (grid%xp%v1y -> grid%xp%v1z)
138 ! convert from y-stripe to vertical column.
140 call da_transpose_y2z (grid)
142 ! [4.2] Transform filtered field to dimensional space:
145 !$OMP PRIVATE ( ij, m, i, j )
146 do ij = 1 , grid%num_tiles
148 do j = grid%j_start(ij), grid%j_end(ij)
151 field(i,j,m) = grid%xp%v1z(i,j,m) * p_x(i,j)
156 !$OMP END PARALLEL DO
158 ! [4.3] Optionally scale by background error:
160 ! be_s % val = Gridpoint standard deviation - only required for
161 ! vert_corr = vert_corr_1 as scaling is performed in vertical transform
162 ! for vert_corr = vert_corr_2:
164 if (vert_corr == vert_corr_1) then
167 field(i,jts:jte,m) = field(i,jts:jte,m) * val(jts:jte,m)
172 if (trace_use_dull) call da_trace_exit("da_transform_through_rf")
174 end subroutine da_transform_through_rf