Merge remote-tracking branch 'origin/release-v4.5.2'
[WRF.git] / var / da / da_dynamics / da_balance_cycloterm_adj.inc
blob1b6ad0a64493d10978b4b889d3d5f5d2d11bc00e
1 subroutine da_balance_cycloterm_adj (rho, ub, vb, u, v, coefx, coefy, term_x, term_y)
3    !---------------------------------------------------------------------------
4    ! Purpose: Adjoint of da_balance_cycloterm
5    !---------------------------------------------------------------------------
7    implicit none
8    
9    real, intent(in)    :: rho(ims:ime,jms:jme)    ! Density.
10    real, intent(in)    :: ub(ims:ime,jms:jme)     ! Background u wind
11    real, intent(in)    :: vb(ims:ime,jms:jme)     ! Background u wind
12    real, intent(in)    :: term_x(ims:ime,jms:jme) ! x component of term
13    real, intent(in)    :: term_y(ims:ime,jms:jme) ! y component of term
14    real, intent(in)    :: coefx(ims:ime,jms:jme)
15    real, intent(in)    :: coefy(ims:ime,jms:jme)  ! Mulplicative coeff. 
17    real, intent(inout) :: u(ims:ime,jms:jme)      ! u wind increment
18    real, intent(inout) :: v(ims:ime,jms:jme)      ! v wind increment
20    integer              :: i, j                         ! Loop counters.
21    integer              :: is, ie                       ! 1st dim. end points.
22    integer              :: js, je                       ! 2nd dim. end points.
23    real                 :: data(ims:ime,jms:jme)        ! Work array.
25    real                 :: var, varb, uar
27    if (trace_use) call da_trace_entry("da_balance_cycloterm_adj")
29    !---------------------------------------------------------------------------
30    ! [1.0] Initialise:
31    !---------------------------------------------------------------------------
33    ! Computation to check for edge of domain:
34    is = its; ie = ite; js = jts; je = jte
35    if (.not. global .and. its == ids) is = ids+1
36    if (.not. global .and. ite == ide) ie = ide-1
37    if (jts == jds) js = jds+1
38    if (jte == jde) je = jde-1
40    !---------------------------------------------------------------------------
41    ! [3.0] Calculate term_y = rho M ( u'dv/dx + v'dv/dy + udv'/dx + vdv'/dy ):
42    !---------------------------------------------------------------------------
44    ! [3.7] Multiply by rho and add to term_y
46    data(its:ite,jts:jte) = rho(its:ite,jts:jte) * term_y(its:ite,jts:jte)
48    if (.NOT. global) then      
50       ! [3.6] Corner points:
52       if (its == ids .AND. jts == jds ) then
53          data(its,jts+1) = data(its,jts+1) + 0.5 * data(its,jts)
54          data(its+1,jts) = data(its+1,jts) + 0.5 * data(its,jts)
55       end if
57       if (ite == ide .AND. jts == jds ) then
58          data(ite-1,jts) = data(ite-1,jts) + 0.5 * data(ite,jts)
59          data(ite,jts+1) = data(ite,jts+1) + 0.5 * data(ite,jts)
60       end if
62       if (its == ids .AND. jte == jde ) then
63          data(its,jde-1) = data(its,jde-1) + 0.5 * data(its,jde)
64          data(its+1,jde) = data(its+1,jde) + 0.5 * data(its,jde)
65       end if
67       if (ite == ide .AND. jte == jde ) then 
68          data(ite-1,jte) = data(ite-1,jte) + 0.5 * data(ite,jte)
69          data(ite,jte-1) = data(ite,jte-1) + 0.5 * data(ite,jte)
70       end if
72       ! [3.5] Right boundaries:
74       if (jte == jde ) then
75          j = jte
77          do i = is, ie
78             varb = 3.0*vb(i,j)-4.0*vb(i,j-1)+vb(i,j-2)
80             var = coefy(i,j)* vb(i,j) * data(i,j)
81             uar = coefx(i,j)* data(i,j) * ub(i,j)
83             u(i,j)   = u(i,j) + coefx(i,j)*data(i,j) * ( vb(i+1,j) - vb(i-1,j) )
84             v(i,j)   = v(i,j) + coefy(i,j)*data(i,j) * varb
85             v(i+1,j) = v(i+1,j) + uar                             
86             v(i-1,j) = v(i-1,j) - uar                             
88             v(i,j) = v(i,j) + 3.0*var
89             v(i,j-1) = v(i,j-1) -4.0*var
90             v(i,j-2) = v(i,j-2) + var
91          end do
92       end if
94       ! [3.4] Left boundaries:
96       if (jts == jds ) then
97          j = jts
99          do i = is, ie
100             varb = -3.0*vb(i,j)+4.0*vb(i,j+1)-vb(i,j+2)
102             var = coefy(i,j)*vb(i,j) * data(i,j)
103             uar = coefx(i,j)*ub(i,j) * data(i,j)
105             v(i,j)   = v(i,j) + coefy(i,j)*data(i,j) * varb
106             v(i+1,j) = v(i+1,j) + uar                           
107             v(i-1,j) = v(i-1,j) - uar                           
109             v(i,j) = v(i,j) - 3.0*var
110             v(i,j+1) = v(i,j+1) +4.0*var
111             v(i,j+2) = v(i,j+2) - var
112          end do
113       end if
115       ! [3.3] Top boundaries:
117       if (ite == ide ) then
118          i = ite
120          do j = js, je
121             varb = 3.0*vb(i,j)-4.0*vb(i-1,j)+vb(i-2,j)
123             var = coefx(i,j)* ub(i,j) * data(i,j)
124             uar = coefy(i,j)* vb(i,j) * data(i,j)
126             u(i,j) = u(i,j) + coefx(i,j)*data(i,j) * varb
127             v(i,j) = v(i,j) + coefy(i,j)*data(i,j) * ( vb(i,j+1) - vb(i,j-1) )
128             v(i,j+1) = v(i,j+1) + uar                           
129             v(i,j-1) = v(i,j-1) - uar                           
131             v(i,j) = v(i,j) + 3.0*var
132             v(i-1,j) = v(i-1,j) -4.0**var
133             v(i-2,j) = v(i-2,j) + var
134          end do
135       end if
137       ! [3.2] Bottom boundaries:
139       if (its == ids ) then
140          i = its
142          do j = js, je
143             varb = -3.0*vb(i,j)+4.0*vb(i+1,j)-vb(i+2,j)
145             var = coefx(i,j)* ub(i,j) * data(i,j)
146             uar = coefy(i,j)* vb(i,j) * data(i,j)
148             u(i,j) = u(i,j) + coefx(i,j)*data(i,j) * varb
149             v(i,j) = v(i,j) + coefy(i,j)*data(i,j) * ( vb(i,j+1) - vb(i,j-1) )
150             v(i,j+1) = v(i,j+1) + uar                             
151             v(i,j-1) = v(i,j-1) - uar                             
153             v(i,j) = v(i,j) - 3.0*var
154             v(i+1,j) = v(i+1,j) +4.0**var
155             v(i+2,j) = v(i+2,j) - var
156          end do
157       end if
158    end if ! not global
159    
160    !  [3.1] Interior points:
162    do j = je, js, -1
163       do i = ie, is, -1
164          uar = coefx(i,j) * ub(i,j) * data(i,j)  
165          var = coefy(i,j) * vb(i,j) * data(i,j)  
167          u(i,j) = u(i,j) + coefx(i,j)*data(i,j)*( vb(i+1,j) - vb(i-1,j) ) 
168          v(i,j) = v(i,j) + coefy(i,j)*data(i,j)*( vb(i,j+1) - vb(i,j-1) ) 
169          v(i+1,j) = v(i+1,j) + uar                 
170          v(i-1,j) = v(i-1,j) - uar                 
171          v(i,j+1) = v(i,j+1) + var                  
172          v(i,j-1) = v(i,j-1) - var                  
173       end do
174    end do
175    
176    !---------------------------------------------------------------------------
177    ! [2.0] Calculate term_x = rho M ( u'du/dx + v'du/dy + udu'/dx + vdu'/dy ):
178    !---------------------------------------------------------------------------
180    ! [2.7] Multiply by rho and add to term_x:
182    data(its:ite,jts:jte) = rho(its:ite,jts:jte) * term_x(its:ite,jts:jte)
184    if( .NOT. global) then
185       ! [2.6] Corner points:
187       if (its == ids .AND. jts == jds ) then
188          data(its,jts+1) = data(its,jts+1) + 0.5 * data(its,jts)
189          data(its+1,jts) = data(its+1,jts) + 0.5 * data(its,jts)
190       end if
192       if (ite == ide .AND. jts == jds ) then
193          data(ite-1,jts) = data(ite-1,jts) + 0.5 * data(ite,jts)
194          data(ite,jts+1) = data(ite,jts+1) + 0.5 * data(ite,jts)
195       end if
197       if (its == ids .AND. jte == jde ) then
198          data(its,jde-1) = data(its,jde-1) + 0.5 * data(its,jde)
199          data(its+1,jde) = data(its+1,jde) + 0.5 * data(its,jde)
200       end if
202       if (ite == ide .AND. jte == jde ) then 
203          data(ite-1,jte) = data(ite-1,jte) + 0.5 * data(ite,jte)
204          data(ite,jte-1) = data(ite,jte-1) + 0.5 * data(ite,jte)
205       end if
207       ! [2.5] Right boundaries:
209       if (jte == jde ) then
210          j = jte
212          do i = is, ie
213             varb = 3.0*ub(i,j)-4.0*ub(i,j-1)+ub(i,j-2)
214             var  = coefy(i,j) * vb(i,j) * data(i,j)
215             uar  = coefx(i,j) * ub(i,j) * data(i,j)
217             u(i+1,j) = u(i+1,j) + uar                   
218             u(i-1,j) = u(i-1,j) - uar                   
219             v(i,j) = v(i,j) + coefy(i,j)*data(i,j) * varb
220             u(i,j) = u(i,j) + coefx(i,j)*data(i,j) * ( ub(i+1,j) - ub(i-1,j) )
222             u(i,j) = u(i,j) + 3.0*var
223             u(i,j-1) = u(i,j-1) -4.0*var
224             u(i,j-2) = u(i,j-2) + var
225          end do
226       end if
228       ! [2.4] Left boundaries:
230       if (jts == jds ) then
231          j = jts
233          do i = is, ie
234             varb = -3.0*ub(i,j)+4.0*ub(i,j+1)-ub(i,j+2)
235             var = coefy(i,j)*vb(i,j) * data(i,j)
236             uar = coefx(i,j)*ub(i,j) * data(i,j)
238             u(i+1,j) = u(i+1,j) + uar                 
239             u(i-1,j) = u(i-1,j) - uar                 
240             v(i,j) = v(i,j) + coefy(i,j)*data(i,j) * varb
241             u(i,j) = u(i,j) + coefx(i,j)*data(i,j) * ( ub(i+1,j) - ub(i-1,j) )
243             u(i,j) = u(i,j) - 3.0*var
244             u(i,j+1) = u(i,j+1) +4.0*var
245             u(i,j+2) = u(i,j+2) - var
246          end do
247       end if
249       ! [2.3] Top boundaries:
251       if (ite == ide ) then
252          i = ite
254          do j = js, je
255             varb = 3.0*ub(i,j)-4.0*ub(i-1,j)+ub(i-2,j)
256             var = coefx(i,j)*ub(i,j) * data(i,j)
257             uar = coefy(i,j)*vb(i,j) * data(i,j)
259             u(i,j+1) = u(i,j+1) + uar                  
260             u(i,j-1) = u(i,j-1) - uar                  
261             v(i,j) = v(i,j) + coefy(i,j)*data(i,j) * ( ub(i,j+1) - ub(i,j-1) )
262             u(i,j) = u(i,j) + coefx(i,j)*data(i,j) * varb
264             u(i,j)   = u(i,j) + 3.0*var
265             u(i-1,j) =  u(i-1,j) - 4.0*var
266             u(i-2,j) =  u(i-2,j) + var
267          end do
268       end if
270       ! [2.2] Bottom boundaries:
272       if (its == ids ) then
273          i = its
275          do j = js, je
276             varb = -3.0*ub(i,j)+4.0*ub(i+1,j)-ub(i+2,j)
277             var = coefy(i,j)*ub(i,j) * data(i,j)
278             uar = coefy(i,j)*vb(i,j) * data(i,j)
280             u(i,j+1) = u(i,j+1) + uar                  
281             u(i,j-1) = u(i,j-1) - uar                  
282             v(i,j) = v(i,j) + coefy(i,j)*data(i,j) * ( ub(i,j+1) - ub(i,j-1) )
283             u(i,j) = u(i,j) + coefx(i,j)*data(i,j) * varb
285             u(i,j) = u(i,j) - 3.0*var
286             u(i+1,j) =  u(i+1,j) + 4.0*var
287             u(i+2,j) =  u(i+2,j) - var
288          end do
289       end if
290    end if ! not global
292    ! [2.1] Interior points:
294    do j = je, js, -1
295       do i = ie, is, -1
296          uar = coefx(i,j) * ub(i,j) * data(i,j)
297          var = coefy(i,j) * vb(i,j) * data(i,j)
299          u(i,j) = u(i,j) + coefx(i,j)*( ub(i+1,j) - ub(i-1,j) ) * data(i,j)
300          v(i,j) = v(i,j) + coefy(i,j)*( ub(i,j+1) - ub(i,j-1) ) * data(i,j)
301          u(i+1,j) = u(i+1,j) + uar                 
302          u(i-1,j) = u(i-1,j) - uar                 
303          u(i,j+1) = u(i,j+1) + var                   
304          u(i,j-1) = u(i,j-1) - var  
305       end do
306    end do
308    if (trace_use) call da_trace_exit("da_balance_cycloterm_adj")
310 end subroutine da_balance_cycloterm_adj