<p><b>ringler@lanl.gov</b> 2011-06-10 12:44:09 -0600 (Fri, 10 Jun 2011)</p><p><br>
add drag term to vorticity equation<br>
</p><hr noshade><pre><font color="gray">Modified: branches/pv_based_swm/mpas/src/core_pvsw/Registry
===================================================================
--- branches/pv_based_swm/mpas/src/core_pvsw/Registry        2011-06-10 17:15:11 UTC (rev 895)
+++ branches/pv_based_swm/mpas/src/core_pvsw/Registry        2011-06-10 18:44:09 UTC (rev 896)
@@ -21,6 +21,7 @@
 namelist real      sw_model config_apvm_upwinding       0.5
 namelist real      sw_model config_alpha                0.0
 namelist logical   sw_model config_alpha_closure       false
+namelist real      sw_model config_dragCoefficient      0.001
 namelist character io       config_input_name          grid.nc
 namelist character io       config_output_name         output.nc
 namelist character io       config_restart_name        restart.nc
@@ -148,6 +149,7 @@
 
 # Diagnostic fields: only written to output
 var persistent real    v ( nVertLevels nEdges Time ) 2 - v state - -
+var persistent real    gradKE ( nVertLevels nEdges Time ) 2 o gradKE state - -
 var persistent real    divergence ( nVertLevels nCells Time ) 2 - divergence state - -
 var persistent real    h_edge ( nVertLevels nEdges Time ) 2 - h_edge state - -
 var persistent real    ke ( nVertLevels nCells Time ) 2 o ke state - -
@@ -156,9 +158,13 @@
 var persistent real    uReconstructZ ( nVertLevels nCells Time ) 2 - uReconstructZ state - -
 var persistent real    uReconstructZonal ( nVertLevels nCells Time ) 2 o uReconstructZonal state - -
 var persistent real    uReconstructMeridional ( nVertLevels nCells Time ) 2 o uReconstructMeridional state - -
+var persistent real    gradKeReconstructX ( nVertLevels nCells Time ) 2 o gradKeReconstructX state - -
+var persistent real    gradKeReconstructY ( nVertLevels nCells Time ) 2 o gradKeReconstructY state - -
+var persistent real    gradKeReconstructZ ( nVertLevels nCells Time ) 2 o gradKeReconstructZ state - -
+var persistent real    gradKeReconstructZonal ( nVertLevels nCells Time ) 2 o gradKeReconstructZonal state - -
+var persistent real    gradKeReconstructMerid ( nVertLevels nCells Time ) 2 o gradKeReconstructMerid state - -
 var persistent real    dvordt ( nVertLevels nCells Time ) 2 o dvordt state - -
 var persistent real    pv_advection ( nVertLevels nCells Time ) 2 o pv_advection state - -
 var persistent real    pv_dissipation ( nVertLevels nCells Time ) 2 o pv_dissipation state - -
 var persistent real    pv_forcing ( nVertLevels nCells Time ) 2 o pv_forcing state - -
 var persistent real    pv_drag ( nVertLevels nCells Time ) 2 o pv_drag state - -
-

Modified: branches/pv_based_swm/mpas/src/core_pvsw/module_time_integration.F
===================================================================
--- branches/pv_based_swm/mpas/src/core_pvsw/module_time_integration.F        2011-06-10 17:15:11 UTC (rev 895)
+++ branches/pv_based_swm/mpas/src/core_pvsw/module_time_integration.F        2011-06-10 18:44:09 UTC (rev 896)
@@ -225,6 +225,7 @@
                  end do
               end do
               call compute_solve_diagnostics(dt, provis, block % mesh)
+              call compute_drag(provis, block % mesh)
               block =&gt; block % next
            end do
         end if
@@ -310,8 +311,10 @@
       do while (associated(block))
 
          call compute_solve_diagnostics(dt, block % state % time_levs(2) % state, block % mesh)
+         call compute_drag(provis, block % mesh)
 
          call reconstruct(block % state % time_levs(2) % state, block % mesh)
+         call reconstructGradKE(block % state % time_levs(2) % state, block % mesh)
 
          block =&gt; block % next
       end do
@@ -731,6 +734,75 @@
    end subroutine compute_scalar_tend
 
 
+   subroutine compute_drag(s, grid)
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   ! drag on RHS of PV equation
+   !
+   ! Input: grid - grid metadata
+   !
+   ! Output: s - computed diagnostics
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+      implicit none
+
+      type (state_type), intent(inout) :: s
+      type (mesh_type), intent(in) :: grid
+
+      real (kind=RKIND), pointer, dimension(:) :: xCell, yCell, zCell
+      real (kind=RKIND), pointer, dimension(:,:) :: pv_drag, vor, ke, h
+      real (kind=RKIND), pointer, dimension(:,:) :: ux, uy, uz, gx, gy, gz
+      real (kind=RKIND) :: p(3), q(3), t(3), r
+      integer :: iCell, k
+
+      xCell       =&gt; grid % xCell % array
+      yCell       =&gt; grid % yCell % array
+      zCell       =&gt; grid % zCell % array
+
+      pv_drag     =&gt; s % pv_drag % array
+      vor         =&gt; s % vor % array
+      ke          =&gt; s % ke % array
+      h           =&gt; s % h % array
+
+      ux          =&gt; s % uReconstructX % array
+      uy          =&gt; s % uReconstructY % array
+      uz          =&gt; s % uReconstructZ % array
+
+      gx          =&gt; s % gradKeReconstructX % array
+      gy          =&gt; s % gradKeReconstructY % array
+      gz          =&gt; s % gradKeReconstructZ % array
+
+
+      do iCell = 1,grid%nCells
+       do k=1,grid % nVertLevels
+         pv_drag(k,iCell) = -config_dragCoefficient * sqrt(2.0*ke(k,iCell)) * vor(k,iCell) / h(k,iCell)
+       enddo
+      enddo
+
+      do iCell = 1,grid%nCells
+       do k=1,grid % nVertLevels
+        p(1) = gx(k,iCell); p(2) = gy(k,iCell); p(3) = gz(k,iCell)
+        q(1) = ux(k,iCell); q(2) = uy(k,iCell); q(3) = uz(k,iCell)
+        call cross_product_in_R3(p,q,t)
+        r = xCell(iCell)*t(1) + yCell(iCell)*t(2) + zCell(iCell)*t(3)
+        pv_drag(k,iCell) = pv_drag(k,iCell) - config_dragCoefficient * r / h(k,iCell)
+       enddo
+      enddo
+
+   contains
+
+   subroutine cross_product_in_R3(p_1,p_2,p_out)
+     real (kind=RKIND), intent(in) :: p_1 (3), p_2 (3)
+     real (kind=RKIND), intent(out) :: p_out (3)
+
+     p_out(1) = p_1(2)*p_2(3)-p_1(3)*p_2(2)
+     p_out(2) = p_1(3)*p_2(1)-p_1(1)*p_2(3)
+     p_out(3) = p_1(1)*p_2(2)-p_1(2)*p_2(1)
+   end subroutine cross_product_in_R3
+
+
+   end subroutine compute_drag
+
+
    subroutine compute_solve_diagnostics(dt, s, grid)
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
    ! Compute diagnostic fields used in the tendency computations
@@ -753,7 +825,7 @@
       integer :: nCells, nEdges, nVertices, nVertLevels
       real (kind=RKIND), dimension(:), pointer :: h_s, dvEdge, dcEdge, areaCell
       real (kind=RKIND), dimension(:,:), pointer :: weightsOnEdge, h_edge, h, u, v, tend_h, tend_u, &amp;
-                                                    ke,  divergence
+                                                    ke,  divergence, gradKE
       integer, dimension(:,:), pointer :: cellsOnEdge, edgesOnCell, edgesOnEdge, boundaryEdge, boundaryCell
       integer, dimension(:), pointer :: nEdgesOnCell, nEdgesOnEdge
       real (kind=RKIND) :: r
@@ -769,6 +841,7 @@
       tend_u      =&gt; s % u % array
       divergence  =&gt; s % divergence % array
       ke          =&gt; s % ke % array
+      gradKE      =&gt; s % gradKE % array
 
       weightsOnEdge     =&gt; grid % weightsOnEdge % array
       cellsOnEdge       =&gt; grid % cellsOnEdge % array
@@ -849,6 +922,18 @@
       end do
 
       !
+      ! Compute kinetic energy at every edge
+      !
+      gradKE(:,:) = 0.0
+      do iEdge=1,nEdges
+         cell1 = cellsOnEdge(1,iEdge)
+         cell2 = cellsOnEdge(2,iEdge)
+         do k=1,nVertLevels
+           gradKE(k,iEdge) = (ke(k,cell2) - ke(k,cell1)) / dcEdge(iEdge)
+         enddo
+      enddo
+
+      !
       ! Compute v (tangential) velocities
       !
       v(:,:) = 0.0

Modified: branches/pv_based_swm/mpas/src/operators/module_vector_reconstruction.F
===================================================================
--- branches/pv_based_swm/mpas/src/operators/module_vector_reconstruction.F        2011-06-10 17:15:11 UTC (rev 895)
+++ branches/pv_based_swm/mpas/src/operators/module_vector_reconstruction.F        2011-06-10 18:44:09 UTC (rev 896)
@@ -7,7 +7,7 @@
 
   implicit none
 
-  public :: init_reconstruct, reconstruct
+  public :: init_reconstruct, reconstruct, reconstructGradKE
 
   contains
 
@@ -200,4 +200,93 @@
 
   end subroutine reconstruct
 
+  subroutine reconstructGradKE(state, grid)
+  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+  ! Purpose: reconstruct gradient of KE vector field at cell centers based on radial basis functions
+  !
+  ! Input: grid meta data and vector component data residing at cell edges
+  !
+  ! Output: reconstructed vector field (measured in X,Y,Z) located at cell centers
+  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+    implicit none
+
+    type (state_type), intent(inout) :: state 
+    type (mesh_type), intent(in) :: grid
+
+    !   temporary arrays needed in the compute procedure
+    integer :: nCellsSolve
+    integer, dimension(:,:), pointer :: edgesOnCell
+    integer, dimension(:), pointer :: nEdgesOnCell
+    integer :: iCell,iEdge, i
+    real (kind=RKIND), dimension(:,:), pointer :: u
+    real(kind=RKIND), dimension(:), pointer :: latCell, lonCell
+    real (kind=RKIND), dimension(:,:), pointer :: uReconstructX, uReconstructY, uReconstructZ
+    real (kind=RKIND), dimension(:,:), pointer :: uReconstructZonal, uReconstructMeridional
+
+    real (kind=RKIND), dimension(:,:,:), pointer :: coeffs_reconstruct
+
+    logical :: on_a_sphere
+
+    real (kind=RKIND) :: clat, slat, clon, slon
+
+
+    ! stored arrays used during compute procedure
+    coeffs_reconstruct =&gt; grid % coeffs_reconstruct % array
+
+    ! temporary variables
+    edgesOnCell =&gt; grid % edgesOnCell % array
+    nEdgesOnCell=&gt; grid % nEdgesOnCell % array
+    nCellsSolve = grid % nCellsSolve
+    u =&gt; state % u % array
+    uReconstructX =&gt; state % gradKeReconstructX % array
+    uReconstructY =&gt; state % gradKeReconstructY % array
+    uReconstructZ =&gt; state % gradKeReconstructZ % array
+
+    latCell       =&gt; grid % latCell % array
+    lonCell       =&gt; grid % lonCell % array
+    uReconstructZonal =&gt; state % gradKeReconstructZonal % array
+    uReconstructMeridional =&gt; state % gradKeReconstructMerid % array
+    on_a_sphere = grid % on_a_sphere
+
+    ! init the intent(out)
+    uReconstructX = 0.0
+    uReconstructY = 0.0
+    uReconstructZ = 0.0
+
+    ! loop over cell centers
+    do iCell=1,nCellsSolve
+      ! a more efficient reconstruction where rbf_values*matrix_reconstruct has been precomputed
+      ! in coeffs_reconstruct
+      do i=1,nEdgesOnCell(iCell)
+        iEdge = edgesOnCell(i,iCell)
+        uReconstructX(:,iCell) = uReconstructX(:,iCell) &amp;
+          + coeffs_reconstruct(1,i,iCell) * u(:,iEdge)
+        uReconstructY(:,iCell) = uReconstructY(:,iCell) &amp;
+          + coeffs_reconstruct(2,i,iCell) * u(:,iEdge)
+        uReconstructZ(:,iCell) = uReconstructZ(:,iCell) &amp;
+          + coeffs_reconstruct(3,i,iCell) * u(:,iEdge)
+
+      enddo
+    enddo   ! iCell
+
+    if(on_a_sphere) then
+      do iCell=1,nCellsSolve
+        clat = cos(latCell(iCell))
+        slat = sin(latCell(iCell))
+        clon = cos(lonCell(iCell))
+        slon = sin(lonCell(iCell))
+        uReconstructZonal(:,iCell) = -uReconstructX(:,iCell)*slon + uReconstructY(:,iCell)*clon
+        uReconstructMeridional(:,iCell) = -(uReconstructX(:,iCell)*clon &amp;
+          + uReconstructY(:,iCell)*slon)*slat &amp;
+          + uReconstructZ(:,iCell)*clat
+      end do
+    else
+      uReconstructZonal = uReconstructX
+      uReconstructMeridional = uReconstructY
+    end if
+
+  end subroutine reconstructGradKE
+
+
 end module vector_reconstruction

</font>
</pre>