#include <misc.h>
#include <preproc.h>
module subgridAveMod 12,19
!-----------------------------------------------------------------------
!BOP
!
! !MODULE: subgridAveMod
!
! !DESCRIPTION:
! Utilities to perfrom subgrid averaging
!
! !USES:
use shr_kind_mod
, only: r8 => shr_kind_r8
use clmtype
use clm_varcon
, only : spval, isturb, icol_roof, icol_sunwall, icol_shadewall, &
icol_road_perv, icol_road_imperv
use clm_varctl
, only : iulog
use abortutils
, only : endrun
! !PUBLIC TYPES:
implicit none
save
!
! !PUBLIC MEMBER FUNCTIONS:
public :: p2c ! Perfrom an average from pfts to columns
public :: p2l ! Perfrom an average from pfts to landunits
public :: p2g ! Perfrom an average from pfts to gridcells
public :: c2l ! Perfrom an average from columns to landunits
public :: c2g ! Perfrom an average from columns to gridcells
public :: l2g ! Perfrom an average from landunits to gridcells
interface p2c 47
module procedure p2c_1d
module procedure p2c_2d
module procedure p2c_1d_filter
module procedure p2c_2d_filter
end interface
interface p2l
module procedure p2l_1d
module procedure p2l_2d
end interface
interface p2g 35
module procedure p2g_1d
module procedure p2g_2d
end interface
interface c2l
module procedure c2l_1d
module procedure c2l_2d
end interface
interface c2g 8
module procedure c2g_1d
module procedure c2g_2d
end interface
interface l2g 2
module procedure l2g_1d
module procedure l2g_2d
end interface
!
! !REVISION HISTORY:
! Created by Mariana Vertenstein 12/03
!
!EOP
!-----------------------------------------------------------------------
contains
!-----------------------------------------------------------------------
!BOP
!
! !IROUTINE: p2c_1d
!
! !INTERFACE:
subroutine p2c_1d (lbp, ubp, lbc, ubc, parr, carr, p2c_scale_type) 1,3
!
! !DESCRIPTION:
! Perfrom subgrid-average from pfts to columns.
! Averaging is only done for points that are not equal to "spval".
!
! !USES:
use clm_varpar
, only : max_pft_per_col
!
! !ARGUMENTS:
implicit none
integer , intent(in) :: lbp, ubp ! beginning and ending pft
integer , intent(in) :: lbc, ubc ! beginning and ending column
real(r8), intent(in) :: parr(lbp:ubp) ! pft array
real(r8), intent(out) :: carr(lbc:ubc) ! column array
character(len=*), intent(in) :: p2c_scale_type ! scale type
!
! !REVISION HISTORY:
! Created by Mariana Vertenstein 12/03
!
!
! !LOCAL VARIABLES:
!EOP
integer :: pi,p,c,index ! indices
real(r8) :: scale_p2c(lbp:ubp) ! scale factor for column->landunit mapping
logical :: found ! temporary for error check
real(r8) :: sumwt(lbc:ubc) ! sum of weights
real(r8), pointer :: wtcol(:) ! weight of pft relative to column
integer , pointer :: pcolumn(:) ! column index of corresponding pft
integer , pointer :: npfts(:) ! number of pfts in column
integer , pointer :: pfti(:) ! initial pft index in column
!------------------------------------------------------------------------
wtcol => clm3%g%l%c%p%wtcol
pcolumn => clm3%g%l%c%p%column
npfts => clm3%g%l%c%npfts
pfti => clm3%g%l%c%pfti
if (p2c_scale_type == 'unity') then
do p = lbp,ubp
scale_p2c(p) = 1.0_r8
end do
else
write(iulog,*)'p2c_1d error: scale type ',p2c_scale_type,' not supported'
call endrun
()
end if
carr(lbc:ubc) = spval
sumwt(lbc:ubc) = 0._r8
#if (defined CPP_VECTOR)
!dir$ nointerchange
do pi = 1,max_pft_per_col
!dir$ concurrent
!cdir nodep
do c = lbc,ubc
if (pi <= npfts(c)) then
p = pfti(c) + pi - 1
if (wtcol(p) /= 0._r8) then
if (parr(p) /= spval) then
carr(c) = 0._r8
end if
end if
end if
end do
end do
!dir$ nointerchange
do pi = 1,max_pft_per_col
!dir$ concurrent
!cdir nodep
do c = lbc,ubc
if (pi <= npfts(c)) then
p = pfti(c) + pi - 1
if (wtcol(p) /= 0._r8) then
if (parr(p) /= spval) then
carr(c) = carr(c) + parr(p) * scale_p2c(p) * wtcol(p)
sumwt(c) = sumwt(c) + wtcol(p)
end if
end if
end if
end do
end do
#else
do p = lbp,ubp
if (wtcol(p) /= 0._r8) then
if (parr(p) /= spval) then
c = pcolumn(p)
if (sumwt(c) == 0._r8) carr(c) = 0._r8
carr(c) = carr(c) + parr(p) * scale_p2c(p) * wtcol(p)
sumwt(c) = sumwt(c) + wtcol(p)
end if
end if
end do
#endif
found = .false.
do c = lbc,ubc
if (sumwt(c) > 1.0_r8 + 1.e-6_r8) then
found = .true.
index = c
else if (sumwt(c) /= 0._r8) then
carr(c) = carr(c)/sumwt(c)
end if
end do
if (found) then
write(iulog,*)'p2c error: sumwt is greater than 1.0 at c= ',index
call endrun
()
end if
end subroutine p2c_1d
!-----------------------------------------------------------------------
!BOP
!
! !IROUTINE: p2c_2d
!
! !INTERFACE:
subroutine p2c_2d (lbp, ubp, lbc, ubc, num2d, parr, carr, p2c_scale_type) 1,3
!
! !DESCRIPTION:
! Perfrom subgrid-average from landunits to gridcells.
! Averaging is only done for points that are not equal to "spval".
!
! !USES:
use clm_varpar
, only : max_pft_per_col
!
! !ARGUMENTS:
implicit none
integer , intent(in) :: lbp, ubp ! beginning and ending pft
integer , intent(in) :: lbc, ubc ! beginning and ending column
integer , intent(in) :: num2d ! size of second dimension
real(r8), intent(in) :: parr(lbp:ubp,num2d) ! pft array
real(r8), intent(out) :: carr(lbc:ubc,num2d) ! column array
character(len=*), intent(in) :: p2c_scale_type ! scale type
!
! !REVISION HISTORY:
! Created by Mariana Vertenstein 12/03
!
!
! !LOCAL VARIABLES:
!EOP
integer :: j,pi,p,c,index ! indices
real(r8) :: scale_p2c(lbp:ubp) ! scale factor for column->landunit mapping
logical :: found ! temporary for error check
real(r8) :: sumwt(lbc:ubc) ! sum of weights
real(r8), pointer :: wtcol(:) ! weight of pft relative to column
integer , pointer :: pcolumn(:) ! column index of corresponding pft
integer , pointer :: npfts(:) ! number of pfts in column
integer , pointer :: pfti(:) ! initial pft index in column
!------------------------------------------------------------------------
wtcol => clm3%g%l%c%p%wtcol
pcolumn => clm3%g%l%c%p%column
npfts => clm3%g%l%c%npfts
pfti => clm3%g%l%c%pfti
if (p2c_scale_type == 'unity') then
do p = lbp,ubp
scale_p2c(p) = 1.0_r8
end do
else
write(iulog,*)'p2c_2d error: scale type ',p2c_scale_type,' not supported'
call endrun
()
end if
carr(:,:) = spval
do j = 1,num2d
sumwt(:) = 0._r8
#if (defined CPP_VECTOR)
!dir$ nointerchange
do pi = 1,max_pft_per_col
!dir$ concurrent
!cdir nodep
do c = lbc,ubc
if (pi <= npfts(c)) then
p = pfti(c) + pi - 1
if (wtcol(p) /= 0._r8) then
if (parr(p,j) /= spval) then
carr(c,j) = 0._r8
end if
end if
end if
end do
end do
!dir$ nointerchange
do pi = 1,max_pft_per_col
!dir$ concurrent
!cdir nodep
do c = lbc,ubc
if (pi <= npfts(c)) then
p = pfti(c) + pi - 1
if (wtcol(p) /= 0._r8) then
if (parr(p,j) /= spval) then
carr(c,j) = carr(c,j) + parr(p,j) * scale_p2c(p) * wtcol(p)
sumwt(c) = sumwt(c) + wtcol(p)
end if
end if
end if
end do
end do
#else
do p = lbp,ubp
if (wtcol(p) /= 0._r8) then
if (parr(p,j) /= spval) then
c = pcolumn(p)
if (sumwt(c) == 0._r8) carr(c,j) = 0._r8
carr(c,j) = carr(c,j) + parr(p,j) * scale_p2c(p) * wtcol(p)
sumwt(c) = sumwt(c) + wtcol(p)
end if
end if
end do
#endif
found = .false.
do c = lbc,ubc
if (sumwt(c) > 1.0_r8 + 1.e-6_r8) then
found = .true.
index = c
else if (sumwt(c) /= 0._r8) then
carr(c,j) = carr(c,j)/sumwt(c)
end if
end do
if (found) then
write(iulog,*)'p2c_2d error: sumwt is greater than 1.0 at c= ',index,' lev= ',j
call endrun
()
end if
end do
end subroutine p2c_2d
!-----------------------------------------------------------------------
!BOP
!
! !IROUTINE: p2c_1d_filter
!
! !INTERFACE:
subroutine p2c_1d_filter (numfc, filterc, pftarr, colarr) 1,1
!
! !DESCRIPTION:
! perform pft to column averaging for single level pft arrays
!
! !USES:
use clm_varpar
, only : max_pft_per_col
!
! !ARGUMENTS:
implicit none
integer , intent(in) :: numfc
integer , intent(in) :: filterc(numfc)
real(r8), pointer :: pftarr(:)
real(r8), pointer :: colarr(:)
!
! !REVISION HISTORY:
! Created by Mariana Vertenstein 12/03
!
!
! !LOCAL VARIABLES:
!EOP
integer :: fc,c,pi,p ! indices
integer , pointer :: npfts(:)
integer , pointer :: pfti(:)
integer , pointer :: pftf(:)
real(r8), pointer :: wtcol(:)
real(r8), pointer :: wtgcell(:)
!-----------------------------------------------------------------------
npfts => clm3%g%l%c%npfts
pfti => clm3%g%l%c%pfti
pftf => clm3%g%l%c%pftf
wtcol => clm3%g%l%c%p%wtcol
wtgcell => clm3%g%l%c%p%wtgcell
#if (defined CPP_VECTOR)
!dir$ concurrent
!cdir nodep
do fc = 1,numfc
c = filterc(fc)
colarr(c) = 0._r8
end do
!dir$ nointerchange
do pi = 1,max_pft_per_col
!dir$ concurrent
!cdir nodep
do fc = 1,numfc
c = filterc(fc)
if ( pi <= npfts(c) ) then
p = pfti(c) + pi - 1
if (wtgcell(p) > 0._r8) colarr(c) = colarr(c) + pftarr(p) * wtcol(p)
end if
end do
end do
#else
do fc = 1,numfc
c = filterc(fc)
colarr(c) = 0._r8
do p = pfti(c), pftf(c)
if (wtgcell(p) > 0._r8) colarr(c) = colarr(c) + pftarr(p) * wtcol(p)
end do
end do
#endif
end subroutine p2c_1d_filter
!-----------------------------------------------------------------------
!BOP
!
! !IROUTINE: p2c_2d_filter
!
! !INTERFACE:
subroutine p2c_2d_filter (lev, numfc, filterc, pftarr, colarr) 1,1
!
! !DESCRIPTION:
! perform pft to column averaging for multi level pft arrays
!
! !USES:
use clm_varpar
, only : max_pft_per_col
! !ARGUMENTS:
implicit none
integer , intent(in) :: lev
integer , intent(in) :: numfc
integer , intent(in) :: filterc(numfc)
real(r8), pointer :: pftarr(:,:)
real(r8), pointer :: colarr(:,:)
!
! !REVISION HISTORY:
! Created by Mariana Vertenstein 12/03
!
!
! !LOCAL VARIABLES:
!EOP
integer :: fc,c,pi,p,j ! indices
integer , pointer :: npfts(:)
integer , pointer :: pfti(:)
integer , pointer :: pftf(:)
real(r8), pointer :: wtcol(:)
!-----------------------------------------------------------------------
npfts => clm3%g%l%c%npfts
pfti => clm3%g%l%c%pfti
pftf => clm3%g%l%c%pftf
wtcol => clm3%g%l%c%p%wtcol
#if (defined CPP_VECTOR)
do j = 1,lev
!dir$ concurrent
!cdir nodep
do fc = 1,numfc
c = filterc(fc)
colarr(c,j) = 0._r8
end do
!dir$ nointerchange
do pi = 1,max_pft_per_col
!dir$ concurrent
!cdir nodep
do fc = 1,numfc
c = filterc(fc)
if ( pi <= npfts(c) ) then
p = pfti(c) + pi - 1
colarr(c,j) = colarr(c,j) + pftarr(p,j) * wtcol(p)
end if
end do
end do
end do
#else
do j = 1,lev
do fc = 1,numfc
c = filterc(fc)
colarr(c,j) = 0._r8
do p = pfti(c), pftf(c)
colarr(c,j) = colarr(c,j) + pftarr(p,j) * wtcol(p)
end do
end do
end do
#endif
end subroutine p2c_2d_filter
!-----------------------------------------------------------------------
!BOP
!
! !IROUTINE: p2l_1d
!
! !INTERFACE:
subroutine p2l_1d (lbp, ubp, lbc, ubc, lbl, ubl, parr, larr, & 1,4
p2c_scale_type, c2l_scale_type)
!
! !DESCRIPTION:
! Perfrom subgrid-average from pfts to landunits
! Averaging is only done for points that are not equal to "spval".
!
! !USES:
use clm_varpar
, only : max_pft_per_lu
!
! !ARGUMENTS:
implicit none
integer , intent(in) :: lbp, ubp ! beginning and ending pft indices
integer , intent(in) :: lbc, ubc ! beginning and ending column indices
integer , intent(in) :: lbl, ubl ! beginning and ending landunit indices
real(r8), intent(in) :: parr(lbp:ubp) ! input column array
real(r8), intent(out) :: larr(lbl:ubl) ! output landunit array
character(len=*), intent(in) :: p2c_scale_type ! scale factor type for averaging
character(len=*), intent(in) :: c2l_scale_type ! scale factor type for averaging
!
! !REVISION HISTORY:
! Created by Mariana Vertenstein 12/03
!
!
! !LOCAL VARIABLES:
!EOP
integer :: pi,p,c,l,index ! indices
logical :: found ! temporary for error check
real(r8) :: sumwt(lbl:ubl) ! sum of weights
real(r8) :: scale_p2c(lbc:ubc) ! scale factor for pft->column mapping
real(r8) :: scale_c2l(lbc:ubc) ! scale factor for column->landunit mapping
real(r8), pointer :: wtlunit(:) ! weight of pft relative to landunit
integer , pointer :: pcolumn(:) ! column of corresponding pft
integer , pointer :: plandunit(:) ! landunit of corresponding pft
integer , pointer :: npfts(:) ! number of pfts in landunit
integer , pointer :: pfti(:) ! initial pft index in landunit
integer , pointer :: clandunit(:) ! landunit of corresponding column
integer , pointer :: ctype(:) ! column type
integer , pointer :: ltype(:) ! landunit type
real(r8), pointer :: canyon_hwr(:) ! urban canyon height to width ratio
!------------------------------------------------------------------------
canyon_hwr => clm3%g%l%canyon_hwr
ltype => clm3%g%l%itype
ctype => clm3%g%l%c%itype
clandunit => clm3%g%l%c%landunit
wtlunit => clm3%g%l%c%p%wtlunit
pcolumn => clm3%g%l%c%p%column
plandunit => clm3%g%l%c%p%landunit
npfts => clm3%g%l%npfts
pfti => clm3%g%l%pfti
if (c2l_scale_type == 'unity') then
do c = lbc,ubc
scale_c2l(c) = 1.0_r8
end do
else if (c2l_scale_type == 'urbanf') then
do c = lbc,ubc
l = clandunit(c)
if (ltype(l) == isturb) then
if (ctype(c) == icol_sunwall) then
scale_c2l(c) = 3.0 * canyon_hwr(l)
else if (ctype(c) == icol_shadewall) then
scale_c2l(c) = 3.0 * canyon_hwr(l)
else if (ctype(c) == icol_road_perv .or. ctype(c) == icol_road_imperv) then
scale_c2l(c) = 3.0_r8
else if (ctype(c) == icol_roof) then
scale_c2l(c) = 1.0_r8
end if
else
scale_c2l(c) = 1.0_r8
end if
end do
else if (c2l_scale_type == 'urbans') then
do c = lbc,ubc
l = clandunit(c)
if (ltype(l) == isturb) then
if (ctype(c) == icol_sunwall) then
scale_c2l(c) = (3.0 * canyon_hwr(l)) / (2.*canyon_hwr(l) + 1.)
else if (ctype(c) == icol_shadewall) then
scale_c2l(c) = (3.0 * canyon_hwr(l)) / (2.*canyon_hwr(l) + 1.)
else if (ctype(c) == icol_road_perv .or. ctype(c) == icol_road_imperv) then
scale_c2l(c) = 3.0 / (2.*canyon_hwr(l) + 1.)
else if (ctype(c) == icol_roof) then
scale_c2l(c) = 1.0_r8
end if
else
scale_c2l(c) = 1.0_r8
end if
end do
else if (c2l_scale_type == 'urbanh') then
do c = lbc,ubc
l = clandunit(c)
if (ltype(l) == isturb) then
if (ctype(c) == icol_sunwall) then
scale_c2l(c) = spval
else if (ctype(c) == icol_shadewall) then
scale_c2l(c) = spval
else if (ctype(c) == icol_road_perv .or. ctype(c) == icol_road_imperv) then
scale_c2l(c) = spval
else if (ctype(c) == icol_roof) then
scale_c2l(c) = spval
end if
else
scale_c2l(c) = 1.0_r8
end if
end do
else
write(iulog,*)'p2l_1d error: scale type ',c2l_scale_type,' not supported'
call endrun
()
end if
if (p2c_scale_type == 'unity') then
do p = lbp,ubp
scale_p2c(p) = 1.0_r8
end do
else
write(iulog,*)'p2l_1d error: scale type ',p2c_scale_type,' not supported'
call endrun
()
end if
larr(:) = spval
sumwt(:) = 0._r8
#if (defined CPP_VECTOR)
!dir$ nointerchange
do pi = 1,max_pft_per_lu
!dir$ concurrent
!cdir nodep
do l = lbl,ubl
if (pi <= npfts(l)) then
p = pfti(l) + pi - 1
if (wtlunit(p) /= 0._r8) then
if (parr(p) /= spval) then
larr(l) = 0._r8
end if
end if
end if
end do
end do
!dir$ nointerchange
do pi = 1,max_pft_per_lu
!dir$ concurrent
!cdir nodep
do l = lbl,ubl
if (pi <= npfts(l)) then
p = pfti(l) + pi - 1
if (wtlunit(p) /= 0._r8) then
c = pcolumn(p)
if (parr(p) /= spval .and. scale_c2l(c) /= spval) then
larr(l) = larr(l) + parr(p) * scale_p2c(p) * scale_c2l(c) * wtlunit(p)
sumwt(l) = sumwt(l) + wtlunit(p)
end if
end if
end if
end do
end do
#else
do p = lbp,ubp
if (wtlunit(p) /= 0._r8) then
c = pcolumn(p)
if (parr(p) /= spval .and. scale_c2l(c) /= spval) then
l = plandunit(p)
if (sumwt(l) == 0._r8) larr(l) = 0._r8
larr(l) = larr(l) + parr(p) * scale_p2c(p) * scale_c2l(c) * wtlunit(p)
sumwt(l) = sumwt(l) + wtlunit(p)
end if
end if
end do
#endif
found = .false.
do l = lbl,ubl
if (sumwt(l) > 1.0_r8 + 1.e-6_r8) then
found = .true.
index = l
else if (sumwt(l) /= 0._r8) then
larr(l) = larr(l)/sumwt(l)
end if
end do
if (found) then
write(iulog,*)'p2l_1d error: sumwt is greater than 1.0 at l= ',index
call endrun
()
end if
end subroutine p2l_1d
!-----------------------------------------------------------------------
!BOP
!
! !IROUTINE: p2l_2d
!
! !INTERFACE:
subroutine p2l_2d(lbp, ubp, lbc, ubc, lbl, ubl, num2d, parr, larr, & 1,4
p2c_scale_type, c2l_scale_type)
!
! !DESCRIPTION:
! Perfrom subgrid-average from pfts to landunits
! Averaging is only done for points that are not equal to "spval".
!
! !USES:
use clm_varpar
, only : max_pft_per_lu
!
! !ARGUMENTS:
implicit none
integer , intent(in) :: lbp, ubp ! beginning and ending pft indices
integer , intent(in) :: lbc, ubc ! beginning and ending column indices
integer , intent(in) :: lbl, ubl ! beginning and ending landunit indices
integer , intent(in) :: num2d ! size of second dimension
real(r8), intent(in) :: parr(lbp:ubp,num2d) ! input pft array
real(r8), intent(out) :: larr(lbl:ubl,num2d) ! output gridcell array
character(len=*), intent(in) :: p2c_scale_type ! scale factor type for averaging
character(len=*), intent(in) :: c2l_scale_type ! scale factor type for averaging
!
! !REVISION HISTORY:
! Created by Mariana Vertenstein 12/03
!
!
! !LOCAL VARIABLES:
!EOP
integer :: j,pi,p,c,l,index ! indices
logical :: found ! temporary for error check
real(r8) :: sumwt(lbl:ubl) ! sum of weights
real(r8) :: scale_p2c(lbc:ubc) ! scale factor for pft->column mapping
real(r8) :: scale_c2l(lbc:ubc) ! scale factor for column->landunit mapping
real(r8), pointer :: wtlunit(:) ! weight of pft relative to landunit
integer , pointer :: pcolumn(:) ! column of corresponding pft
integer , pointer :: plandunit(:) ! landunit of corresponding pft
integer , pointer :: npfts(:) ! number of pfts in landunit
integer , pointer :: pfti(:) ! initial pft index in landunit
integer , pointer :: clandunit(:) ! landunit of corresponding column
integer , pointer :: ctype(:) ! column type
integer , pointer :: ltype(:) ! landunit type
real(r8), pointer :: canyon_hwr(:) ! urban canyon height to width ratio
!------------------------------------------------------------------------
canyon_hwr => clm3%g%l%canyon_hwr
ltype => clm3%g%l%itype
clandunit => clm3%g%l%c%landunit
ctype => clm3%g%l%c%itype
wtlunit => clm3%g%l%c%p%wtlunit
pcolumn => clm3%g%l%c%p%column
plandunit => clm3%g%l%c%p%landunit
npfts => clm3%g%l%npfts
pfti => clm3%g%l%pfti
if (c2l_scale_type == 'unity') then
do c = lbc,ubc
scale_c2l(c) = 1.0_r8
end do
else if (c2l_scale_type == 'urbanf') then
do c = lbc,ubc
l = clandunit(c)
if (ltype(l) == isturb) then
if (ctype(c) == icol_sunwall) then
scale_c2l(c) = 3.0 * canyon_hwr(l)
else if (ctype(c) == icol_shadewall) then
scale_c2l(c) = 3.0 * canyon_hwr(l)
else if (ctype(c) == icol_road_perv .or. ctype(c) == icol_road_imperv) then
scale_c2l(c) = 3.0_r8
else if (ctype(c) == icol_roof) then
scale_c2l(c) = 1.0_r8
end if
else
scale_c2l(c) = 1.0_r8
end if
end do
else if (c2l_scale_type == 'urbans') then
do c = lbc,ubc
l = clandunit(c)
if (ltype(l) == isturb) then
if (ctype(c) == icol_sunwall) then
scale_c2l(c) = (3.0 * canyon_hwr(l)) / (2.*canyon_hwr(l) + 1.)
else if (ctype(c) == icol_shadewall) then
scale_c2l(c) = (3.0 * canyon_hwr(l)) / (2.*canyon_hwr(l) + 1.)
else if (ctype(c) == icol_road_perv .or. ctype(c) == icol_road_imperv) then
scale_c2l(c) = 3.0 / (2.*canyon_hwr(l) + 1.)
else if (ctype(c) == icol_roof) then
scale_c2l(c) = 1.0_r8
end if
else
scale_c2l(c) = 1.0_r8
end if
end do
else if (c2l_scale_type == 'urbanh') then
do c = lbc,ubc
l = clandunit(c)
if (ltype(l) == isturb) then
if (ctype(c) == icol_sunwall) then
scale_c2l(c) = spval
else if (ctype(c) == icol_shadewall) then
scale_c2l(c) = spval
else if (ctype(c) == icol_road_perv .or. ctype(c) == icol_road_imperv) then
scale_c2l(c) = spval
else if (ctype(c) == icol_roof) then
scale_c2l(c) = spval
end if
else
scale_c2l(c) = 1.0_r8
end if
end do
else
write(iulog,*)'p2l_2d error: scale type ',c2l_scale_type,' not supported'
call endrun
()
end if
if (p2c_scale_type == 'unity') then
do p = lbp,ubp
scale_p2c(p) = 1.0_r8
end do
else
write(iulog,*)'p2l_2d error: scale type ',p2c_scale_type,' not supported'
call endrun
()
end if
larr(:,:) = spval
do j = 1,num2d
sumwt(:) = 0._r8
#if (defined CPP_VECTOR)
!dir$ nointerchange
do pi = 1,max_pft_per_lu
!dir$ concurrent
!cdir nodep
do l = lbl,ubl
if (pi <= npfts(l)) then
p = pfti(l) + pi - 1
if (wtlunit(p) /= 0._r8) then
if (parr(p,j) /= spval) then
larr(l,j) = 0._r8
end if
end if
end if
end do
end do
!dir$ nointerchange
do pi = 1,max_pft_per_lu
!dir$ concurrent
!cdir nodep
do l = lbl,ubl
if (pi <= npfts(l)) then
p = pfti(l) + pi - 1
if (wtlunit(p) /= 0._r8) then
c = pcolumn(p)
if (parr(p,j) /= spval .and. scale_c2l(c) /= spval) then
larr(l,j) = larr(l,j) + parr(p,j) * scale_p2c(p) * scale_c2l(c) * wtlunit(p)
sumwt(l) = sumwt(l) + wtlunit(p)
end if
end if
end if
end do
end do
#else
do p = lbp,ubp
if (wtlunit(p) /= 0._r8) then
c = pcolumn(p)
if (parr(p,j) /= spval .and. scale_c2l(c) /= spval) then
l = plandunit(p)
if (sumwt(l) == 0._r8) larr(l,j) = 0._r8
larr(l,j) = larr(l,j) + parr(p,j) * scale_p2c(p) * scale_c2l(c) * wtlunit(p)
sumwt(l) = sumwt(l) + wtlunit(p)
end if
end if
end do
#endif
found = .false.
do l = lbl,ubl
if (sumwt(l) > 1.0_r8 + 1.e-6_r8) then
found = .true.
index = l
else if (sumwt(l) /= 0._r8) then
larr(l,j) = larr(l,j)/sumwt(l)
end if
end do
if (found) then
write(iulog,*)'p2l_2d error: sumwt is greater than 1.0 at l= ',index,' j= ',j
call endrun
()
end if
end do
end subroutine p2l_2d
!-----------------------------------------------------------------------
!BOP
!
! !IROUTINE: p2g_1d
!
! !INTERFACE:
subroutine p2g_1d(lbp, ubp, lbc, ubc, lbl, ubl, lbg, ubg, parr, garr, & 1,5
p2c_scale_type, c2l_scale_type, l2g_scale_type)
!
! !DESCRIPTION:
! Perfrom subgrid-average from pfts to gridcells.
! Averaging is only done for points that are not equal to "spval".
!
! !USES:
use clm_varpar
, only : max_pft_per_gcell
!
! !ARGUMENTS:
implicit none
integer , intent(in) :: lbp, ubp ! beginning and ending pft indices
integer , intent(in) :: lbc, ubc ! beginning and ending column indices
integer , intent(in) :: lbl, ubl ! beginning and ending landunit indices
integer , intent(in) :: lbg, ubg ! beginning and ending gridcell indices
real(r8), intent(in) :: parr(lbp:ubp) ! input pft array
real(r8), intent(out) :: garr(lbg:ubg) ! output gridcell array
character(len=*), intent(in) :: p2c_scale_type ! scale factor type for averaging
character(len=*), intent(in) :: c2l_scale_type ! scale factor type for averaging
character(len=*), intent(in) :: l2g_scale_type ! scale factor type for averaging
!
! !REVISION HISTORY:
! Created by Mariana Vertenstein 12/03
!
! !LOCAL VARIABLES:
!EOP
integer :: pi,p,c,l,g,index ! indices
logical :: found ! temporary for error check
real(r8) :: scale_p2c(lbp:ubp) ! scale factor
real(r8) :: scale_c2l(lbc:ubc) ! scale factor
real(r8) :: scale_l2g(lbl:ubl) ! scale factor
real(r8) :: sumwt(lbg:ubg) ! sum of weights
real(r8), pointer :: wtgcell(:) ! weight of pfts relative to gridcells
integer , pointer :: pcolumn(:) ! column of corresponding pft
integer , pointer :: plandunit(:) ! landunit of corresponding pft
integer , pointer :: pgridcell(:) ! gridcell of corresponding pft
integer , pointer :: npfts(:) ! number of pfts in gridcell
integer , pointer :: pfti(:) ! initial pft index in gridcell
integer , pointer :: ctype(:) ! column type
integer , pointer :: clandunit(:) ! landunit of corresponding column
integer , pointer :: ltype(:) ! landunit type
real(r8), pointer :: canyon_hwr(:) ! urban canyon height to width ratio
!------------------------------------------------------------------------
canyon_hwr => clm3%g%l%canyon_hwr
ltype => clm3%g%l%itype
clandunit => clm3%g%l%c%landunit
ctype => clm3%g%l%c%itype
wtgcell => clm3%g%l%c%p%wtgcell
pcolumn => clm3%g%l%c%p%column
pgridcell => clm3%g%l%c%p%gridcell
plandunit => clm3%g%l%c%p%landunit
npfts => clm3%g%npfts
pfti => clm3%g%pfti
if (l2g_scale_type == 'unity') then
do l = lbl,ubl
scale_l2g(l) = 1.0_r8
end do
else
write(iulog,*)'p2g_1d error: scale type ',l2g_scale_type,' not supported'
call endrun
()
end if
if (c2l_scale_type == 'unity') then
do c = lbc,ubc
scale_c2l(c) = 1.0_r8
end do
else if (c2l_scale_type == 'urbanf') then
do c = lbc,ubc
l = clandunit(c)
if (ltype(l) == isturb) then
if (ctype(c) == icol_sunwall) then
scale_c2l(c) = 3.0 * canyon_hwr(l)
else if (ctype(c) == icol_shadewall) then
scale_c2l(c) = 3.0 * canyon_hwr(l)
else if (ctype(c) == icol_road_perv .or. ctype(c) == icol_road_imperv) then
scale_c2l(c) = 3.0_r8
else if (ctype(c) == icol_roof) then
scale_c2l(c) = 1.0_r8
end if
else
scale_c2l(c) = 1.0_r8
end if
end do
else if (c2l_scale_type == 'urbans') then
do c = lbc,ubc
l = clandunit(c)
if (ltype(l) == isturb) then
if (ctype(c) == icol_sunwall) then
scale_c2l(c) = (3.0 * canyon_hwr(l)) / (2.*canyon_hwr(l) + 1.)
else if (ctype(c) == icol_shadewall) then
scale_c2l(c) = (3.0 * canyon_hwr(l)) / (2.*canyon_hwr(l) + 1.)
else if (ctype(c) == icol_road_perv .or. ctype(c) == icol_road_imperv) then
scale_c2l(c) = 3.0 / (2.*canyon_hwr(l) + 1.)
else if (ctype(c) == icol_roof) then
scale_c2l(c) = 1.0_r8
end if
else
scale_c2l(c) = 1.0_r8
end if
end do
else if (c2l_scale_type == 'urbanh') then
do c = lbc,ubc
l = clandunit(c)
if (ltype(l) == isturb) then
if (ctype(c) == icol_sunwall) then
scale_c2l(c) = spval
else if (ctype(c) == icol_shadewall) then
scale_c2l(c) = spval
else if (ctype(c) == icol_road_perv .or. ctype(c) == icol_road_imperv) then
scale_c2l(c) = spval
else if (ctype(c) == icol_roof) then
scale_c2l(c) = spval
end if
else
scale_c2l(c) = 1.0_r8
end if
end do
else
write(iulog,*)'p2g_1d error: scale type ',c2l_scale_type,' not supported'
call endrun
()
end if
if (p2c_scale_type == 'unity') then
do p = lbp,ubp
scale_p2c(p) = 1.0_r8
end do
else
write(iulog,*)'p2g_1d error: scale type ',c2l_scale_type,' not supported'
call endrun
()
end if
garr(:) = spval
sumwt(:) = 0._r8
#if (defined CPP_VECTOR)
!dir$ nointerchange
do pi = 1,max_pft_per_gcell
!dir$ concurrent
!cdir nodep
do g = lbg,ubg
if (pi <= npfts(g)) then
p = pfti(g) + pi - 1
if (wtgcell(p) /= 0._r8) then
if (parr(p) /= spval) then
garr(g) = 0._r8
end if
end if
end if
end do
end do
!dir$ nointerchange
do pi = 1,max_pft_per_gcell
!dir$ concurrent
!cdir nodep
do g = lbg,ubg
if (pi <= npfts(g)) then
p = pfti(g) + pi - 1
if (wtgcell(p) /= 0._r8) then
c = pcolumn(p)
if (parr(p) /= spval .and. scale_c2l(c) /= spval) then
l = plandunit(p)
garr(g) = garr(g) + parr(p) * scale_p2c(p) * scale_c2l(c) * scale_l2g(l) * wtgcell(p)
sumwt(g) = sumwt(g) + wtgcell(p)
end if
end if
end if
end do
end do
#else
do p = lbp,ubp
if (wtgcell(p) /= 0._r8) then
c = pcolumn(p)
if (parr(p) /= spval .and. scale_c2l(c) /= spval) then
l = plandunit(p)
g = pgridcell(p)
if (sumwt(g) == 0._r8) garr(g) = 0._r8
garr(g) = garr(g) + parr(p) * scale_p2c(p) * scale_c2l(c) * scale_l2g(l) * wtgcell(p)
sumwt(g) = sumwt(g) + wtgcell(p)
end if
end if
end do
#endif
found = .false.
do g = lbg, ubg
if (sumwt(g) > 1.0_r8 + 1.e-6_r8) then
found = .true.
index = g
else if (sumwt(g) /= 0._r8) then
garr(g) = garr(g)/sumwt(g)
end if
end do
if (found) then
write(iulog,*)'p2g_1d error: sumwt is greater than 1.0 at g= ',index
call endrun
()
end if
end subroutine p2g_1d
!-----------------------------------------------------------------------
!BOP
!
! !IROUTINE: p2g_2d
!
! !INTERFACE:
subroutine p2g_2d(lbp, ubp, lbc, ubc, lbl, ubl, lbg, ubg, num2d, & 1,5
parr, garr, p2c_scale_type, c2l_scale_type, l2g_scale_type)
!
! !DESCRIPTION:
! Perfrom subgrid-average from pfts to gridcells.
! Averaging is only done for points that are not equal to "spval".
!
! !USES:
use clm_varpar
, only : max_pft_per_gcell
!
! !ARGUMENTS:
implicit none
integer , intent(in) :: lbp, ubp ! beginning and ending pft indices
integer , intent(in) :: lbc, ubc ! beginning and ending column indices
integer , intent(in) :: lbl, ubl ! beginning and ending landunit indices
integer , intent(in) :: lbg, ubg ! beginning and ending gridcell indices
integer , intent(in) :: num2d ! size of second dimension
real(r8), intent(in) :: parr(lbp:ubp,num2d) ! input pft array
real(r8), intent(out) :: garr(lbg:ubg,num2d) ! output gridcell array
character(len=*), intent(in) :: p2c_scale_type ! scale factor type for averaging
character(len=*), intent(in) :: c2l_scale_type ! scale factor type for averaging
character(len=*), intent(in) :: l2g_scale_type ! scale factor type for averaging
!
! !REVISION HISTORY:
! Created by Mariana Vertenstein 12/03
!
!
! !LOCAL VARIABLES:
!EOP
integer :: j,pi,p,c,l,g,index ! indices
logical :: found ! temporary for error check
real(r8) :: scale_p2c(lbp:ubp) ! scale factor
real(r8) :: scale_c2l(lbc:ubc) ! scale factor
real(r8) :: scale_l2g(lbl:ubl) ! scale factor
real(r8) :: sumwt(lbg:ubg) ! sum of weights
real(r8), pointer :: wtgcell(:) ! weight of pfts relative to gridcells
integer , pointer :: pcolumn(:) ! column of corresponding pft
integer , pointer :: plandunit(:) ! landunit of corresponding pft
integer , pointer :: pgridcell(:) ! gridcell of corresponding pft
integer , pointer :: npfts(:) ! number of pfts in gridcell
integer , pointer :: pfti(:) ! initial pft index in gridcell
integer , pointer :: clandunit(:) ! landunit of corresponding column
integer , pointer :: ctype(:) ! column type
integer , pointer :: ltype(:) ! landunit type
real(r8), pointer :: canyon_hwr(:) ! urban canyon height to width ratio
!------------------------------------------------------------------------
canyon_hwr => clm3%g%l%canyon_hwr
ltype => clm3%g%l%itype
clandunit => clm3%g%l%c%landunit
ctype => clm3%g%l%c%itype
wtgcell => clm3%g%l%c%p%wtgcell
pcolumn => clm3%g%l%c%p%column
pgridcell => clm3%g%l%c%p%gridcell
plandunit => clm3%g%l%c%p%landunit
npfts => clm3%g%npfts
pfti => clm3%g%pfti
if (l2g_scale_type == 'unity') then
do l = lbl,ubl
scale_l2g(l) = 1.0_r8
end do
else
write(iulog,*)'p2g_2d error: scale type ',l2g_scale_type,' not supported'
call endrun
()
end if
if (c2l_scale_type == 'unity') then
do c = lbc,ubc
scale_c2l(c) = 1.0_r8
end do
else if (c2l_scale_type == 'urbanf') then
do c = lbc,ubc
l = clandunit(c)
if (ltype(l) == isturb) then
if (ctype(c) == icol_sunwall) then
scale_c2l(c) = 3.0 * canyon_hwr(l)
else if (ctype(c) == icol_shadewall) then
scale_c2l(c) = 3.0 * canyon_hwr(l)
else if (ctype(c) == icol_road_perv .or. ctype(c) == icol_road_imperv) then
scale_c2l(c) = 3.0_r8
else if (ctype(c) == icol_roof) then
scale_c2l(c) = 1.0_r8
end if
else
scale_c2l(c) = 1.0_r8
end if
end do
else if (c2l_scale_type == 'urbans') then
do c = lbc,ubc
l = clandunit(c)
if (ltype(l) == isturb) then
if (ctype(c) == icol_sunwall) then
scale_c2l(c) = (3.0 * canyon_hwr(l)) / (2.*canyon_hwr(l) + 1.)
else if (ctype(c) == icol_shadewall) then
scale_c2l(c) = (3.0 * canyon_hwr(l)) / (2.*canyon_hwr(l) + 1.)
else if (ctype(c) == icol_road_perv .or. ctype(c) == icol_road_imperv) then
scale_c2l(c) = 3.0 / (2.*canyon_hwr(l) + 1.)
else if (ctype(c) == icol_roof) then
scale_c2l(c) = 1.0_r8
end if
else
scale_c2l(c) = 1.0_r8
end if
end do
else if (c2l_scale_type == 'urbanh') then
do c = lbc,ubc
l = clandunit(c)
if (ltype(l) == isturb) then
if (ctype(c) == icol_sunwall) then
scale_c2l(c) = spval
else if (ctype(c) == icol_shadewall) then
scale_c2l(c) = spval
else if (ctype(c) == icol_road_perv .or. ctype(c) == icol_road_imperv) then
scale_c2l(c) = spval
else if (ctype(c) == icol_roof) then
scale_c2l(c) = spval
end if
else
scale_c2l(c) = 1.0_r8
end if
end do
else
write(iulog,*)'p2g_2d error: scale type ',c2l_scale_type,' not supported'
call endrun
()
end if
if (p2c_scale_type == 'unity') then
do p = lbp,ubp
scale_p2c(p) = 1.0_r8
end do
else
write(iulog,*)'p2g_2d error: scale type ',c2l_scale_type,' not supported'
call endrun
()
end if
garr(:,:) = spval
do j = 1,num2d
sumwt(:) = 0._r8
#if (defined CPP_VECTOR)
!dir$ nointerchange
do pi = 1,max_pft_per_gcell
!dir$ concurrent
!cdir nodep
do g = lbg,ubg
if (pi <= npfts(g)) then
p = pfti(g) + pi - 1
if (wtgcell(p) /= 0._r8) then
if (parr(p,j) /= spval) then
garr(g,j) = 0._r8
end if
end if
end if
end do
end do
!dir$ nointerchange
do pi = 1,max_pft_per_gcell
!dir$ concurrent
!cdir nodep
do g = lbg,ubg
if (pi <= npfts(g)) then
p = pfti(g) + pi - 1
if (wtgcell(p) /= 0._r8) then
c = pcolumn(p)
if (parr(p,j) /= spval .and. scale_c2l(c) /= spval) then
l = plandunit(p)
garr(g,j) = garr(g,j) + parr(p,j) * scale_p2c(p) * scale_c2l(c) * scale_l2g(l) * wtgcell(p)
sumwt(g) = sumwt(g) + wtgcell(p)
end if
end if
end if
end do
end do
#else
do p = lbp,ubp
if (wtgcell(p) /= 0._r8) then
c = pcolumn(p)
if (parr(p,j) /= spval .and. scale_c2l(c) /= spval) then
l = plandunit(p)
g = pgridcell(p)
if (sumwt(g) == 0._r8) garr(g,j) = 0._r8
garr(g,j) = garr(g,j) + parr(p,j) * scale_p2c(p) * scale_c2l(c) * scale_l2g(l) * wtgcell(p)
sumwt(g) = sumwt(g) + wtgcell(p)
end if
end if
end do
#endif
found = .false.
do g = lbg, ubg
if (sumwt(g) > 1.0_r8 + 1.e-6_r8) then
found = .true.
index = g
else if (sumwt(g) /= 0._r8) then
garr(g,j) = garr(g,j)/sumwt(g)
end if
end do
if (found) then
write(iulog,*)'p2g_2d error: sumwt gt 1.0 at g/sumwt = ',index,sumwt(index)
call endrun
()
end if
end do
end subroutine p2g_2d
!-----------------------------------------------------------------------
!BOP
!
! !IROUTINE: c2l_1d
!
! !INTERFACE:
subroutine c2l_1d (lbc, ubc, lbl, ubl, carr, larr, c2l_scale_type) 1,2
!
! !DESCRIPTION:
! Perfrom subgrid-average from columns to landunits
! Averaging is only done for points that are not equal to "spval".
!
! !ARGUMENTS:
implicit none
integer , intent(in) :: lbc, ubc ! beginning and ending column indices
integer , intent(in) :: lbl, ubl ! beginning and ending landunit indices
real(r8), intent(in) :: carr(lbc:ubc) ! input column array
real(r8), intent(out) :: larr(lbl:ubl) ! output landunit array
character(len=*), intent(in) :: c2l_scale_type ! scale factor type for averaging
!
! !REVISION HISTORY:
! Created by Mariana Vertenstein 12/03
!
!
! !LOCAL VARIABLES:
!EOP
integer :: ci,c,l,index ! indices
integer :: max_col_per_lu ! max columns per landunit; on the fly
logical :: found ! temporary for error check
real(r8) :: scale_c2l(lbc:ubc) ! scale factor for column->landunit mapping
real(r8) :: sumwt(lbl:ubl) ! sum of weights
real(r8), pointer :: wtlunit(:) ! weight of landunits relative to gridcells
integer , pointer :: clandunit(:) ! gridcell of corresponding column
integer , pointer :: ncolumns(:) ! number of columns in landunit
integer , pointer :: coli(:) ! initial column index in landunit
integer , pointer :: ctype(:) ! column type
integer , pointer :: ltype(:) ! landunit type
real(r8), pointer :: canyon_hwr(:) ! urban canyon height to width ratio
!------------------------------------------------------------------------
ctype => clm3%g%l%c%itype
ltype => clm3%g%l%itype
canyon_hwr => clm3%g%l%canyon_hwr
wtlunit => clm3%g%l%c%wtlunit
clandunit => clm3%g%l%c%landunit
ncolumns => clm3%g%l%ncolumns
coli => clm3%g%l%coli
if (c2l_scale_type == 'unity') then
do c = lbc,ubc
scale_c2l(c) = 1.0_r8
end do
else if (c2l_scale_type == 'urbanf') then
do c = lbc,ubc
l = clandunit(c)
if (ltype(l) == isturb) then
if (ctype(c) == icol_sunwall) then
scale_c2l(c) = 3.0 * canyon_hwr(l)
else if (ctype(c) == icol_shadewall) then
scale_c2l(c) = 3.0 * canyon_hwr(l)
else if (ctype(c) == icol_road_perv .or. ctype(c) == icol_road_imperv) then
scale_c2l(c) = 3.0_r8
else if (ctype(c) == icol_roof) then
scale_c2l(c) = 1.0_r8
end if
else
scale_c2l(c) = 1.0_r8
end if
end do
else if (c2l_scale_type == 'urbans') then
do c = lbc,ubc
l = clandunit(c)
if (ltype(l) == isturb) then
if (ctype(c) == icol_sunwall) then
scale_c2l(c) = (3.0 * canyon_hwr(l)) / (2.*canyon_hwr(l) + 1.)
else if (ctype(c) == icol_shadewall) then
scale_c2l(c) = (3.0 * canyon_hwr(l)) / (2.*canyon_hwr(l) + 1.)
else if (ctype(c) == icol_road_perv .or. ctype(c) == icol_road_imperv) then
scale_c2l(c) = 3.0 / (2.*canyon_hwr(l) + 1.)
else if (ctype(c) == icol_roof) then
scale_c2l(c) = 1.0_r8
end if
else
scale_c2l(c) = 1.0_r8
end if
end do
else if (c2l_scale_type == 'urbanh') then
do c = lbc,ubc
l = clandunit(c)
if (ltype(l) == isturb) then
if (ctype(c) == icol_sunwall) then
scale_c2l(c) = spval
else if (ctype(c) == icol_shadewall) then
scale_c2l(c) = spval
else if (ctype(c) == icol_road_perv .or. ctype(c) == icol_road_imperv) then
scale_c2l(c) = spval
else if (ctype(c) == icol_roof) then
scale_c2l(c) = spval
end if
else
scale_c2l(c) = 1.0_r8
end if
end do
else
write(iulog,*)'c2l_1d error: scale type ',c2l_scale_type,' not supported'
call endrun
()
end if
larr(:) = spval
sumwt(:) = 0._r8
#if (defined CPP_VECTOR)
max_col_per_lu = 0
do l = lbl,ubl
max_col_per_lu = max(ncolumns(l), max_col_per_lu)
end do
!dir$ nointerchange
do ci = 1,max_col_per_lu
!dir$ concurrent
!cdir nodep
do l = lbl,ubl
if (ci <= ncolumns(l)) then
c = coli(l) + ci - 1
if (wtlunit(c) /= 0._r8) then
if (carr(c) /= spval) then
larr(l) = 0._r8
end if
end if
end if
end do
end do
!dir$ nointerchange
do ci = 1,max_col_per_lu
!dir$ concurrent
!cdir nodep
do l = lbl,ubl
if (ci <= ncolumns(l)) then
c = coli(l) + ci - 1
if (wtlunit(c) /= 0._r8) then
if (carr(c) /= spval .and. scale_c2l(c) /= spval) then
larr(l) = larr(l) + carr(c) * scale_c2l(c) * wtlunit(c)
sumwt(l) = sumwt(l) + wtlunit(c)
end if
end if
end if
end do
end do
#else
do c = lbc,ubc
if (wtlunit(c) /= 0._r8) then
if (carr(c) /= spval .and. scale_c2l(c) /= spval) then
l = clandunit(c)
if (sumwt(l) == 0._r8) larr(l) = 0._r8
larr(l) = larr(l) + carr(c) * scale_c2l(c) * wtlunit(c)
sumwt(l) = sumwt(l) + wtlunit(c)
end if
end if
end do
#endif
found = .false.
do l = lbl,ubl
if (sumwt(l) > 1.0_r8 + 1.e-6_r8) then
found = .true.
index = l
else if (sumwt(l) /= 0._r8) then
larr(l) = larr(l)/sumwt(l)
end if
end do
if (found) then
write(iulog,*)'c2l_1d error: sumwt is greater than 1.0 at l= ',index
call endrun
()
end if
end subroutine c2l_1d
!-----------------------------------------------------------------------
!BOP
!
! !IROUTINE: c2l_2d
!
! !INTERFACE:
subroutine c2l_2d (lbc, ubc, lbl, ubl, num2d, carr, larr, c2l_scale_type) 1,2
!
! !DESCRIPTION:
! Perfrom subgrid-average from columns to landunits
! Averaging is only done for points that are not equal to "spval".
!
! !ARGUMENTS:
implicit none
integer , intent(in) :: lbc, ubc ! beginning and ending column indices
integer , intent(in) :: lbl, ubl ! beginning and ending landunit indices
integer , intent(in) :: num2d ! size of second dimension
real(r8), intent(in) :: carr(lbc:ubc,num2d) ! input column array
real(r8), intent(out) :: larr(lbl:ubl,num2d) ! output landunit array
character(len=*), intent(in) :: c2l_scale_type ! scale factor type for averaging
!
! !REVISION HISTORY:
! Created by Mariana Vertenstein 12/03
!
!
! !LOCAL VARIABLES:
!EOP
integer :: j,l,ci,c,index ! indices
integer :: max_col_per_lu ! max columns per landunit; on the fly
logical :: found ! temporary for error check
real(r8) :: scale_c2l(lbc:ubc) ! scale factor for column->landunit mapping
real(r8) :: sumwt(lbl:ubl) ! sum of weights
real(r8), pointer :: wtlunit(:) ! weight of column relative to landunit
integer , pointer :: clandunit(:) ! landunit of corresponding column
integer , pointer :: ncolumns(:) ! number of columns in landunit
integer , pointer :: coli(:) ! initial column index in landunit
integer , pointer :: ctype(:) ! column type
integer , pointer :: ltype(:) ! landunit type
real(r8), pointer :: canyon_hwr(:) ! urban canyon height to width ratio
!------------------------------------------------------------------------
ctype => clm3%g%l%c%itype
ltype => clm3%g%l%itype
canyon_hwr => clm3%g%l%canyon_hwr
wtlunit => clm3%g%l%c%wtlunit
clandunit => clm3%g%l%c%landunit
ncolumns => clm3%g%l%ncolumns
coli => clm3%g%l%coli
if (c2l_scale_type == 'unity') then
do c = lbc,ubc
scale_c2l(c) = 1.0_r8
end do
else if (c2l_scale_type == 'urbanf') then
do c = lbc,ubc
l = clandunit(c)
if (ltype(l) == isturb) then
if (ctype(c) == icol_sunwall) then
scale_c2l(c) = 3.0 * canyon_hwr(l)
else if (ctype(c) == icol_shadewall) then
scale_c2l(c) = 3.0 * canyon_hwr(l)
else if (ctype(c) == icol_road_perv .or. ctype(c) == icol_road_imperv) then
scale_c2l(c) = 3.0_r8
else if (ctype(c) == icol_roof) then
scale_c2l(c) = 1.0_r8
end if
else
scale_c2l(c) = 1.0_r8
end if
end do
else if (c2l_scale_type == 'urbans') then
do c = lbc,ubc
l = clandunit(c)
if (ltype(l) == isturb) then
if (ctype(c) == icol_sunwall) then
scale_c2l(c) = (3.0 * canyon_hwr(l)) / (2.*canyon_hwr(l) + 1.)
else if (ctype(c) == icol_shadewall) then
scale_c2l(c) = (3.0 * canyon_hwr(l)) / (2.*canyon_hwr(l) + 1.)
else if (ctype(c) == icol_road_perv .or. ctype(c) == icol_road_imperv) then
scale_c2l(c) = 3.0 / (2.*canyon_hwr(l) + 1.)
else if (ctype(c) == icol_roof) then
scale_c2l(c) = 1.0_r8
end if
else
scale_c2l(c) = 1.0_r8
end if
end do
else if (c2l_scale_type == 'urbanh') then
do c = lbc,ubc
l = clandunit(c)
if (ltype(l) == isturb) then
if (ctype(c) == icol_sunwall) then
scale_c2l(c) = spval
else if (ctype(c) == icol_shadewall) then
scale_c2l(c) = spval
else if (ctype(c) == icol_road_perv .or. ctype(c) == icol_road_imperv) then
scale_c2l(c) = spval
else if (ctype(c) == icol_roof) then
scale_c2l(c) = spval
end if
else
scale_c2l(c) = 1.0_r8
end if
end do
else
write(iulog,*)'c2l_2d error: scale type ',c2l_scale_type,' not supported'
call endrun
()
end if
#if (defined CPP_VECTOR)
max_col_per_lu = 0
do l = lbl,ubl
max_col_per_lu = max(ncolumns(l), max_col_per_lu)
end do
#endif
larr(:,:) = spval
do j = 1,num2d
sumwt(:) = 0._r8
#if (defined CPP_VECTOR)
!dir$ nointerchange
do ci = 1,max_col_per_lu
!dir$ concurrent
!cdir nodep
do l = lbl,ubl
if (ci <= ncolumns(l)) then
c = coli(l) + ci - 1
if (wtlunit(c) /= 0._r8) then
if (carr(c,j) /= spval) then
larr(l,j) = 0._r8
end if
end if
end if
end do
end do
!dir$ nointerchange
do ci = 1,max_col_per_lu
!dir$ concurrent
!cdir nodep
do l = lbl,ubl
if (ci <= ncolumns(l)) then
c = coli(l) + ci - 1
if (wtlunit(c) /= 0._r8) then
if (carr(c,j) /= spval .and. scale_c2l(c) /= spval) then
larr(l,j) = larr(l,j) + carr(c,j) * scale_c2l(c) * wtlunit(c)
sumwt(l) = sumwt(l) + wtlunit(c)
end if
end if
end if
end do
end do
#else
do c = lbc,ubc
if (wtlunit(c) /= 0._r8) then
if (carr(c,j) /= spval .and. scale_c2l(c) /= spval) then
l = clandunit(c)
if (sumwt(l) == 0._r8) larr(l,j) = 0._r8
larr(l,j) = larr(l,j) + carr(c,j) * scale_c2l(c) * wtlunit(c)
sumwt(l) = sumwt(l) + wtlunit(c)
end if
end if
end do
#endif
found = .false.
do l = lbl,ubl
if (sumwt(l) > 1.0_r8 + 1.e-6_r8) then
found = .true.
index = l
else if (sumwt(l) /= 0._r8) then
larr(l,j) = larr(l,j)/sumwt(l)
end if
end do
if (found) then
write(iulog,*)'c2l_2d error: sumwt is greater than 1.0 at l= ',index,' lev= ',j
call endrun
()
end if
end do
end subroutine c2l_2d
!-----------------------------------------------------------------------
!BOP
!
! !IROUTINE: c2g_1d
!
! !INTERFACE:
subroutine c2g_1d(lbc, ubc, lbl, ubl, lbg, ubg, carr, garr, & 1,3
c2l_scale_type, l2g_scale_type)
!
! !DESCRIPTION:
! Perfrom subgrid-average from columns to gridcells.
! Averaging is only done for points that are not equal to "spval".
!
! !ARGUMENTS:
implicit none
integer , intent(in) :: lbc, ubc ! beginning and ending column indices
integer , intent(in) :: lbl, ubl ! beginning and ending landunit indices
integer , intent(in) :: lbg, ubg ! beginning and ending landunit indices
real(r8), intent(in) :: carr(lbc:ubc) ! input column array
real(r8), intent(out) :: garr(lbg:ubg) ! output gridcell array
character(len=*), intent(in) :: c2l_scale_type ! scale factor type for averaging
character(len=*), intent(in) :: l2g_scale_type ! scale factor type for averaging
!
! !REVISION HISTORY:
! Created by Mariana Vertenstein 12/03
!
!
! !LOCAL VARIABLES:
!EOP
integer :: ci,c,l,g,index ! indices
integer :: max_col_per_gcell ! max columns per gridcell; on the fly
logical :: found ! temporary for error check
real(r8) :: scale_c2l(lbc:ubc) ! scale factor
real(r8) :: scale_l2g(lbl:ubl) ! scale factor
real(r8) :: sumwt(lbg:ubg) ! sum of weights
real(r8), pointer :: wtgcell(:) ! weight of columns relative to gridcells
integer , pointer :: clandunit(:) ! landunit of corresponding column
integer , pointer :: cgridcell(:) ! gridcell of corresponding column
integer , pointer :: ncolumns(:) ! number of columns in gridcell
integer , pointer :: coli(:) ! initial column index in gridcell
integer , pointer :: ctype(:) ! column type
integer , pointer :: ltype(:) ! landunit type
real(r8), pointer :: canyon_hwr(:) ! urban canyon height to width ratio
!------------------------------------------------------------------------
ctype => clm3%g%l%c%itype
ltype => clm3%g%l%itype
canyon_hwr => clm3%g%l%canyon_hwr
wtgcell => clm3%g%l%c%wtgcell
clandunit => clm3%g%l%c%landunit
cgridcell => clm3%g%l%c%gridcell
ncolumns => clm3%g%ncolumns
coli => clm3%g%coli
if (l2g_scale_type == 'unity') then
do l = lbl,ubl
scale_l2g(l) = 1.0_r8
end do
else
write(iulog,*)'c2l_1d error: scale type ',l2g_scale_type,' not supported'
call endrun
()
end if
if (c2l_scale_type == 'unity') then
do c = lbc,ubc
scale_c2l(c) = 1.0_r8
end do
else if (c2l_scale_type == 'urbanf') then
do c = lbc,ubc
l = clandunit(c)
if (ltype(l) == isturb) then
if (ctype(c) == icol_sunwall) then
scale_c2l(c) = 3.0 * canyon_hwr(l)
else if (ctype(c) == icol_shadewall) then
scale_c2l(c) = 3.0 * canyon_hwr(l)
else if (ctype(c) == icol_road_perv .or. ctype(c) == icol_road_imperv) then
scale_c2l(c) = 3.0_r8
else if (ctype(c) == icol_roof) then
scale_c2l(c) = 1.0_r8
end if
else
scale_c2l(c) = 1.0_r8
end if
end do
else if (c2l_scale_type == 'urbans') then
do c = lbc,ubc
l = clandunit(c)
if (ltype(l) == isturb) then
if (ctype(c) == icol_sunwall) then
scale_c2l(c) = (3.0 * canyon_hwr(l)) / (2.*canyon_hwr(l) + 1.)
else if (ctype(c) == icol_shadewall) then
scale_c2l(c) = (3.0 * canyon_hwr(l)) / (2.*canyon_hwr(l) + 1.)
else if (ctype(c) == icol_road_perv .or. ctype(c) == icol_road_imperv) then
scale_c2l(c) = 3.0 / (2.*canyon_hwr(l) + 1.)
else if (ctype(c) == icol_roof) then
scale_c2l(c) = 1.0_r8
end if
else
scale_c2l(c) = 1.0_r8
end if
end do
else if (c2l_scale_type == 'urbanh') then
do c = lbc,ubc
l = clandunit(c)
if (ltype(l) == isturb) then
if (ctype(c) == icol_sunwall) then
scale_c2l(c) = spval
else if (ctype(c) == icol_shadewall) then
scale_c2l(c) = spval
else if (ctype(c) == icol_road_perv .or. ctype(c) == icol_road_imperv) then
scale_c2l(c) = spval
else if (ctype(c) == icol_roof) then
scale_c2l(c) = spval
end if
else
scale_c2l(c) = 1.0_r8
end if
end do
else
write(iulog,*)'c2l_1d error: scale type ',c2l_scale_type,' not supported'
call endrun
()
end if
garr(:) = spval
sumwt(:) = 0._r8
#if (defined CPP_VECTOR)
max_col_per_gcell = 0
do g = lbg,ubg
max_col_per_gcell = max(ncolumns(g), max_col_per_gcell)
end do
!dir$ nointerchange
do ci = 1,max_col_per_gcell
!dir$ concurrent
!cdir nodep
do g = lbg,ubg
if (ci <= ncolumns(g)) then
c = coli(g) + ci - 1
if (wtgcell(c) /= 0._r8) then
if (carr(c) /= spval) then
garr(g) = 0._r8
end if
end if
end if
end do
end do
!dir$ nointerchange
do ci = 1,max_col_per_gcell
!dir$ concurrent
!cdir nodep
do g = lbg,ubg
if (ci <= ncolumns(g)) then
c = coli(g) + ci - 1
if (wtgcell(c) /= 0._r8) then
if (carr(c) /= spval .and. scale_c2l(c) /= spval) then
l = clandunit(c)
garr(g) = garr(g) + carr(c) * scale_c2l(c) * scale_l2g(l) * wtgcell(c)
sumwt(g) = sumwt(g) + wtgcell(c)
end if
end if
end if
end do
end do
#else
do c = lbc,ubc
if ( wtgcell(c) /= 0._r8) then
if (carr(c) /= spval .and. scale_c2l(c) /= spval) then
l = clandunit(c)
g = cgridcell(c)
if (sumwt(g) == 0._r8) garr(g) = 0._r8
garr(g) = garr(g) + carr(c) * scale_c2l(c) * scale_l2g(l) * wtgcell(c)
sumwt(g) = sumwt(g) + wtgcell(c)
end if
end if
end do
#endif
found = .false.
do g = lbg, ubg
if (sumwt(g) > 1.0_r8 + 1.e-6_r8) then
found = .true.
index = g
else if (sumwt(g) /= 0._r8) then
garr(g) = garr(g)/sumwt(g)
end if
end do
if (found) then
write(iulog,*)'c2g_1d error: sumwt is greater than 1.0 at g= ',index
call endrun
()
end if
end subroutine c2g_1d
!-----------------------------------------------------------------------
!BOP
!
! !IROUTINE: c2g_2d
!
! !INTERFACE:
subroutine c2g_2d(lbc, ubc, lbl, ubl, lbg, ubg, num2d, carr, garr, & 1,3
c2l_scale_type, l2g_scale_type)
!
! !DESCRIPTION:
! Perfrom subgrid-average from columns to gridcells.
! Averaging is only done for points that are not equal to "spval".
!
! !ARGUMENTS:
implicit none
integer , intent(in) :: lbc, ubc ! beginning and ending column indices
integer , intent(in) :: lbl, ubl ! beginning and ending landunit indices
integer , intent(in) :: lbg, ubg ! beginning and ending gridcell indices
integer , intent(in) :: num2d ! size of second dimension
real(r8), intent(in) :: carr(lbc:ubc,num2d) ! input column array
real(r8), intent(out) :: garr(lbg:ubg,num2d) ! output gridcell array
character(len=*), intent(in) :: c2l_scale_type ! scale factor type for averaging
character(len=*), intent(in) :: l2g_scale_type ! scale factor type for averaging
!
! !REVISION HISTORY:
! Created by Mariana Vertenstein 12/03
!
!
! !LOCAL VARIABLES:
!EOP
integer :: j,ci,c,g,l,index ! indices
integer :: max_col_per_gcell ! max columns per gridcell; on the fly
logical :: found ! temporary for error check
real(r8) :: scale_c2l(lbc:ubc) ! scale factor
real(r8) :: scale_l2g(lbl:ubl) ! scale factor
real(r8) :: sumwt(lbg:ubg) ! sum of weights
real(r8), pointer :: wtgcell(:) ! weight of columns relative to gridcells
integer , pointer :: clandunit(:) ! landunit of corresponding column
integer , pointer :: cgridcell(:) ! gridcell of corresponding column
integer , pointer :: ncolumns(:) ! number of columns in gridcell
integer , pointer :: coli(:) ! initial column index in gridcell
integer , pointer :: ctype(:) ! column type
integer , pointer :: ltype(:) ! landunit type
real(r8), pointer :: canyon_hwr(:) ! urban canyon height to width ratio
!------------------------------------------------------------------------
ctype => clm3%g%l%c%itype
ltype => clm3%g%l%itype
canyon_hwr => clm3%g%l%canyon_hwr
wtgcell => clm3%g%l%c%wtgcell
clandunit => clm3%g%l%c%landunit
cgridcell => clm3%g%l%c%gridcell
ncolumns => clm3%g%ncolumns
coli => clm3%g%coli
if (l2g_scale_type == 'unity') then
do l = lbl,ubl
scale_l2g(l) = 1.0_r8
end do
else
write(iulog,*)'c2g_2d error: scale type ',l2g_scale_type,' not supported'
call endrun
()
end if
if (c2l_scale_type == 'unity') then
do c = lbc,ubc
scale_c2l(c) = 1.0_r8
end do
else if (c2l_scale_type == 'urbanf') then
do c = lbc,ubc
l = clandunit(c)
if (ltype(l) == isturb) then
if (ctype(c) == icol_sunwall) then
scale_c2l(c) = 3.0 * canyon_hwr(l)
else if (ctype(c) == icol_shadewall) then
scale_c2l(c) = 3.0 * canyon_hwr(l)
else if (ctype(c) == icol_road_perv .or. ctype(c) == icol_road_imperv) then
scale_c2l(c) = 3.0_r8
else if (ctype(c) == icol_roof) then
scale_c2l(c) = 1.0_r8
end if
else
scale_c2l(c) = 1.0_r8
end if
end do
else if (c2l_scale_type == 'urbans') then
do c = lbc,ubc
l = clandunit(c)
if (ltype(l) == isturb) then
if (ctype(c) == icol_sunwall) then
scale_c2l(c) = (3.0 * canyon_hwr(l)) / (2.*canyon_hwr(l) + 1.)
else if (ctype(c) == icol_shadewall) then
scale_c2l(c) = (3.0 * canyon_hwr(l)) / (2.*canyon_hwr(l) + 1.)
else if (ctype(c) == icol_road_perv .or. ctype(c) == icol_road_imperv) then
scale_c2l(c) = 3.0 / (2.*canyon_hwr(l) + 1.)
else if (ctype(c) == icol_roof) then
scale_c2l(c) = 1.0_r8
end if
else
scale_c2l(c) = 1.0_r8
end if
end do
else if (c2l_scale_type == 'urbanh') then
do c = lbc,ubc
l = clandunit(c)
if (ltype(l) == isturb) then
if (ctype(c) == icol_sunwall) then
scale_c2l(c) = spval
else if (ctype(c) == icol_shadewall) then
scale_c2l(c) = spval
else if (ctype(c) == icol_road_perv .or. ctype(c) == icol_road_imperv) then
scale_c2l(c) = spval
else if (ctype(c) == icol_roof) then
scale_c2l(c) = spval
end if
else
scale_c2l(c) = 1.0_r8
end if
end do
else
write(iulog,*)'c2g_2d error: scale type ',c2l_scale_type,' not supported'
call endrun
()
end if
#if (defined CPP_VECTOR)
max_col_per_gcell = 0
do g = lbg,ubg
max_col_per_gcell = max(ncolumns(g), max_col_per_gcell)
end do
#endif
garr(:,:) = spval
do j = 1,num2d
sumwt(:) = 0._r8
#if (defined CPP_VECTOR)
!dir$ nointerchange
do ci = 1,max_col_per_gcell
!dir$ concurrent
!cdir nodep
do g = lbg,ubg
if (ci <= ncolumns(g)) then
c = coli(g) + ci - 1
if (wtgcell(c) /= 0._r8) then
if (carr(c,j) /= spval) then
garr(g,j) = 0._r8
end if
end if
end if
end do
end do
!dir$ nointerchange
do ci = 1,max_col_per_gcell
!dir$ concurrent
!cdir nodep
do g = lbg,ubg
if (ci <= ncolumns(g)) then
c = coli(g) + ci - 1
if (wtgcell(c) /= 0._r8) then
if (carr(c,j) /= spval .and. scale_c2l(c) /= spval) then
l = clandunit(c)
garr(g,j) = garr(g,j) + carr(c,j) * scale_c2l(c) * scale_l2g(l) * wtgcell(c)
sumwt(g) = sumwt(g) + wtgcell(c)
end if
end if
end if
end do
end do
#else
do c = lbc,ubc
if (wtgcell(c) /= 0._r8) then
if (carr(c,j) /= spval .and. scale_c2l(c) /= spval) then
l = clandunit(c)
g = cgridcell(c)
if (sumwt(g) == 0._r8) garr(g,j) = 0._r8
garr(g,j) = garr(g,j) + carr(c,j) * scale_c2l(c) * scale_l2g(l) * wtgcell(c)
sumwt(g) = sumwt(g) + wtgcell(c)
end if
end if
end do
#endif
found = .false.
do g = lbg, ubg
if (sumwt(g) > 1.0_r8 + 1.e-6_r8) then
found = .true.
index = g
else if (sumwt(g) /= 0._r8) then
garr(g,j) = garr(g,j)/sumwt(g)
end if
end do
if (found) then
write(iulog,*)'c2g_2d error: sumwt is greater than 1.0 at g= ',index
call endrun
()
end if
end do
end subroutine c2g_2d
!-----------------------------------------------------------------------
!BOP
!
! !IROUTINE: l2g_1d
!
! !INTERFACE:
subroutine l2g_1d(lbl, ubl, lbg, ubg, larr, garr, l2g_scale_type) 1,2
!
! !DESCRIPTION:
! Perfrom subgrid-average from landunits to gridcells.
! Averaging is only done for points that are not equal to "spval".
!
! !ARGUMENTS:
implicit none
integer , intent(in) :: lbl, ubl ! beginning and ending sub landunit indices
integer , intent(in) :: lbg, ubg ! beginning and ending gridcell indices
real(r8), intent(in) :: larr(lbl:ubl) ! input landunit array
real(r8), intent(out) :: garr(lbg:ubg) ! output gridcell array
character(len=*), intent(in) :: l2g_scale_type ! scale factor type for averaging
!
! !REVISION HISTORY:
! Created by Mariana Vertenstein 12/03
!
!
! !LOCAL VARIABLES:
!EOP
integer :: li,l,g,index ! indices
integer :: max_lu_per_gcell ! max landunits per gridcell; on the fly
logical :: found ! temporary for error check
real(r8) :: scale_l2g(lbl:ubl) ! scale factor
real(r8) :: sumwt(lbg:ubg) ! sum of weights
real(r8), pointer :: wtgcell(:) ! weight of landunits relative to gridcells
integer , pointer :: lgridcell(:) ! gridcell of corresponding landunit
integer , pointer :: nlandunits(:) ! number of landunits in gridcell
integer , pointer :: luni(:) ! initial landunit index in gridcell
!------------------------------------------------------------------------
wtgcell => clm3%g%l%wtgcell
lgridcell => clm3%g%l%gridcell
nlandunits => clm3%g%nlandunits
luni => clm3%g%luni
if (l2g_scale_type == 'unity') then
do l = lbl,ubl
scale_l2g(l) = 1.0_r8
end do
else
write(iulog,*)'l2g_1d error: scale type ',l2g_scale_type,' not supported'
call endrun
()
end if
garr(:) = spval
sumwt(:) = 0._r8
#if (defined CPP_VECTOR)
max_lu_per_gcell = 0
do g = lbg,ubg
max_lu_per_gcell = max(nlandunits(g), max_lu_per_gcell)
end do
!dir$ nointerchange
do li = 1,max_lu_per_gcell
!dir$ concurrent
!cdir nodep
do g = lbg,ubg
if (li <= nlandunits(g)) then
l = luni(g) + li - 1
if (wtgcell(l) /= 0._r8) then
if (larr(l) /= spval) then
garr(g) = 0._r8
end if
end if
end if
end do
end do
!dir$ nointerchange
do li = 1,max_lu_per_gcell
!dir$ concurrent
!cdir nodep
do g = lbg,ubg
if (li <= nlandunits(g)) then
l = luni(g) + li - 1
if (wtgcell(l) /= 0._r8) then
if (larr(l) /= spval) then
garr(g) = garr(g) + larr(l) * scale_l2g(l) * wtgcell(l)
sumwt(g) = sumwt(g) + wtgcell(l)
end if
end if
end if
end do
end do
#else
do l = lbl,ubl
if (wtgcell(l) /= 0._r8) then
if (larr(l) /= spval) then
g = lgridcell(l)
if (sumwt(g) == 0._r8) garr(g) = 0._r8
garr(g) = garr(g) + larr(l) * scale_l2g(l) * wtgcell(l)
sumwt(g) = sumwt(g) + wtgcell(l)
end if
end if
end do
#endif
found = .false.
do g = lbg, ubg
if (sumwt(g) > 1.0_r8 + 1.e-6_r8) then
found = .true.
index = g
else if (sumwt(g) /= 0._r8) then
garr(g) = garr(g)/sumwt(g)
end if
end do
if (found) then
write(iulog,*)'l2g_1d error: sumwt is greater than 1.0 at g= ',index
call endrun
()
end if
end subroutine l2g_1d
!-----------------------------------------------------------------------
!BOP
!
! !IROUTINE: l2g_2d
!
! !INTERFACE:
subroutine l2g_2d(lbl, ubl, lbg, ubg, num2d, larr, garr, l2g_scale_type) 1,2
!
! !DESCRIPTION:
! Perfrom subgrid-average from landunits to gridcells.
! Averaging is only done for points that are not equal to "spval".
!
! !ARGUMENTS:
implicit none
integer , intent(in) :: lbl, ubl ! beginning and ending column indices
integer , intent(in) :: lbg, ubg ! beginning and ending gridcell indices
integer , intent(in) :: num2d ! size of second dimension
real(r8), intent(in) :: larr(lbl:ubl,num2d) ! input landunit array
real(r8), intent(out) :: garr(lbg:ubg,num2d) ! output gridcell array
character(len=*), intent(in) :: l2g_scale_type ! scale factor type for averaging
!
! !REVISION HISTORY:
! Created by Mariana Vertenstein 12/03
!
!
! !LOCAL VARIABLES:
!EOP
integer :: j,g,li,l,index ! indices
integer :: max_lu_per_gcell ! max landunits per gridcell; on the fly
logical :: found ! temporary for error check
real(r8) :: scale_l2g(lbl:ubl) ! scale factor
real(r8) :: sumwt(lbg:ubg) ! sum of weights
real(r8), pointer :: wtgcell(:) ! weight of landunits relative to gridcells
integer , pointer :: lgridcell(:) ! gridcell of corresponding landunit
integer , pointer :: nlandunits(:) ! number of landunits in gridcell
integer , pointer :: luni(:) ! initial landunit index in gridcell
!------------------------------------------------------------------------
wtgcell => clm3%g%l%wtgcell
lgridcell => clm3%g%l%gridcell
nlandunits => clm3%g%nlandunits
luni => clm3%g%luni
if (l2g_scale_type == 'unity') then
do l = lbl,ubl
scale_l2g(l) = 1.0_r8
end do
else
write(iulog,*)'l2g_2d error: scale type ',l2g_scale_type,' not supported'
call endrun
()
end if
#if (defined CPP_VECTOR)
max_lu_per_gcell = 0
do g = lbg,ubg
max_lu_per_gcell = max(nlandunits(g), max_lu_per_gcell)
end do
#endif
garr(:,:) = spval
do j = 1,num2d
sumwt(:) = 0._r8
#if (defined CPP_VECTOR)
!dir$ nointerchange
do li = 1,max_lu_per_gcell
!dir$ concurrent
!cdir nodep
do g = lbg,ubg
if (li <= nlandunits(g)) then
l = luni(g) + li - 1
if (wtgcell(l) /= 0._r8) then
if (larr(l,j) /= spval) then
garr(g,j) = 0._r8
end if
end if
end if
end do
end do
!dir$ nointerchange
do li = 1,max_lu_per_gcell
!dir$ concurrent
!cdir nodep
do g = lbg,ubg
if (li <= nlandunits(g)) then
l = luni(g) + li - 1
if (wtgcell(l) /= 0._r8) then
if (larr(l,j) /= spval) then
garr(g,j) = garr(g,j) + larr(l,j) * scale_l2g(l) * wtgcell(l)
sumwt(g) = sumwt(g) + wtgcell(l)
end if
end if
end if
end do
end do
#else
do l = lbl,ubl
if (wtgcell(l) /= 0._r8) then
if (larr(l,j) /= spval) then
g = lgridcell(l)
if (sumwt(g) == 0._r8) garr(g,j) = 0._r8
garr(g,j) = garr(g,j) + larr(l,j) * scale_l2g(l) * wtgcell(l)
sumwt(g) = sumwt(g) + wtgcell(l)
end if
end if
end do
#endif
found = .false.
do g = lbg,ubg
if (sumwt(g) > 1.0_r8 + 1.e-6_r8) then
found = .true.
index= g
else if (sumwt(g) /= 0._r8) then
garr(g,j) = garr(g,j)/sumwt(g)
end if
end do
if (found) then
write(iulog,*)'l2g_2d error: sumwt is greater than 1.0 at g= ',index,' lev= ',j
call endrun
()
end if
end do
end subroutine l2g_2d
end module subgridAveMod