<p><b>ringler@lanl.gov</b> 2011-04-21 13:54:24 -0600 (Thu, 21 Apr 2011)</p><p><br>
add module for alpha closure<br>
</p><hr noshade><pre><font color="gray">Added: branches/pv_based_swm/mpas/src/core_pvsw/module_alpha.F
===================================================================
--- branches/pv_based_swm/mpas/src/core_pvsw/module_alpha.F                                (rev 0)
+++ branches/pv_based_swm/mpas/src/core_pvsw/module_alpha.F        2011-04-21 19:54:24 UTC (rev 799)
@@ -0,0 +1,273 @@
+module alpha_solver
+
+  use grid_types
+  use configure
+  use constants
+  use poisson_solver
+  use dmpar
+
+  implicit none
+
+  real (KIND=RKIND), parameter :: threshold = 1.0e-8
+  integer, parameter :: nIterPerGS = 2
+
+  public :: init_alpha, gs_iteration_alpha, alpha
+
+  contains
+
+  subroutine init_alpha(domain)
+  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
+  ! Purpose: put any init stuff in here
+  !
+  ! Input: grid meta data
+  !
+  ! Output: 
+  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
+
+    implicit none
+
+    type (domain_type), intent(inout) :: domain
+
+    type (block_type), pointer :: block
+
+    block =&gt; domain % blocklist
+    do while (associated(block))
+
+      block =&gt; block % next
+    enddo   ! block
+
+  end subroutine init_alpha
+
+
+  subroutine alpha(domain)
+  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+  ! Purpose: given the rough vorticity and divergence, find the smooth vorticity and divergence
+  !
+  ! Input: grid meta data
+  !
+  ! Output: vorSmooth, divSmooth
+  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+
+    implicit none
+
+    type (domain_type), intent(inout) :: domain
+
+    integer :: iteration
+    logical :: converge
+    real (kind=RKIND) :: l2_vorSmooth_error, l2_divSmooth_error, globalVorSmoothError, globalDivSmoothError, globalArea, localArea, rflag, gflag
+    type (block_type), pointer :: block
+  
+    iteration = 0; l2_vorSmooth_error = 1.0; l2_divSmooth_error = 1.0
+    converge = .false.
+
+    ! iterate until we converge
+    do while (.not.converge)
+      iteration = iteration + 1
+
+      ! do a few Guass-Seidel iterations
+      block =&gt; domain % blocklist
+      do while (associated(block))
+         call gs_iteration_alpha(block % state % time_levs(2) % state, block % mesh)
+         block =&gt; block % next
+      end do
+
+      ! do a boundary update on vorSmooth and divSmooth
+      block =&gt; domain % blocklist
+      do while (associated(block))
+         call dmpar_exch_halo_field2dReal(domain % dminfo, block % state % time_levs(2) % state % vorSmooth % array(:,:), &amp;
+                                              block % mesh % nVertLevels, block % mesh % nCells, &amp;
+                                              block % parinfo % cellsToSend, block % parinfo % cellsToRecv)
+         if(.not.config_bve) then
+         call dmpar_exch_halo_field2dReal(domain % dminfo, block % state % time_levs(2) % state % divSmooth % array(:,:), &amp;
+                                              block % mesh % nVertLevels, block % mesh % nCells, &amp;
+                                              block % parinfo % cellsToSend, block % parinfo % cellsToRecv)
+         endif
+         block =&gt; block % next
+      end do
+
+
+      ! check the global error every so often
+      if(mod(iteration,100).eq.0) then
+      block =&gt; domain % blocklist
+      do while (associated(block))
+             call compute_alpha_error(block % state % time_levs(2) % state, block % mesh, l2_vorSmooth_error, l2_divSmooth_error, localArea)
+             call dmpar_sum_real(domain % dminfo, l2_vorSmooth_error, globalVorSmoothError)
+             call dmpar_sum_real(domain % dminfo, l2_divSmooth_error, globalDivSmoothError)
+             call dmpar_sum_real(domain % dminfo, localArea, globalArea)
+         block =&gt; block % next
+      end do
+      l2_vorSmooth_error = sqrt(globalVorSmoothError/globalArea)
+      l2_divSmooth_error = sqrt(globalDivSmoothError/globalArea)
+      if(l2_vorSmooth_error.lt.threshold.and.l2_divSmooth_error.lt.threshold) converge=.true.
+      if(iteration.gt.10000) converge=.true.
+      endif
+
+
+      ! make sure that everyone agrees on convergence
+      if(mod(iteration,100).eq.0) then
+      block =&gt; domain % blocklist
+      do while (associated(block))
+         rflag = 0.0
+         if(converge) rflag=1.0
+         call dmpar_min_real(domain % dminfo, rflag, gflag)
+         block =&gt; block % next
+      end do
+      converge=.false.
+      if(gflag.gt.0.5) converge=.true.
+      write(6,10) iteration, l2_vorSmooth_error, l2_divSmooth_error, rflag, gflag
+   10 format(i8,6e20.10)
+      endif
+
+    enddo  ! do while not converged
+
+    ! copy vorSmooth and divSmooth into the other time level 
+    block =&gt; domain % blocklist
+    do while (associated(block))
+      block % state % time_levs(1) % state % vorSmooth % array(:,:) = block % state % time_levs(2) % state % vorSmooth % array(:,:)
+      block % state % time_levs(1) % state % divSmooth % array(:,:) = block % state % time_levs(2) % state % divSmooth % array(:,:)
+      block =&gt; block % next
+    end do
+
+  end subroutine alpha
+
+
+  subroutine gs_iteration_alpha(state, grid)
+  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+  ! Purpose: do one or more iteration(s) using Guass Seidel to solve
+  !   vorSmooth and divSmooth where del2(vorSmooth)=vor and del2(divSmooth)=div
+  !
+  ! Input: vor, div, initial guess for vorSmooth and divSmooth
+  !
+  ! Output: update vorSmooth and divSmooth
+  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+    implicit none
+
+    type (state_type), intent(inout) :: state 
+    type (mesh_type), intent(in) :: grid
+
+    integer :: nCells
+    integer, dimension(:), pointer :: nEdgesOnCell
+    integer, dimension(:,:), pointer :: cellsOnCell
+    integer :: iCell, jCell, iter, k, j, nVertLevels
+    real (kind=RKIND), dimension(:), pointer :: areaCell
+    real (kind=RKIND), dimension(:,:), pointer :: vor, div, vorSmooth, divSmooth
+    real (kind=RKIND), dimension(:,:), pointer :: poisson_weights
+    real (kind=RKIND) :: sum1, sum2, sum3
+    real (kind=RKIND), parameter :: sor = 1.5
+
+    cellsOnCell     =&gt; grid % cellsOnCell % array
+    nEdgesOnCell    =&gt; grid % nEdgesOnCell % array
+    areaCell        =&gt; grid % areaCell % array
+    poisson_weights =&gt; grid % poisson_weights % array
+    nCells          =  grid % nCells
+    nVertLevels     =  grid % nVertLevels
+
+    vor =&gt; state % vor % array
+    div =&gt; state % div % array
+    vorSmooth =&gt; state % vorSmooth % array
+    divSmooth =&gt; state % divSmooth % array
+
+    ! do nIter GS iterations
+    do iter=1,nIterPerGS
+
+    ! loop over the vertical
+    do k = 1, nVertLevels
+
+      ! loop over cell centers
+      do iCell=1,nCells
+        sum1=0.0; sum2=0.0; sum3=0.0
+
+        ! loop over neighboring cells
+        do j=1,nEdgesOnCell(iCell)
+           jCell = cellsOnCell(j,iCell)
+
+            sum1 = sum1 + poisson_weights(j,iCell)
+            sum2 = sum2 + poisson_weights(j,iCell) * vorSmooth(k,jCell)
+            sum3 = sum3 + poisson_weights(j,iCell) * divSmooth(k,jCell)
+
+        enddo ! loop over edges
+
+        sum1 = sum1 * alphasq / areaCell(iCell)
+        sum2 = sum2 * alphasq / areaCell(iCell)
+        sum3 = sum3 * alphasq / areaCell(iCell)
+
+        vorSmooth(k,iCell) = (1.0-sor)*vorSmooth(k,iCell) + sor*(sum2 + vor(k,iCell))/(1.0+sum1)
+        divSmooth(k,iCell) = (1.0-sor)*divSmooth(k,iCell) + sor*(sum3 + div(k,iCell))/(1.0+sum1)
+
+      enddo  ! loop over cell centers
+    enddo    ! loop over vertical levels
+
+    enddo    ! loop over iterations
+
+  end subroutine gs_iteration_alpha
+
+
+  subroutine compute_alpha_error(state, grid, l2_vorSmooth_error, l2_divSmooth_error, localArea)
+  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+  ! Purpose: compute error in poisson solver
+  !
+  ! Input: vorSmooth, divSmooth, vor and div
+  !
+  ! Output: converge (true or false)
+  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+    implicit none
+
+    type (state_type), intent(in) :: state
+    type (mesh_type), intent(in) :: grid
+    real (kind=RKIND), intent(out) :: l2_vorSmooth_error, l2_divSmooth_error, localArea
+
+    integer :: nCellsSolve
+    integer, dimension(:), pointer :: nEdgesOnCell
+    integer, dimension(:,:), pointer :: cellsOnCell
+    integer :: iCell, jCell, iter, k, j, nVertLevels
+    real (kind=RKIND), dimension(:), pointer :: areaCell
+    real (kind=RKIND), dimension(:,:), pointer :: vor, div, vorSmooth, divSmooth
+    real (kind=RKIND), dimension(:,:), pointer :: poisson_weights
+    real (kind=RKIND) :: sum_error_vorSmooth, sum_error_divSmooth, sum_area, r1, r2
+
+    poisson_weights =&gt; grid % poisson_weights % array
+    cellsOnCell     =&gt; grid % cellsOnCell % array
+    nEdgesOnCell    =&gt; grid % nEdgesOnCell % array
+    areaCell        =&gt; grid % areaCell % array
+    nCellsSolve     =  grid % nCellsSolve
+    nVertLevels     =  grid % nVertLevels
+
+    vor =&gt; state % vor % array
+    div =&gt; state % div % array
+    vorSmooth =&gt; state % vorSmooth % array
+    divSmooth =&gt; state % divSmooth % array
+
+    do k=1,nVertLevels
+
+      sum_error_vorSmooth = 0.0; sum_error_divSmooth = 0.0; sum_area = 0.0
+      do iCell=1,nCellsSolve
+
+        r1=0.0; r2=0.0
+        do j=1,nEdgesOnCell(iCell)
+        
+          jCell = cellsOnCell(j,iCell)
+          r1 = r1 + poisson_weights(j,iCell) * (vorSmooth(k,jCell)-vorSmooth(k,iCell))
+          r2 = r2 + poisson_weights(j,iCell) * (divSmooth(k,jCell)-divSmooth(k,iCell))
+
+        enddo
+        r1 = vorSmooth(k,iCell) - r1 * alphasq / areaCell(iCell)
+        r2 = divSmooth(k,iCell) - r2 * alphasq / areaCell(iCell)
+
+        sum_error_vorSmooth = sum_error_vorSmooth + areaCell(iCell)*(r1 - vor (k,iCell))**2
+        sum_error_divSmooth = sum_error_divSmooth + areaCell(iCell)*(r2 - div(k,iCell))**2
+        sum_area = sum_area + areaCell(iCell)
+
+      enddo
+
+      l2_vorSmooth_error = sum_error_vorSmooth
+      l2_divSmooth_error = sum_error_divSmooth
+      localArea = sum_area
+
+    enddo
+
+  end subroutine compute_alpha_error
+
+end module alpha_solver

</font>
</pre>