1 subroutine da_balance_cycloterm (xb, k, term_x, term_y)
3 !---------------------------------------------------------------------------
4 ! Purpose: Calculates cyclostrophic term in balance equation.
6 ! Method: Term is rho (u.grad) u on a single level.
7 !---------------------------------------------------------------------------
11 type(xb_type), intent(in) :: xb ! First guess structure.
12 integer, intent(in) :: k ! Model level.
13 real, intent(inout) :: term_x(:,:) ! x component of term.
14 real, intent(inout) :: term_y(:,:) ! y component of term.
16 integer :: i, j ! Loop counters.
17 integer :: is, ie ! 1st dim. end points.
18 integer :: js, je ! 2nd dim. end points.
20 real :: data(ims:ime,jms:jme) ! Temporary storage.
24 if (trace_use) call da_trace_entry("da_balance_cycloterm")
26 !---------------------------------------------------------------------------
28 !---------------------------------------------------------------------------
30 ! Computation to check for edge of domain:
31 is = its; ie = ite; js = jts; je = jte
32 if (.not. global .and. its==ids) is = ids+1
33 if (.not. global .and. ite==ide) ie = ide-1
34 if (jts==jds) js = jds+1
35 if (jte==jde) je = jde-1
37 !---------------------------------------------------------------------------
38 ! [2.0] Calculate term_x = rho M (u.du/dx + v.du/dy):
39 !---------------------------------------------------------------------------
41 ! [2.1] Interior points:
45 data(i,j) = xb%u(i,j,k) * xb%coefx(i,j)*(xb%u(i+1,j,k) - &
46 xb%u(i-1,j,k)) + xb%v(i,j,k) * xb%coefy(i,j)*(xb%u(i,j+1,k) - &
51 if (.NOT. global) then ! For global only interior points
53 ! [2.2] Bottom boundaries:
59 varb = -3.0*xb%u(i,j,k)+4.0*xb%u(i+1,j,k)-xb%u(i+2,j,k)
61 data(i,j) = xb%u(i,j,k) * xb%coefx(i,j) * varb + &
62 xb%v(i,j,k) * xb%coefy(i,j) * (xb%u(i,j+1,k) - xb%u(i,j-1,k))
66 ! [2.3] Top boundaries:
72 varb = 3.0*xb%u(i,j,k)-4.0*xb%u(i-1,j,k)+xb%u(i-2,j,k)
74 data(i,j) = xb%u(i,j,k) * xb%coefx(i,j) * varb + &
75 xb%v(i,j,k) * xb%coefy(i,j) * (xb%u(i,j+1,k) - xb%u(i,j-1,k))
79 ! [2.4] Left boundaries:
85 varb = -3.0*xb%u(i,j,k)+4.0*xb%u(i,j+1,k)-xb%u(i,j+2,k)
87 data(i,j) = xb%u(i,j,k) * xb%coefx(i,j) * (xb%u(i+1,j,k) - &
88 xb%u(i-1,j,k)) + xb%v(i,j,k) * xb%coefy(i,j) * varb
92 ! [2.5] Right boundaries:
98 varb = 3.0*xb%u(i,j,k)-4.0*xb%u(i,j-1,k)+xb%u(i,j-2,k)
100 data(i,j) = xb%u(i,j,k) * xb%coefx(i,j) * (xb%u(i+1,j,k) - &
101 xb%u(i-1,j,k)) + xb%v(i,j,k) * xb%coefy(i,j) * varb
105 ! [2.6] Corner points:
107 if (its==ids .AND. jts==jds) then
108 data(its,jts) = 0.5 * (data(its,jts+1) + data(its+1,jts))
111 if (ite==ide .AND. jts==jds) then
112 data(ite,jts) = 0.5 * (data(ite-1,jts) + data(ite,jts+1))
115 if (its==ids .AND. jte==jde) then
116 data(its,jde) = 0.5 * (data(its,jde-1) + data(its+1,jde))
119 if (ite==ide .AND. jte==jde) then
120 data(ite,jte) = 0.5 * (data(ite-1,jte) + data(ite,jte-1))
124 ! [2.7] Multiply by rho and add to term_x:
126 term_x(its:ite,jts:jte) = xb%rho(its:ite,jts:jte,k)*data(its:ite,jts:jte) + term_x(its:ite,jts:jte)
128 !---------------------------------------------------------------------------
129 ! [3.0] Calculate term_y = rho M (u.dv/dx + v.dv/dy):
130 !---------------------------------------------------------------------------
132 ! [3.1] Interior points:
136 data(i,j) = xb%u(i,j,k) * xb%coefx(i,j)*(xb%v(i+1,j,k) - xb%v(i-1,j,k)) + &
137 xb%v(i,j,k) * xb%coefy(i,j)*(xb%v(i,j+1,k) - xb%v(i,j-1,k))
142 if (.NOT. global) then ! For global only interior points
144 ! [3.2] Bottom boundaries:
150 varb = -3.0*xb%v(i,j,k)+4.0*xb%v(i+1,j,k)-xb%v(i+2,j,k)
152 data(i,j) = xb%u(i,j,k) * xb%coefx(i,j)* varb + &
153 xb%v(i,j,k) * xb%coefy(i,j)* (xb%v(i,j+1,k) - xb%v(i,j-1,k))
157 ! [3.3] Top boundaries:
163 varb = 3.0*xb%v(i,j,k)-4.0*xb%v(i-1,j,k)+xb%v(i-2,j,k)
165 data(i,j) = xb%u(i,j,k) * xb%coefx(i,j)* varb + &
166 xb%v(i,j,k) * xb%coefy(i,j)* (xb%v(i,j+1,k) - xb%v(i,j-1,k))
170 ! [3.4] Left boundaries:
176 varb = -3.0*xb%v(i,j,k)+4.0*xb%v(i,j+1,k)-xb%v(i,j+2,k)
178 data(i,j) = xb%u(i,j,k) * xb%coefx(i,j)* (xb%v(i+1,j,k) - xb%v(i-1,j,k)) + &
179 xb%v(i,j,k) * xb%coefy(i,j)* varb
183 ! [3.5] Right boundaries:
189 varb = 3.0*xb%v(i,j,k)-4.0*xb%v(i,j+1,k)+xb%v(i,j+2,k)
191 data(i,j) = xb%u(i,j,k) * xb%coefx(i,j)* (xb%v(i+1,j,k) - xb%v(i-1,j,k)) + &
192 xb%v(i,j,k) * xb%coefy(i,j)* varb
196 ! [3.6] Corner points:
198 if (its==ids .AND. jts==jds) then
199 data(its,jts) = 0.5 * (data(its,jts+1) + data(its+1,jts))
202 if (ite==ide .AND. jts==jds) then
203 data(ite,jts) = 0.5 * (data(ite-1,jts) + data(ite,jts+1))
206 if (its==ids .AND. jte==jde) then
207 data(its,jde) = 0.5 * (data(its,jde-1) + data(its+1,jde))
210 if (ite==ide .AND. jte==jde) then
211 data(ite,jte) = 0.5 * (data(ite-1,jte) + data(ite,jte-1))
215 ! [3.7] Multiply by rho and add to term_y
217 term_y(its:ite,jts:jte)=xb%rho(its:ite,jts:jte,k)* data(its:ite,jts:jte) + &
218 term_y(its:ite,jts:jte)
220 if (trace_use) call da_trace_exit("da_balance_cycloterm")
222 end subroutine da_balance_cycloterm