LCOV - code coverage report
Current view: top level - physics/cam - polar_avg.F90 (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 79 0.0 %
Date: 2024-12-17 22:39:59 Functions: 0 2 0.0 %

          Line data    Source code
       1             : module polar_avg
       2             : !----------------------------------------------------------------------- 
       3             : ! 
       4             : ! Purpose: 
       5             : !  These routines are used by the fv dycore to set the collocated 
       6             : !  pole points at the limits of the latitude dimension to the same 
       7             : !  value. 
       8             : !
       9             : ! Methods: 
      10             : !  The reprosum reproducible distributed sum is used for these 
      11             : !  calculations.
      12             : !
      13             : ! Author: A. Mirin
      14             : ! 
      15             : !-----------------------------------------------------------------------
      16             : 
      17             : !-----------------------------------------------------------------------
      18             : !- use statements ------------------------------------------------------
      19             : !-----------------------------------------------------------------------
      20             :    use shr_kind_mod,  only: r8 => shr_kind_r8
      21             :    use dycore,        only: dycore_is
      22             :    use dyn_grid,      only: get_dyn_grid_parm
      23             :    use phys_grid,     only: get_ncols_p, get_lat_all_p
      24             :    use ppgrid,        only: begchunk, endchunk, pcols
      25             :    use shr_reprosum_mod, only: shr_reprosum_calc
      26             : #if ( defined SPMD )
      27             :    use mpishorthand,  only: mpicom
      28             : #endif
      29             : 
      30             : !-----------------------------------------------------------------------
      31             : !- module boilerplate --------------------------------------------------
      32             : !-----------------------------------------------------------------------
      33             :    implicit none
      34             :    private
      35             :    save
      36             : 
      37             : !-----------------------------------------------------------------------
      38             : ! Public interfaces ----------------------------------------------------
      39             : !-----------------------------------------------------------------------
      40             :    public :: &
      41             :       polar_average           ! support for LR dycore polar averaging
      42             : 
      43             :    interface polar_average
      44             :       module procedure polar_average2d, polar_average3d
      45             :    end interface
      46             : 
      47             :    CONTAINS
      48             : !
      49             : !========================================================================
      50             : !
      51           0 :    subroutine polar_average2d(field)
      52             : !----------------------------------------------------------------------- 
      53             : ! Purpose: Set the collocated pole points at the limits of the latitude 
      54             : !          dimension to the same value. 
      55             : ! Author: J. Edwards
      56             : !-----------------------------------------------------------------------
      57             : !
      58             : ! Arguments
      59             : !
      60             :      real(r8), intent(inout) :: field(pcols,begchunk:endchunk)
      61             : !
      62             : ! Local workspace
      63             : !
      64             :      integer :: i, c, ln, ls, ncols
      65             :      integer :: plat, plon
      66           0 :      integer, allocatable :: lats(:)
      67             : #if (! defined SPMD)
      68             :      integer  :: mpicom = 0
      69             : #endif
      70             : 
      71             :      real(r8) :: sum(2)
      72           0 :      real(r8), allocatable :: n_pole(:), s_pole(:)
      73             : !
      74             : !-----------------------------------------------------------------------
      75             : !
      76           0 :      if(.not. dycore_is('LR')) return
      77             : 
      78           0 :      plon = get_dyn_grid_parm('plon')
      79           0 :      plat = get_dyn_grid_parm('plat')
      80           0 :      allocate(lats(pcols), n_pole(plon), s_pole(plon))
      81           0 :      ln=0
      82           0 :      ls=0
      83           0 :      n_pole = 0._r8
      84           0 :      s_pole = 0._r8
      85             : 
      86           0 :      do c=begchunk,endchunk
      87           0 :         call get_lat_all_p(c,pcols,lats) 
      88           0 :         ncols = get_ncols_p(c)
      89             : 
      90           0 :         do i=1,ncols
      91           0 :            if(lats(i).eq.1) then
      92           0 :               ln=ln+1
      93           0 :               n_pole(ln) = field(i,c)
      94           0 :            else if(lats(i).eq.plat) then
      95           0 :               ls=ls+1
      96           0 :               s_pole(ls) = field(i,c)
      97             :            end if
      98             :         enddo
      99             :         
     100             :      end do
     101             :      
     102             :      call shr_reprosum_calc(n_pole, sum(1:1), ln, plon, 1, &
     103           0 :                     gbl_count=plon, commid=mpicom)
     104             : 
     105             :      call shr_reprosum_calc(s_pole, sum(2:2), ls, plon, 1, &
     106           0 :                     gbl_count=plon, commid=mpicom)
     107             : 
     108           0 :      ln=0
     109           0 :      ls=0
     110           0 :      do c=begchunk,endchunk
     111           0 :         call get_lat_all_p(c,pcols,lats) 
     112           0 :         ncols = get_ncols_p(c)
     113             : 
     114           0 :         do i=1,ncols
     115           0 :            if(lats(i).eq.1) then
     116           0 :               ln=ln+1
     117           0 :               field(i,c) = sum(1)/plon
     118           0 :            else if(lats(i).eq.plat) then
     119           0 :               ls=ls+1
     120           0 :               field(i,c) = sum(2)/plon
     121             :            end if
     122             :         enddo
     123             :         
     124             :      end do
     125             : 
     126           0 :      deallocate(lats, n_pole, s_pole)
     127             :    
     128           0 :    end subroutine polar_average2d
     129             : 
     130             : !
     131             : !========================================================================
     132             : !
     133             : 
     134           0 :    subroutine polar_average3d(nlev, field)
     135             : !----------------------------------------------------------------------- 
     136             : ! Purpose: Set the collocated pole points at the limits of the latitude 
     137             : !          dimension to the same value. 
     138             : ! Author: J. Edwards
     139             : !-----------------------------------------------------------------------
     140             : !
     141             : ! Arguments
     142             : !
     143             :      integer, intent(in) :: nlev
     144             :      real(r8), intent(inout) :: field(pcols,nlev,begchunk:endchunk)
     145             : !
     146             : ! Local workspace
     147             : !
     148             :      integer :: i, c, ln, ls, ncols, k
     149             :      integer :: plat, plon
     150           0 :      integer, allocatable :: lats(:)
     151             : #if (! defined SPMD)
     152             :      integer  :: mpicom = 0
     153             : #endif
     154             : 
     155           0 :      real(r8) :: sum(nlev,2)
     156           0 :      real(r8), allocatable :: n_pole(:,:), s_pole(:,:)
     157             : !
     158             : !-----------------------------------------------------------------------
     159             : !
     160           0 :      if(.not. dycore_is('LR')) return
     161             : 
     162           0 :      plon = get_dyn_grid_parm('plon')
     163           0 :      plat = get_dyn_grid_parm('plat')
     164           0 :      allocate(lats(pcols), n_pole(plon,nlev), s_pole(plon,nlev))
     165           0 :      ln=0
     166           0 :      ls=0
     167           0 :      n_pole = 0._r8
     168           0 :      s_pole = 0._r8
     169             : 
     170           0 :      do c=begchunk,endchunk
     171           0 :         call get_lat_all_p(c,pcols,lats) 
     172           0 :         ncols = get_ncols_p(c)
     173             : 
     174           0 :         do i=1,ncols
     175           0 :            if(lats(i).eq.1) then
     176           0 :               ln=ln+1
     177           0 :               do k=1,nlev
     178           0 :                  n_pole(ln,k) = field(i,k,c)
     179             :               end do
     180           0 :            else if(lats(i).eq.plat) then
     181           0 :               ls=ls+1
     182           0 :               do k=1,nlev                 
     183           0 :                  s_pole(ls,k) = field(i,k,c)
     184             :               end do
     185             :            end if
     186             :         enddo
     187             :      end do
     188             :      
     189             :      call shr_reprosum_calc(n_pole, sum(:,1), ln, plon, nlev, &
     190           0 :                     gbl_count=plon, commid=mpicom)
     191             : 
     192             :      call shr_reprosum_calc(s_pole, sum(:,2), ls, plon, nlev, &
     193           0 :                     gbl_count=plon, commid=mpicom)
     194             : 
     195           0 :      ln=0
     196           0 :      ls=0
     197           0 :      do c=begchunk,endchunk
     198           0 :         call get_lat_all_p(c,pcols,lats) 
     199           0 :         ncols = get_ncols_p(c)
     200             : 
     201           0 :         do i=1,ncols
     202           0 :            if(lats(i).eq.1) then
     203           0 :               ln=ln+1
     204           0 :               do k=1,nlev
     205           0 :                  field(i,k,c) = sum(k,1)/plon
     206             :               end do
     207           0 :            else if(lats(i).eq.plat) then
     208           0 :               ls=ls+1
     209           0 :               do k=1,nlev
     210           0 :                  field(i,k,c) = sum(k,2)/plon
     211             :               end do
     212             :            end if
     213             :         enddo
     214             :         
     215             :      end do
     216             :    
     217           0 :      deallocate(lats, n_pole, s_pole)
     218             : 
     219           0 :    end subroutine polar_average3d
     220             : 
     221             : end module polar_avg

Generated by: LCOV version 1.14