module map_atmice_mct 3,9
!---------------------------------------------------------------------
!
! Purpose:
!
! Collect coupling routines for sequential coupling of ICE-ATM.
!
! Author: R. Jacob, M. Vertenstein
!
!---------------------------------------------------------------------
use shr_kind_mod
, only: R8 => SHR_KIND_R8
use shr_sys_mod
use shr_mct_mod
, only: shr_mct_sMatPInitnc
use mct_mod
use seq_flds_mod
use seq_flds_indices
use seq_cdata_mod
use seq_comm_mct
, only: logunit, loglevel
use seq_infodata_mod
use m_die
implicit none
save
private ! except
!--------------------------------------------------------------------------
! Public interfaces
!--------------------------------------------------------------------------
public :: map_ice2atm_init_mct
public :: map_ice2atm_mct
! atm2ice is not used or validated yet
private :: map_atm2ice_init_mct
private :: map_atm2ice_mct
!--------------------------------------------------------------------------
! Public data
!--------------------------------------------------------------------------
!--------------------------------------------------------------------------
! Private data
!--------------------------------------------------------------------------
type(mct_rearr), private :: Re_ice2atm
type(mct_sMatp), private :: sMatp_Fi2a
type(mct_sMatp), private :: sMatp_Si2a
! atm2ice is not used or validated yet
type(mct_rearr), private :: Re_atm2ice
type(mct_sMatp), private :: sMatp_Fa2i
type(mct_sMatp), private :: sMatp_Sa2i
#ifdef CPP_VECTOR
logical :: usevector = .true.
#else
logical :: usevector = .false.
#endif
#ifdef SYSUNICOS
logical :: usealltoall = .true.
#else
logical :: usealltoall = .false.
#endif
logical :: samegrid_mapa2i
!=======================================================================
contains
!=======================================================================
subroutine map_atm2ice_init_mct( cdata_a, cdata_i),6
!-----------------------------------------------
!
! Arguments
!
type(seq_cdata),intent(in) :: cdata_a
type(seq_cdata),intent(in) :: cdata_i
!
! Local variables
!
type(seq_infodata_type), pointer :: infodata
type(mct_gsMap), pointer :: gsMap_a
type(mct_gsMap), pointer :: gsMap_i
integer :: mpicom
character(*),parameter :: subName = '(map_atm2ice_init_mct) '
!-----------------------------------------------
call seq_cdata_setptrs
(cdata_a, gsMap=gsMap_a)
call seq_cdata_setptrs
(cdata_i, gsMap=gsMap_i)
call seq_cdata_setptrs
(cdata_a, mpicom=mpicom, infodata=infodata)
call seq_infodata_GetData
( infodata, samegrid_ao=samegrid_mapa2i)
if (samegrid_mapa2i) then
call mct_rearr_init(gsMap_a, gsMap_i, mpicom, Re_atm2ice)
else
call shr_mct_sMatPInitnc
(sMatp_Fa2i,gsMap_a,gsMap_i,"seq_maps.rc", &
"atm2iceFmapname:","atm2iceFmaptype:",mpicom)
call shr_mct_sMatPInitnc
(sMatp_Sa2i,gsMap_a,gsMap_i,"seq_maps.rc", &
"atm2iceSmapname:","atm2iceSmaptype:",mpicom)
endif
end subroutine map_atm2ice_init_mct
!=======================================================================
subroutine map_ice2atm_init_mct( cdata_i, cdata_a) 1,6
!-----------------------------------------------
!
! Arguments
!
type(seq_cdata), intent(in) :: cdata_i
type(seq_cdata), intent(in) :: cdata_a
!
! Local variables
!
type(seq_infodata_type), pointer :: infodata
type(mct_gsMap), pointer :: gsMap_i ! ice gsMap
type(mct_gsMap), pointer :: gsMap_a ! atm gsMap
type(mct_gGrid), pointer :: dom_i ! ice domain
type(mct_gGrid), pointer :: dom_a ! atm domain
integer :: mpicom ! communicator spanning atm and ice
character(*),parameter :: subName = '(map_ice2atm_init_mct) '
!-----------------------------------------------
call seq_cdata_setptrs
(cdata_i, gsMap=gsMap_i, dom=dom_i)
call seq_cdata_setptrs
(cdata_a, gsMap=gsMap_a, dom=dom_a)
call seq_cdata_setptrs
(cdata_a, mpicom=mpicom, infodata=infodata)
call seq_infodata_GetData
( infodata, samegrid_ao=samegrid_mapa2i)
! Initialize ice->atm mapping or rearranging
if(samegrid_mapa2i) then
call mct_rearr_init(gsMap_i, gsMap_a, mpicom, Re_ice2atm)
else
call shr_mct_sMatPInitnc
(sMatp_Fi2a, gsMap_i, gsMap_a, "seq_maps.rc", &
"ice2atmFmapname:", "ice2atmFmaptype:", mpicom)
call shr_mct_sMatPInitnc
(sMatp_Si2a, gsMap_i, gsMap_a, "seq_maps.rc", &
"ice2atmSmapname:", "ice2atmSmaptype:", mpicom)
endif
end subroutine map_ice2atm_init_mct
!=======================================================================
subroutine map_atm2ice_mct( cdata_a, av_a, cdata_i, av_i, &,2
fluxlist, statelist)
!-----------------------------------------------
!
! Arguments
!
type(seq_cdata) ,intent(in) :: cdata_a
type(mct_aVect) ,intent(in) :: av_a
type(seq_cdata) ,intent(in) :: cdata_i
type(mct_aVect) ,intent(out) :: av_i
character(len=*),intent(in), optional :: fluxlist
character(len=*),intent(in), optional :: statelist
!
! Local variables
!
integer :: lsize ! temporary
type(mct_aVect) :: av_i_f ! temporary flux attribute vector
type(mct_aVect) :: av_i_s ! temporary state attribute vector
type(mct_aVect) :: av_a_fl ! temporary av for rearranging
type(mct_aVect) :: av_i_fl ! temporary av for rearranging
character(*),parameter :: subName = '(map_atm2ice_mct) '
!-----------------------------------------------
if(samegrid_mapa2i) then
if (present(fluxlist) .or. present(statelist)) then
if (present(fluxlist)) then
call mct_rearr_rearrange_fldlist
(av_a, av_i, Re_atm2ice, VECTOR=usevector, &
ALLTOALL=usealltoall, fldlist=fluxlist)
end if
if (present(statelist)) then
call mct_rearr_rearrange_fldlist
(av_a, av_i, Re_atm2ice, VECTOR=usevector, &
ALLTOALL=usealltoall, fldlist=statelist)
end if
else
call mct_rearr_rearrange(av_a, av_i, Re_atm2ice, VECTOR=usevector, ALLTOALL=usealltoall)
endif
else
if (present(fluxlist) .or. present(statelist)) then
if (present(fluxlist)) then
lsize = mct_aVect_lsize(av_i)
call mct_aVect_init (av_i_f, rlist=fluxlist , lsize=lsize)
call mct_sMat_avMult(av_a, sMatp_Fa2i, av_i_f, VECTOR=usevector, rList=fluxlist)
call mct_aVect_copy (aVin=av_i_f, aVout=av_i, vector=usevector)
call mct_aVect_clean(av_i_f)
end if
if (present(statelist)) then
lsize = mct_aVect_lsize(av_i)
call mct_aVect_init (av_i_s, rlist=statelist , lsize=lsize)
call mct_sMat_avMult(av_a, sMatp_Sa2i, av_i_s, VECTOR=usevector, rList=statelist)
call mct_aVect_copy (aVin=av_i_s, aVout=av_i, vector=usevector)
call mct_aVect_clean(av_i_s)
end if
else
!--- default is flux mapping
call mct_sMat_avMult(av_a, sMatp_Fa2i, av_i, VECTOR=usevector)
endif
endif
end subroutine map_atm2ice_mct
!=======================================================================
subroutine map_ice2atm_mct( cdata_i, av_i, cdata_a, av_a, & 5,2
fractions_i, fractions_a, &
fluxlist, statelist)
!-----------------------------------------------
!
! Arguments
!
type(seq_cdata) ,intent(in) :: cdata_i
type(mct_AVect) ,intent(in) :: av_i
type(seq_cdata) ,intent(in) :: cdata_a
type(mct_AVect) ,intent(out) :: av_a
type(mct_AVect) ,intent(in), optional :: fractions_i
type(mct_AVect) ,intent(in), optional :: fractions_a
character(len=*),intent(in), optional :: fluxlist
character(len=*),intent(in), optional :: statelist
!
! Local Variables
!
integer :: n,ki,i,j ! indices
integer :: numats,ier ! number of attributes
integer :: lsize ! size of attribute vector
type(mct_aVect) :: temp ! temporary
type(mct_aVect) :: av_a_f, av_a_s ! temporary
real(R8),allocatable :: recip(:) ! temporary
character(*),parameter :: subName = '(map_ice2atm_mct) '
!-----------------------------------------------
if (samegrid_mapa2i) then
if (present(fluxlist) .or. present(statelist)) then
if (present(fluxlist)) then
call mct_rearr_rearrange_fldlist
(av_i, av_a, Re_ice2atm, VECTOR=usevector, &
ALLTOALL=usealltoall, fldlist=fluxlist)
end if
if (present(statelist)) then
call mct_rearr_rearrange_fldlist
(av_i, av_a, Re_ice2atm, VECTOR=usevector, &
ALLTOALL=usealltoall, fldlist=statelist)
end if
else
call mct_rearr_rearrange(av_i, av_a, Re_ice2atm, VECTOR=usevector, ALLTOALL=usealltoall)
endif
else
if (present(fractions_i) .and. present(fractions_a)) then
! Normalize input data with fraction of ice
lsize = mct_aVect_lsize(av_i)
call mct_aVect_init(temp, av_i, lsize=lsize)
numats = mct_aVect_nRAttr(av_i)
ki = mct_aVect_indexRA(fractions_i,"ifrac")
do j= 1,lsize
do i =1,numats
temp%rAttr(i,j) = av_i%rAttr(i,j) * fractions_i%rAttr(ki,j)
enddo
enddo
! Perform mapping
if (present(fluxlist) .or. present(statelist)) then
if (present(fluxlist)) then
lsize = mct_aVect_lsize(av_a)
call mct_aVect_init (av_a_f, rlist=fluxlist , lsize=lsize)
call mct_sMat_avMult(temp, sMatp_Fi2a, av_a_f, VECTOR=usevector, rList=fluxlist)
call mct_aVect_copy (aVin=av_a_f, aVout=av_a, vector=usevector)
call mct_aVect_clean(av_a_f)
end if
if (present(statelist)) then
lsize = mct_aVect_lsize(av_a)
call mct_aVect_init (av_a_s, rlist=statelist, lsize=lsize)
call mct_sMat_avMult(temp, sMatp_Si2a, av_a_s, VECTOR=usevector, rList=statelist)
call mct_aVect_copy (aVin=av_a_s, aVout=av_a, vector=usevector)
call mct_aVect_clean(av_a_s)
end if
else
!--- default is flux mapping
call mct_sMat_avMult(temp, sMatp_Fi2a, av_a, VECTOR=usevector)
endif
! Clean up temporary vector
call mct_aVect_clean(temp)
! Denormalize output data with fraction of ice on atmosphere grid (icefrac_a)
lsize = mct_aVect_lsize(av_a)
numats = mct_aVect_nRAttr(av_a)
allocate(recip(lsize),stat=ier)
if(ier/=0) call die(subName,'allocate recip',ier)
ki = mct_aVect_indexRA(fractions_a,"ifrac")
do j = 1,lsize
recip(j) = 0.0_R8
if(fractions_a%rAttr(ki,j) /= 0.0_R8) then
recip(j)= 1.0_R8 / fractions_a%rAttr(ki,j)
end if
do i =1,numats
av_a%rAttr(i,j) = av_a%rAttr(i,j) * recip(j)
enddo
enddo
deallocate(recip,stat=ier)
if(ier/=0) call die(subName,'deallocate recip',ier)
else
if (present(fluxlist) .or. present(statelist)) then
if (present(fluxlist)) then
lsize = mct_aVect_lsize(av_a)
call mct_aVect_init (av_a_f, rlist=fluxlist , lsize=lsize)
call mct_sMat_avMult(av_i, sMatp_Fi2a, av_a_f, VECTOR=usevector, rList=fluxlist)
call mct_aVect_copy (aVin=av_a_f, aVout=av_a, vector=usevector)
call mct_aVect_clean(av_a_f)
end if
if (present(statelist)) then
lsize = mct_aVect_lsize(av_a)
call mct_aVect_init (av_a_s, rlist=statelist, lsize=lsize)
call mct_sMat_avMult(av_i, sMatp_Si2a, av_a_s, VECTOR=usevector, rList=statelist)
call mct_aVect_copy (aVin=av_a_s, aVout=av_a, vector=usevector)
call mct_aVect_clean(av_a_s)
end if
else
!--- default is flux mapping
call mct_sMat_avMult(av_i, sMatp_Fi2a, av_a, VECTOR=usevector)
endif
end if
endif
end subroutine map_ice2atm_mct
!=======================================================================
end module map_atmice_mct