<HTML> <BODY BGCOLOR=#ccccdd LINK=#0000aa VLINK=#0000ff ALINK=#ff0000 ><BASE TARGET="bottom_target"><PRE>
<A NAME='DA_WPEC_CONSTRAINT_ADJ'><A href='../../html_code/dynamics/da_wpec_constraint_adj.inc.html#DA_WPEC_CONSTRAINT_ADJ' TARGET='top_target'><IMG SRC="../../gif/bar_red.gif" border=0></A>

subroutine da_wpec_constraint_adj(grid, xbx) 1,5

   !---------------------------------------------------------------------------
   ! Purpose: Calculates ADM of balance equation G(x)
   !---------------------------------------------------------------------------

   implicit none

   type(domain), intent(inout)               :: grid

   type (xbx_type),intent(in) :: xbx              ! Header &amp; non-gridded vars.

   real :: p(ims:ime,jms:jme,kms:kme) ! pressure increment.
   real :: geoh(ims:ime,jms:jme,kms:kme) ! geopotential height increment.
   real :: u(ims:ime,jms:jme,kms:kme) ! u wind comp. (dot pts)
   real :: v(ims:ime,jms:jme,kms:kme) ! v wind comp. (dot pts)

   integer             :: i, j, k          ! Loop counters.
   integer             :: is, ie           ! 1st dim. end points.
   integer             :: js, je           ! 2nd dim. end points.

   real, dimension(ims:ime,jms:jme) :: coefx, &amp;   ! Multiplicative coefficient.
                                       coefy, &amp;   ! Multiplicative coefficient.
                                       term_x, &amp;  ! Balance eqn x term
                                       term_y     ! Balance eqn y term
   real    :: phi_b_x(ims:ime,jms:jme) ! Balance eqn x term
   real    :: phi_b_y(ims:ime,jms:jme) ! Balance eqn y term

   real                 :: data(ims:ime,jms:jme)        ! Work array.
   real                 :: var, uar

   if (trace_use) call da_trace_entry("da_wpec_constraint_adj")

   !---------------------------------------------------------------------------
   ! [1.0] Initialise:
   !---------------------------------------------------------------------------

   is = its; ie = ite; js = jts; je = jte
   if (.not. global .and. its == ids) is = ids+1
   if (.not. global .and. ite == ide) ie = ide-1
   if (jts == jds ) js = jds+1
   if (jte == jde ) je = jde-1

   if (fg_format == fg_format_kma_global) then
      coefx = grid%xb%coefx
      coefy = grid%xb%coefy
   else if (fg_format == fg_format_wrf_arw_regional) then
      coefx = grid%xb%coefx
      coefy = grid%xb%coefy
   else if (fg_format == fg_format_wrf_arw_global) then
      write (unit=message(1),fmt='(A,I3)') ' needs work for fg_format  = ',fg_format
      call da_error(__FILE__,__LINE__,message(1:1))
   else if (fg_format == fg_format_wrf_nmm_regional) then
      write (unit=message(1),fmt='(A,I3)') ' needs work for fg_format  = ',fg_format
      call da_error(__FILE__,__LINE__,message(1:1))
   else
      write (unit=message(1),fmt='(A,I3)') ' Wrong FG_FORMAT = ',fg_format
      call da_error(__FILE__,__LINE__,message(1:1))
   end if
   
   u       = 0.0
   v       = 0.0
   p       = 0.0
   geoh    = 0.0

   do k = kts, kte

      term_x = 0.0
      term_y = 0.0
      phi_b_x = 0.0
      phi_b_y = 0.0

      !---------------------------------------------------------------------------
      ! [2.0] Solve Grad_p for balance eqn
      !---------------------------------------------------------------------------

      phi_b_x = grid%xa%grad_p_x(:,:,k)
      phi_b_y = grid%xa%grad_p_y(:,:,k)
      term_x = grid%xa%grad_p_x(:,:,k)
      term_y = grid%xa%grad_p_y(:,:,k)

      !---------------------------------------------------------------------------
      ! [3.0] Calculate RHS of balance equation in gridpt space
      !---------------------------------------------------------------------------

      ! [3.1] Include phi_b terms in balance eqn

      do j = je, js, -1
         do i = ie, is, -1

            p(i+1,j,k) = p(i+1,j,k) + coefx(i,j) * phi_b_x(i,j)
            p(i-1,j,k) = p(i-1,j,k) - coefx(i,j) * phi_b_x(i,j)
            p(i,j+1,k) = p(i,j+1,k) + coefy(i,j) * phi_b_y(i,j)
            p(i,j-1,k) = p(i,j-1,k) - coefy(i,j) * phi_b_y(i,j)

            geoh(i+1,j,k) = geoh(i+1,j,k) + coefx(i,j) * phi_b_x(i,j) * grid%xb % rho(i,j,k)
            geoh(i-1,j,k) = geoh(i-1,j,k) - coefx(i,j) * phi_b_x(i,j) * grid%xb % rho(i,j,k)
            geoh(i,j+1,k) = geoh(i,j+1,k) + coefy(i,j) * phi_b_y(i,j) * grid%xb % rho(i,j,k)
            geoh(i,j-1,k) = geoh(i,j-1,k) - coefy(i,j) * phi_b_y(i,j) * grid%xb % rho(i,j,k)

         end do
      end do

      ! [3.2] Include cyclostrophic terms in balance eqn if requested:

      if (balance_type == balance_cyc .OR. balance_type == balance_geocyc ) then

         ! [3.2.1] Calculate adjoint of term_y = rho M ( u'dv/dx + v'dv/dy + udv'/dx + vdv'/dy ):
         data = grid%xb%rho(:,:,k) * term_y

         do j = je, js, -1
            do i = ie, is, -1
               uar = coefx(i,j) * grid%xb%u(i,j,k) * data(i,j)
               var = coefy(i,j) * grid%xb%v(i,j,k) * data(i,j)

                u(i,j,k) = u(i,j,k) + coefx(i,j)*data(i,j)*( grid%xb%v(i+1,j,k) - grid%xb%v(i-1,j,k) )
                v(i,j,k) = v(i,j,k) + coefy(i,j)*data(i,j)*( grid%xb%v(i,j+1,k) - grid%xb%v(i,j-1,k) )
                v(i+1,j,k) = v(i+1,j,k) + uar
                v(i-1,j,k) = v(i-1,j,k) - uar
                v(i,j+1,k) = v(i,j+1,k) + var
                v(i,j-1,k) = v(i,j-1,k) - var
            end do
         end do

         ! [3.2.2] Calculate adjoint of term_x = rho M ( u'du/dx + v'du/dy + udu'/dx + vdu'/dy ):
         data = grid%xb%rho(:,:,k) * term_x

         do j = je, js, -1
            do i = ie, is, -1
               uar = coefx(i,j) * grid%xb%u(i,j,k) * data(i,j)
               var = coefy(i,j) * grid%xb%v(i,j,k) * data(i,j)

                u(i,j,k) = u(i,j,k) + coefx(i,j)*( grid%xb%u(i+1,j,k) - grid%xb%u(i-1,j,k) ) * data(i,j)
                v(i,j,k) = v(i,j,k) + coefy(i,j)*( grid%xb%u(i,j+1,k) - grid%xb%u(i,j-1,k) ) * data(i,j)
                u(i+1,j,k) = u(i+1,j,k) + uar
                u(i-1,j,k) = u(i-1,j,k) - uar
                u(i,j+1,k) = u(i,j+1,k) + var
                u(i,j-1,k) = u(i,j-1,k) - var
            end do
         end do
      end if

      
      ! [3.3] Calculate geostrophic terms in balance eqn:
 
      if (balance_type == balance_geo .OR. balance_type == balance_geocyc ) then
         ! [3.3.1] Calculate term_y = f rho u~:
         u(:,:,k) = u(:,:,k) + grid%xb%rho(:,:,k) * grid%xb%cori * term_y

         ! [3.3.2] Calculate term_x = -f rho v~:
         v(:,:,k) = v(:,:,k) - grid%xb%rho(:,:,k) * grid%xb%cori * term_x

      end if

   end do

   !---------------------------------------------------------------------------
   ! [4.0] Store results in grid%xa structure
   !---------------------------------------------------------------------------


   grid%xa%u=u
   grid%xa%v=v
   grid%xa%p=p
   grid%xa%geoh=geoh


   if (trace_use) call da_trace_exit("da_wpec_constraint_adj")

end subroutine da_wpec_constraint_adj