module lnd_comp_mct 2,2
!---------------------------------------------------------------------------
!BOP
!
! !MODULE: lnd_comp_mct
!
! Interface of the active land model component of CCSM the CLM (Community Land Model)
! with the main CCSM driver. This is a thin interface taking CCSM driver information
! in MCT (Model Coupling Toolkit) format and converting it to use by CLM.
!
! !DESCRIPTION:
!
! !USES:
use shr_kind_mod
, only : r8 => shr_kind_r8
use mct_mod
, only : mct_aVect
!
! !PUBLIC MEMBER FUNCTIONS:
implicit none
SAVE
private ! By default make data private
!
! !PUBLIC MEMBER FUNCTIONS:
!
public :: lnd_init_mct ! clm initialization
public :: lnd_run_mct ! clm run phase
public :: lnd_final_mct ! clm finalization/cleanup
!
! !PUBLIC DATA MEMBERS: None
!
! !REVISION HISTORY:
! Author: Mariana Vertenstein
! Dec/18/2009 Make sure subroutines have documentation. Erik Kluzek
!
! !PRIVATE MEMBER FUNCTIONS:
private :: lnd_SetgsMap_mct ! Set the land model MCT GS map
private :: lnd_chkAerDep_mct ! Check if aerosol deposition data is input or not
private :: lnd_domain_mct ! Set the land model domain information
private :: lnd_export_mct ! export land data to CCSM coupler
private :: lnd_import_mct ! import data from the CCSM coupler to the land model
#ifdef RTM
private :: rof_SetgsMap_mct ! Set the river runoff model MCT GS map
private :: rof_domain_mct ! Set the river runoff model domain information
private :: rof_export_mct ! Export the river runoff model data to the CCSM coupler
#endif
private :: sno_export_mct
private :: sno_import_mct
!
! !PRIVATE DATA MEMBERS:
!
! Time averaged flux fields
!
type(mct_aVect) :: l2x_l_SNAP ! Snapshot of land to coupler data on the land grid
type(mct_aVect) :: l2x_l_SUM ! Summation of land to coupler data on the land grid
type(mct_aVect) :: l2x_l_clm ! Internal clm grid
type(mct_aVect) :: x2l_l_clm ! Internal clm grid
type(mct_aVect) :: s2x_s_SNAP ! Snapshot of sno to coupler data on the land grid
type(mct_aVect) :: s2x_s_SUM ! Summation of sno to coupler data on the land grid
!
! Time averaged counter for flux fields
!
integer :: avg_count ! Number of times snapshots of above flux data summed together
integer :: avg_count_sno
!
! Atmospheric mode
!
logical :: atm_prognostic ! Flag if active atmosphere component or not
!EOP
!===============================================================
contains
!===============================================================
!---------------------------------------------------------------------------
!BOP
!
! !IROUTINE: lnd_init_mct
!
! !INTERFACE:
subroutine lnd_init_mct( EClock, cdata_l, x2l_l, l2x_l, & 1,76
cdata_r, r2x_r, &
cdata_s, x2s_s, s2x_s, &
NLFilename )
!
! !DESCRIPTION:
! Initialize land surface model and obtain relevant atmospheric model arrays
! back from (i.e. albedos, surface temperature and snow cover over land).
!
! !USES:
use abortutils
, only : endrun
use areaMod
, only : map1dl_a2l, map1dl_l2a, map_maparrayl
use clm_time_manager
, only : get_nstep, get_step_size, set_timemgr_init, &
set_nextsw_cday
use clm_atmlnd
, only : clm_l2a, clm_mapa2l
use clm_comp
, only : clm_init1, clm_init2, clm_init3
use clm_varctl
, only : finidat,single_column, set_clmvarctl, iulog, noland
use clm_varpar
, only : rtmlon, rtmlat
use clm_varorb
, only : eccen, obliqr, lambm0, mvelpp
use controlMod
, only : control_setNL
use decompMod
, only : get_proc_bounds, get_proc_bounds_atm
use domainMod
, only : adomain
use shr_kind_mod
, only : r8 => shr_kind_r8
use shr_file_mod
, only : shr_file_setLogUnit, shr_file_setLogLevel, &
shr_file_getLogUnit, shr_file_getLogLevel, &
shr_file_getUnit, shr_file_setIO
use seq_cdata_mod
, only : seq_cdata, seq_cdata_setptrs
use seq_timemgr_mod
, only : seq_timemgr_EClockGetData
use seq_infodata_mod
, only : seq_infodata_type, seq_infodata_GetData, seq_infodata_PutData, &
seq_infodata_start_type_start, seq_infodata_start_type_cont, &
seq_infodata_start_type_brnch
use mct_mod
, only : mct_aVect, mct_gsMap, mct_gGrid, mct_aVect_init, mct_aVect_zero
use spmdMod
, only : masterproc, spmd_init
use seq_flds_mod
use seq_flds_indices
use clm_glclnd
, only : clm_maps2x, clm_s2x, atm_s2x, create_clm_s2x
use clm_varctl
, only : create_glacier_mec_landunit
use ESMF_mod
implicit none
!
! !ARGUMENTS:
type(ESMF_Clock), intent(in) :: EClock ! Input synchronization clock
type(seq_cdata), intent(inout) :: cdata_l ! Input land-model driver data
type(mct_aVect), intent(inout) :: x2l_l, l2x_l ! land model import and export states
type(seq_cdata), intent(inout) :: cdata_r ! Input runoff-model driver data
type(mct_aVect), intent(inout) :: r2x_r ! River export state
type(seq_cdata), intent(inout) :: cdata_s ! Input snow-model (land-ice) driver data
type(mct_aVect), intent(inout) :: x2s_s, s2x_s ! Snow-model import and export states
character(len=*), optional, intent(in) :: NLFilename ! Namelist filename to read
!
! !LOCAL VARIABLES:
integer :: LNDID ! Land identifyer
integer :: mpicom_lnd ! MPI communicator
type(mct_gsMap), pointer :: GSMap_lnd ! Land model MCT GS map
type(mct_gGrid), pointer :: dom_l ! Land model domain
type(mct_gsMap), pointer :: GSMap_rof ! Runoff model MCT GS map
type(mct_gGrid), pointer :: dom_r ! Runoff model domain
type(mct_gsMap), pointer :: GSMap_sno
type(mct_gGrid), pointer :: dom_s
type(seq_infodata_type), pointer :: infodata ! CCSM driver level info data
integer :: lsize ! size of attribute vector
integer :: g,i,j ! indices
integer :: dtime_sync ! coupling time-step from the input synchronization clock
integer :: dtime_clm ! clm time-step
logical :: exists ! true if file exists
real(r8) :: scmlat ! single-column latitude
real(r8) :: scmlon ! single-column longitude
real(r8) :: nextsw_cday ! calday from clock of next radiation computation
character(len=SHR_KIND_CL) :: caseid ! case identifier name
character(len=SHR_KIND_CL) :: ctitle ! case description title
character(len=SHR_KIND_CL) :: starttype ! start-type (startup, continue, branch, hybrid)
character(len=SHR_KIND_CL) :: calendar ! calendar type name
character(len=SHR_KIND_CL) :: hostname ! hostname of machine running on
character(len=SHR_KIND_CL) :: version ! Model version
character(len=SHR_KIND_CL) :: username ! user running the model
integer :: nsrest ! clm restart type
integer :: perpetual_ymd ! perpetual date
integer :: ref_ymd ! reference date (YYYYMMDD)
integer :: ref_tod ! reference time of day (sec)
integer :: start_ymd ! start date (YYYYMMDD)
integer :: start_tod ! start time of day (sec)
integer :: stop_ymd ! stop date (YYYYMMDD)
integer :: stop_tod ! stop time of day (sec)
logical :: brnch_retain_casename ! flag if should retain the case name on a branch start type
logical :: perpetual_run ! flag if should cycle over a perpetual date or not
integer :: lbnum ! input to memory diagnostic
integer :: shrlogunit,shrloglev ! old values for log unit and log level
integer :: begg_l, endg_l, begg_a, endg_a
character(len=32), parameter :: sub = 'lnd_init_mct'
character(len=*), parameter :: format = "('("//trim(sub)//") :',A)"
!
! !REVISION HISTORY:
! Author: Mariana Vertenstein
!
!EOP
!-----------------------------------------------------------------------
! Set cdata data
call seq_cdata_setptrs
(cdata_l, ID=LNDID, mpicom=mpicom_lnd, &
gsMap=GSMap_lnd, dom=dom_l, infodata=infodata)
call seq_cdata_setptrs
(cdata_r, &
gsMap=gsMap_rof, dom=dom_r)
! Initialize clm MPI communicator
call spmd_init
( mpicom_lnd )
#if (defined _MEMTRACE)
if(masterproc) then
lbnum=1
call memmon_dump_fort('memmon.out','lnd_init_mct:start::',lbnum)
endif
#endif
! Initialize io log unit
call shr_file_getLogUnit
(shrlogunit)
if (masterproc) then
inquire(file='lnd_modelio.nml',exist=exists)
if (exists) then
iulog = shr_file_getUnit
()
call shr_file_setIO
('lnd_modelio.nml',iulog)
end if
write(iulog,format) "CLM land model initialization"
else
iulog = shrlogunit
end if
call shr_file_getLogLevel
(shrloglev)
call shr_file_setLogUnit
(iulog)
! Use infodata to set orbital values
call seq_infodata_GetData
( infodata, orb_eccen=eccen, orb_mvelpp=mvelpp, &
orb_lambm0=lambm0, orb_obliqr=obliqr )
! Consistency check on namelist filename
call control_setNL
( 'lnd_in' )
! Initialize clm
! clm_init1 reads namelist, grid and surface data
! clm_init2 and clm_init3 performs rest of initialization
call seq_timemgr_EClockGetData
(EClock, &
start_ymd=start_ymd, &
start_tod=start_tod, ref_ymd=ref_ymd, &
ref_tod=ref_tod, stop_ymd=stop_ymd, &
stop_tod=stop_tod, &
calendar=calendar )
call seq_infodata_GetData
(infodata, perpetual=perpetual_run, &
perpetual_ymd=perpetual_ymd, case_name=caseid, &
case_desc=ctitle, single_column=single_column, &
scmlat=scmlat, scmlon=scmlon, &
brnch_retain_casename=brnch_retain_casename, &
start_type=starttype, model_version=version, &
hostname=hostname, username=username &
)
call set_timemgr_init
( calendar_in=calendar, start_ymd_in=start_ymd, start_tod_in=start_tod, &
ref_ymd_in=ref_ymd, ref_tod_in=ref_tod, stop_ymd_in=stop_ymd, &
stop_tod_in=stop_tod, perpetual_run_in=perpetual_run, &
perpetual_ymd_in=perpetual_ymd )
if ( trim(starttype) == trim(seq_infodata_start_type_start)) then
nsrest = 0
else if (trim(starttype) == trim(seq_infodata_start_type_cont) ) then
nsrest = 1
else if (trim(starttype) == trim(seq_infodata_start_type_brnch)) then
nsrest = 3
else
call endrun
( sub//' ERROR: unknown starttype' )
end if
call set_clmvarctl
( caseid_in=caseid, ctitle_in=ctitle, &
brnch_retain_casename_in=brnch_retain_casename, &
single_column_in=single_column, scmlat_in=scmlat, &
scmlon_in=scmlon, nsrest_in=nsrest, version_in=version, &
hostname_in=hostname, username_in=username )
! Read namelist, grid and surface data
call clm_init1
( )
! If no land then exit out of initialization
if ( noland) then
call seq_infodata_PutData
( infodata, lnd_present =.false.)
call seq_infodata_PutData
( infodata, lnd_prognostic=.false.)
call seq_infodata_PutData
( infodata, rof_present =.false.)
return
end if
! Determine if aerosol and dust deposition come from atmosphere component
call lnd_chkAerDep_mct
( infodata )
! Initialize lnd gsMap and domain
call lnd_SetgsMap_mct
( mpicom_lnd, LNDID, gsMap_lnd )
lsize = mct_gsMap_lsize(gsMap_lnd, mpicom_lnd)
call lnd_domain_mct
( lsize, gsMap_lnd, dom_l )
! Initialize lnd attribute vectors coming from driver
call mct_aVect_init(x2l_l, rList=seq_flds_x2l_fields, lsize=lsize)
call mct_aVect_zero(x2l_l)
call mct_aVect_init(l2x_l, rList=seq_flds_l2x_fields, lsize=lsize)
call mct_aVect_zero(l2x_l)
call mct_aVect_init(l2x_l_SNAP, rList=seq_flds_l2x_fluxes, lsize=lsize)
call mct_aVect_zero(l2x_l_SNAP)
call mct_aVect_init(l2x_l_SUM , rList=seq_flds_l2x_fluxes, lsize=lsize)
call mct_aVect_zero(l2x_l_SUM )
if (masterproc) then
write(iulog,format)'time averaging the following flux fields over the coupling interval'
write(iulog,format) trim(seq_flds_l2x_fluxes)
end if
! Finish initializing clm
call clm_init2
()
call clm_init3
()
! Check that clm internal dtime aligns with clm coupling interval
call seq_timemgr_EClockGetData
(EClock, dtime=dtime_sync )
dtime_clm = get_step_size
()
if (masterproc) write(iulog,*)'dtime_sync= ',dtime_sync,&
' dtime_clm= ',dtime_clm,' mod = ',mod(dtime_sync,dtime_clm)
if (mod(dtime_sync,dtime_clm) /= 0) then
write(iulog,*)'clm dtime ',dtime_clm,' and Eclock dtime ',&
dtime_sync,' never align'
call endrun
( sub//' ERROR: time out of sync' )
end if
! Create new attribute vectors for the clm internal grid (dst)
call get_proc_bounds_atm
(begg_a, endg_a) ! clm grid - driver (src)
call get_proc_bounds
(begg_l, endg_l) ! clm grid - internal (dst)
call mct_aVect_init(x2l_l_clm, rList=seq_flds_x2l_fields, lsize=endg_l-begg_l+1)
call mct_aVect_zero(x2l_l_clm)
call mct_aVect_init(l2x_l_clm, rList=seq_flds_l2x_fields, lsize=endg_l-begg_l+1)
call mct_aVect_zero(l2x_l_clm)
! Create land export state then map this from the
! clm internal grid (dst) to the clm driver grid (src)
call lnd_export_mct
( clm_l2a, l2x_l_clm, begg_l, endg_l )
call map_maparrayl
(begg_l, endg_l, begg_a, endg_a, nflds_l2x, &
l2x_l_clm, l2x_l, map1dl_l2a)
! Reset landfrac on atmosphere grid to have the right domain
do g = begg_a,endg_a
l2x_l%rAttr(index_l2x_Sl_landfrac,g-begg_a+1) = adomain%frac(g)
end do
#ifdef RTM
! Initialize rof gsMap
call rof_SetgsMap_mct
( mpicom_lnd, LNDID, gsMap_rof )
lsize = mct_gsMap_lsize(gsMap_rof, mpicom_lnd)
! Initialize rof domain
call rof_domain_mct
( lsize, gsMap_rof, dom_r )
! Initialize rtm attribute vectors
call mct_aVect_init(r2x_r, rList=seq_flds_r2x_fields, lsize=lsize)
call mct_aVect_zero(r2x_r)
! Create mct river runoff export state
call rof_export_mct
( r2x_r )
#endif
if (create_glacier_mec_landunit) then
call seq_cdata_setptrs
(cdata_s, gsMap=gsMap_sno, dom=dom_s)
! Initialize sno gsMap (same as gsMap_lnd)
call lnd_SetgsMap_mct
( mpicom_lnd, LNDID, gsMap_sno )
lsize = mct_gsMap_lsize(gsMap_sno, mpicom_lnd)
! Initialize sno domain (same as lnd domain)
call lnd_domain_mct
( lsize, gsMap_sno, dom_s )
! Initialize sno attribute vectors
call mct_aVect_init(x2s_s, rList=seq_flds_x2s_fields, lsize=lsize)
call mct_aVect_zero(x2s_s)
call mct_aVect_init(s2x_s, rList=seq_flds_s2x_fields, lsize=lsize)
call mct_aVect_zero(s2x_s)
call mct_aVect_init(s2x_s_SUM , rList=seq_flds_s2x_fluxes, lsize=lsize)
call mct_aVect_zero(s2x_s_SUM )
call mct_aVect_init(s2x_s_SNAP , rList=seq_flds_s2x_fluxes, lsize=lsize)
call mct_aVect_zero(s2x_s_SNAP )
! Create mct sno export state
call create_clm_s2x
(clm_s2x)
call clm_maps2x
(clm_s2x, atm_s2x)
call sno_export_mct
( atm_s2x, s2x_s )
endif ! create_glacier_mec_landunit
! Initialize averaging counter
avg_count = 0
! Set land modes
call seq_infodata_PutData
( infodata, lnd_prognostic=.true.)
call seq_infodata_PutData
( infodata, lnd_nx = adomain%ni, lnd_ny = adomain%nj)
#ifdef RTM
call seq_infodata_PutData
( infodata, rof_present=.true.)
call seq_infodata_PutData
( infodata, rof_nx = rtmlon, rof_ny = rtmlat)
#else
call seq_infodata_PutData
( infodata, rof_present=.false.)
#endif
if (create_glacier_mec_landunit) then
call seq_infodata_PutData
( infodata, sno_present=.true.)
call seq_infodata_PutData
( infodata, sno_nx = adomain%ni, sno_ny = adomain%nj)
else
call seq_infodata_PutData
( infodata, sno_present=.false.)
endif
call seq_infodata_GetData
(infodata, nextsw_cday=nextsw_cday )
call set_nextsw_cday
( nextsw_cday )
! Determine atmosphere modes
call seq_infodata_GetData
(infodata, atm_prognostic=atm_prognostic)
if (masterproc) then
if ( atm_prognostic )then
write(iulog,format) 'Atmospheric input is from a prognostic model'
else
write(iulog,format) 'Atmospheric input is from a data model'
end if
end if
! Reset shr logging to original values
call shr_file_setLogUnit
(shrlogunit)
call shr_file_setLogLevel
(shrloglev)
#if (defined _MEMTRACE)
if(masterproc) then
write(iulog,*) TRIM(Sub) // ':end::'
lbnum=1
call memmon_dump_fort('memmon.out','lnd_int_mct:end::',lbnum)
call memmon_reset_addr()
endif
#endif
end subroutine lnd_init_mct
!---------------------------------------------------------------------------
!BOP
!
! !IROUTINE: lnd_run_mct
!
! !INTERFACE:
subroutine lnd_run_mct( EClock, cdata_l, x2l_l, l2x_l, & 1,66
cdata_r, r2x_r, &
cdata_s, x2s_s, s2x_s )
!
! !DESCRIPTION:
! Run clm model
!
! !USES:
use shr_kind_mod
,only : r8 => shr_kind_r8
use areaMod
,only : map1dl_a2l, map1dl_l2a, map_maparrayl
use clm_atmlnd
,only : clm_l2a, atm_a2l, clm_a2l, clm_mapa2l
use clm_comp
,only : clm_run1, clm_run2
use clm_time_manager
,only : get_curr_date, get_nstep, get_curr_calday, get_step_size, &
advance_timestep, set_nextsw_cday,update_rad_dtime
use domainMod
,only : adomain
use decompMod
,only : get_proc_bounds_atm, get_proc_bounds
use abortutils
,only : endrun
use clm_varctl
,only : iulog
use shr_file_mod
,only : shr_file_setLogUnit, shr_file_setLogLevel, &
shr_file_getLogUnit, shr_file_getLogLevel
use seq_cdata_mod
,only : seq_cdata, seq_cdata_setptrs
use seq_timemgr_mod
,only : seq_timemgr_EClockGetData, seq_timemgr_StopAlarmIsOn, &
seq_timemgr_RestartAlarmIsOn, seq_timemgr_EClockDateInSync
use seq_infodata_mod
,only : seq_infodata_type, seq_infodata_GetData
use spmdMod
,only : masterproc, mpicom
use perf_mod ,only : t_startf, t_stopf, t_barrierf
use mct_mod
,only : mct_aVect, mct_aVect_accum, mct_aVect_copy, mct_aVect_avg, &
mct_aVect_zero
use mct_mod
, only : mct_gGrid, mct_gGrid_exportRAttr, mct_gGrid_lsize
use clm_varctl
,only : create_glacier_mec_landunit
use clm_glclnd
,only : clm_maps2x, clm_mapx2s, clm_s2x, atm_s2x, atm_x2s, clm_x2s
use clm_glclnd
,only : create_clm_s2x, unpack_clm_x2s
use seq_flds_indices
use ESMF_mod
implicit none
!
! !ARGUMENTS:
type(ESMF_Clock) , intent(in) :: EClock ! Input synchronization clock from driver
type(seq_cdata) , intent(in) :: cdata_l ! Input driver data for land model
type(mct_aVect) , intent(inout) :: x2l_l ! Import state to land model
type(mct_aVect) , intent(inout) :: l2x_l ! Export state from land model
type(seq_cdata) , intent(in) :: cdata_r ! Input driver data for runoff model
type(mct_aVect) , intent(inout) :: r2x_r ! Export state from runoff model
type(seq_cdata) , intent(in) :: cdata_s ! Input driver data for snow model (land-ice)
type(mct_aVect) , intent(inout) :: x2s_s ! Import state for snow model
type(mct_aVect) , intent(inout) :: s2x_s ! Export state for snow model
! !LOCAL VARIABLES:
integer :: ymd_sync ! Sync date (YYYYMMDD)
integer :: yr_sync ! Sync current year
integer :: mon_sync ! Sync current month
integer :: day_sync ! Sync current day
integer :: tod_sync ! Sync current time of day (sec)
integer :: ymd ! CLM current date (YYYYMMDD)
integer :: yr ! CLM current year
integer :: mon ! CLM current month
integer :: day ! CLM current day
integer :: tod ! CLM current time of day (sec)
integer :: dtime ! time step increment (sec)
integer :: nstep ! time step index
logical :: rstwr_sync ! .true. ==> write restart file before returning
logical :: rstwr ! .true. ==> write restart file before returning
logical :: nlend_sync ! Flag signaling last time-step
logical :: nlend ! .true. ==> last time-step
logical :: dosend ! true => send data back to driver
logical :: doalb ! .true. ==> do albedo calculation on this time step
real(r8):: nextsw_cday ! calday from clock of next radiation computation
real(r8):: caldayp1 ! clm calday plus dtime offset
integer :: shrlogunit,shrloglev ! old values for share log unit and log level
integer :: begg, endg ! Beginning and ending gridcell index numbers
integer :: lbnum ! input to memory diagnostic
type(seq_infodata_type),pointer :: infodata ! CCSM information from the driver
type(mct_gGrid), pointer :: dom_l ! Land model domain data
real(r8), pointer :: data(:) ! temporary
integer :: g,i,lsize ! counters
integer :: begg_l, endg_l, begg_a, endg_a ! bounds
logical,save :: first_call = .true. ! first call work
character(len=32) :: rdate ! date char string for restart file names
character(len=32), parameter :: sub = "lnd_run_mct"
logical :: glcrun_alarm ! if true, sno data is averaged and sent to glc this step
logical :: update_glc2sno_fields ! if true, update glacier_mec fields
!
! !REVISION HISTORY:
! Author: Mariana Vertenstein
!
!EOP
!---------------------------------------------------------------------------
#if (defined _MEMTRACE)
if(masterproc) then
lbnum=1
call memmon_dump_fort('memmon.out','lnd_run_mct:start::',lbnum)
endif
#endif
! Reset shr logging to my log file
call shr_file_getLogUnit
(shrlogunit)
call shr_file_getLogLevel
(shrloglev)
call shr_file_setLogUnit
(iulog)
! Determine time of next atmospheric shortwave calculation
call seq_cdata_setptrs
(cdata_l, infodata=infodata, dom=dom_l)
call seq_timemgr_EClockGetData
(EClock, &
curr_ymd=ymd, curr_tod=tod_sync, &
curr_yr=yr_sync, curr_mon=mon_sync, curr_day=day_sync)
call seq_infodata_GetData
(infodata, nextsw_cday=nextsw_cday )
call set_nextsw_cday
( nextsw_cday )
dtime = get_step_size
()
write(rdate,'(i4.4,"-",i2.2,"-",i2.2,"-",i5.5)') yr_sync,mon_sync,day_sync,tod_sync
nlend_sync = seq_timemgr_StopAlarmIsOn
( EClock )
rstwr_sync = seq_timemgr_RestartAlarmIsOn
( EClock )
call get_proc_bounds_atm
(begg_a, endg_a)
call get_proc_bounds
(begg_l, endg_l)
if (first_call) then
lsize = mct_gGrid_lsize(dom_l)
allocate(data(lsize))
call mct_gGrid_exportRattr(dom_l,"ascale",data,lsize)
do g = begg_a,endg_a
i = 1 + (g - begg_a)
adomain%asca(g) = data(i)
end do
deallocate(data)
endif
! Map MCT to land data type
call t_startf ('lc_lnd_import')
call lnd_import_mct
( x2l_l, atm_a2l, begg_a, endg_a )
call t_stopf ('lc_lnd_import')
call map_maparrayl
(begg_a, endg_a, begg_l, endg_l, nflds_x2l, &
x2l_l, x2l_l_clm, map1dl_a2l)
call t_startf ('lc_lnd_import')
call lnd_import_mct
( x2l_l_clm, clm_a2l, begg_l, endg_l )
call t_stopf ('lc_lnd_import')
! Perform downscaling if appropriate
call t_startf ('lc_clm_mapa2l')
call clm_mapa2l
(atm_a2l, clm_a2l)
call t_stopf ('lc_clm_mapa2l')
if (create_glacier_mec_landunit) then
! Receive sno data
call t_startf ('lc_sno_import')
call sno_import_mct
( x2s_s, atm_x2s )
call t_stopf ('lc_sno_import')
! Map to clm (only when state and/or fluxes need to be updated)
update_glc2sno_fields = .false.
call seq_infodata_GetData
(infodata, glc_g2supdate = update_glc2sno_fields)
if (update_glc2sno_fields) then
call t_startf ('lc_clm_mapa2s')
call clm_mapx2s
(atm_x2s, clm_x2s)
call t_stopf ('lc_clm_mapa2s')
call unpack_clm_x2s
(clm_x2s)
endif ! update_glc2sno
endif ! create_glacier_mec_landunit
! Loop over time steps in coupling interval
dosend = .false.
do while(.not. dosend)
! Determine if dosend
! When time is not updated at the beginning of the loop - then return only if
! are in sync with clock before time is updated
call get_curr_date
( yr, mon, day, tod )
ymd = yr*10000 + mon*100 + day
tod = tod
dosend = (seq_timemgr_EClockDateInSync
( EClock, ymd, tod))
! Determine doalb based on nextsw_cday sent from atm model
nstep = get_nstep
()
caldayp1 = get_curr_calday
(offset=dtime)
if (nstep == 0) then
doalb = .false.
else if (nstep == 1) then
doalb = (abs(nextsw_cday- caldayp1) < 1.e-10_r8)
else
doalb = (nextsw_cday >= -0.5_r8)
end if
call update_rad_dtime
(doalb)
! Determine if time to write cam restart and stop
rstwr = .false.
if (rstwr_sync .and. dosend) rstwr = .true.
nlend = .false.
if (nlend_sync .and. dosend) nlend = .true.
! Run clm
call t_barrierf('sync_clm_run1', mpicom)
call t_startf ('clm_run1')
call clm_run1
( doalb, nextsw_cday )
call t_stopf ('clm_run1')
call t_barrierf('sync_clm_run2', mpicom)
call t_startf ('clm_run2')
call clm_run2
( nextsw_cday, rstwr, nlend, rdate )
call t_stopf ('clm_run2')
! Map land data type to MCT
call t_startf ('lc_lnd_export')
call lnd_export_mct
( clm_l2a, l2x_l_clm, begg_l, endg_l )
call map_maparrayl
(begg_l, endg_l, begg_a, endg_a, nflds_l2x, &
l2x_l_clm, l2x_l, map1dl_l2a)
! Reset landfrac on atmosphere grid to have the right domain
do g = begg_a,endg_a
l2x_l%rAttr(index_l2x_Sl_landfrac,g-begg_a+1) = adomain%frac(g)
end do
call t_stopf ('lc_lnd_export')
! Compute snapshot attribute vector for accumulation
! don't accumulate on first coupling freq ts0 and ts1
! for consistency with ccsm3 when flxave is off
nstep = get_nstep
()
if (nstep <= 1) then
call mct_aVect_copy( l2x_l, l2x_l_SUM )
avg_count = 1
else
call mct_aVect_copy( l2x_l, l2x_l_SNAP )
call mct_aVect_accum
( aVin=l2x_l_SNAP, aVout=l2x_l_SUM )
avg_count = avg_count + 1
endif
if (create_glacier_mec_landunit) then
! Map sno data type to MCT
call create_clm_s2x
(clm_s2x)
call t_startf ('lc_clm_maps2a')
call clm_maps2x
(clm_s2x, atm_s2x)
call t_stopf ('lc_clm_maps2a')
call t_startf ('lc_sno_export')
call sno_export_mct
( atm_s2x, s2x_s )
call t_stopf ('lc_sno_export')
if (nstep <= 1) then
call mct_aVect_copy( s2x_s, s2x_s_SUM )
avg_count_sno = 1
else
call mct_aVect_copy( s2x_s, s2x_s_SNAP )
call mct_aVect_accum
( aVin=s2x_s_SNAP, aVout=s2x_s_SUM )
avg_count_sno = avg_count_sno + 1
endif
endif ! create_glacier_mec_landunit
! Advance clm time step
call t_startf ('lc_clm2_adv_timestep')
call advance_timestep
()
call t_stopf ('lc_clm2_adv_timestep')
end do
! Finish accumulation of attribute vector and average and zero out partial sum and counter
call mct_aVect_avg
( l2x_l_SUM, avg_count)
call mct_aVect_copy( l2x_l_SUM, l2x_l )
call mct_aVect_zero( l2x_l_SUM)
avg_count = 0
if (create_glacier_mec_landunit) then
call seq_infodata_GetData
(infodata, glcrun_alarm = glcrun_alarm )
if (glcrun_alarm) then
call mct_aVect_avg
( s2x_s_SUM, avg_count_sno)
call mct_aVect_copy( s2x_s_SUM, s2x_s )
call mct_aVect_zero( s2x_s_SUM)
avg_count_sno = 0
endif
endif
#ifdef RTM
! Create river runoff output state
call t_startf ('lc_rof_export')
call rof_export_mct
( r2x_r )
call t_stopf ('lc_rof_export')
#endif
! Check that internal clock is in sync with master clock
call get_curr_date
( yr, mon, day, tod, offset=-dtime )
ymd = yr*10000 + mon*100 + day
tod = tod
if ( .not. seq_timemgr_EClockDateInSync( EClock, ymd, tod ) )then
call seq_timemgr_EclockGetData
( EClock, curr_ymd=ymd_sync, curr_tod=tod_sync )
write(iulog,*)' clm ymd=',ymd ,' clm tod= ',tod
write(iulog,*)'sync ymd=',ymd_sync,' sync tod= ',tod_sync
call endrun
( sub//":: CLM clock not in sync with Master Sync clock" )
end if
! Reset shr logging to my original values
call shr_file_setLogUnit
(shrlogunit)
call shr_file_setLogLevel
(shrloglev)
#if (defined _MEMTRACE)
if(masterproc) then
lbnum=1
call memmon_dump_fort('memmon.out','lnd_run_mct:end::',lbnum)
call memmon_reset_addr()
endif
#endif
first_call = .false.
end subroutine lnd_run_mct
!---------------------------------------------------------------------------
!BOP
!
! !IROUTINE: lnd_final_mct
!
! !INTERFACE:
subroutine lnd_final_mct( ) 1
!
! !DESCRIPTION:
! Finalize land surface model
!
!------------------------------------------------------------------------------
!
implicit none
! !ARGUMENTS:
!
! !REVISION HISTORY:
! Author: Mariana Vertenstein
!
!EOP
!---------------------------------------------------------------------------
! fill this in
end subroutine lnd_final_mct
!=================================================================================
!---------------------------------------------------------------------------
!BOP
!
! !IROUTINE: lnd_SetgsMap_mct
!
! !INTERFACE:
subroutine lnd_SetgsMap_mct( mpicom_lnd, LNDID, gsMap_lnd ) 2,5
!-------------------------------------------------------------------
!
! !DESCRIPTION:
!
! Set the MCT GS map for the land model
!
!-------------------------------------------------------------------
! !USES:
use shr_kind_mod
, only : r8 => shr_kind_r8
use decompMod
, only : get_proc_bounds_atm, adecomp
use domainMod
, only : adomain
use mct_mod
, only : mct_gsMap, mct_gsMap_init
implicit none
! !ARGUMENTS:
integer , intent(in) :: mpicom_lnd ! MPI communicator for the clm land model
integer , intent(in) :: LNDID ! Land model identifyer number
type(mct_gsMap), intent(out) :: gsMap_lnd ! Resulting MCT GS map for the land model
!
! !LOCAL VARIABLES:
integer,allocatable :: gindex(:) ! Number the local grid points
integer :: i, j, n, gi ! Indices
integer :: lsize,gsize ! GS Map size
integer :: ier ! Error code
integer :: begg, endg ! Beginning/Ending grid cell index
!
! !REVISION HISTORY:
! Author: Mariana Vertenstein
!
!EOP
!---------------------------------------------------------------------------
! Build the land grid numbering for MCT
! NOTE: Numbering scheme is: West to East and South to North
! starting at south pole. Should be the same as what's used in SCRIP
call get_proc_bounds_atm
(begg, endg)
allocate(gindex(begg:endg),stat=ier)
! number the local grid
do n = begg, endg
gindex(n) = adecomp%gdc2glo(n)
end do
lsize = endg-begg+1
gsize = adomain%ni*adomain%nj
call mct_gsMap_init( gsMap_lnd, gindex, mpicom_lnd, LNDID, lsize, gsize )
deallocate(gindex)
end subroutine lnd_SetgsMap_mct
!=================================================================================
!---------------------------------------------------------------------------
!BOP
!
! !IROUTINE: lnd_chkAerDep_mct
!
! !INTERFACE:
subroutine lnd_chkAerDep_mct( infodata ) 1,12
!
! !DESCRIPTION:
! Check infodata to see if aerosol deposition data is sent to the land model.
! If data is NOT sent, read in CLM version of datasets that have this information.
!
!------------------------------------------------------------------------------
! !USES:
use shr_const_mod
, only : spval => SHR_CONST_SPVAL
use shr_sys_mod
, only : shr_sys_flush
use clm_varctl
, only : iulog
use clm_varctl
, only : set_caerdep_from_file, set_dustdep_from_file
use abortutils
, only : endrun
use seq_flds_indices
, only : index_x2l_Faxa_bcphidry, index_x2l_Faxa_bcphodry, &
index_x2l_Faxa_bcphiwet, &
index_x2l_Faxa_ocphidry, index_x2l_Faxa_ocphodry, &
index_x2l_Faxa_ocphiwet, &
index_x2l_Faxa_dstdry1, index_x2l_Faxa_dstdry2, &
index_x2l_Faxa_dstdry3, index_x2l_Faxa_dstdry4, &
index_x2l_Faxa_dstwet1, index_x2l_Faxa_dstwet2, &
index_x2l_Faxa_dstwet3, index_x2l_Faxa_dstwet4
use seq_infodata_mod
, only : seq_infodata_type, seq_infodata_GetData
use spmdMod
, only : masterproc
use aerdepMod
, only : aerdepini
implicit none
!
! !ARGUMENTS:
type(seq_infodata_type),pointer :: infodata ! CCSM information from the driver
!
! !LOCAL VARIABLES:
logical :: caerdep_filled = .true. ! Flag if carbon aerosol deposition is filled
logical :: dustdep_filled = .true. ! Flag if dust deposition is filled
logical :: atm_aero ! Flag if aerosol data sent from atm model
!
! !REVISION HISTORY:
! Author: Erik Kluzek
!
!EOP
!---------------------------------------------------------------------------
call seq_infodata_GetData
(infodata, atm_aero=atm_aero )
if ( .not. atm_aero )then
caerdep_filled = .false.
dustdep_filled = .false.
end if
if ( caerdep_filled )then
if ( masterproc ) &
write(iulog,*) "Using aerosol deposition sent from atmosphere model"
else
if ( masterproc ) then
write(iulog,*) "WARNING: carbon aerosol deposition data NOT sent in from atmosphere model"
write(iulog,*) "WARNING: Reading carbon aerosol deposition from CLM input file"
end if
end if
if ( dustdep_filled )then
if ( masterproc ) &
write(iulog,*) "Using dust deposition sent from atmosphere model"
else
if ( masterproc ) then
write(iulog,*) "WARNING: dust deposition data NOT sent in from atmosphere model"
write(iulog,*) "WARNING: Reading dust deposition from CLM input file"
end if
end if
call shr_sys_flush
( iulog )
set_caerdep_from_file = .not. caerdep_filled
set_dustdep_from_file = .not. dustdep_filled
if ( .not. atm_aero )then
call aerdepini
( )
end if
end subroutine lnd_chkAerDep_mct
!=================================================================================
!---------------------------------------------------------------------------
!BOP
!
! !IROUTINE: lnd_export_mct
!
! !INTERFACE:
subroutine lnd_export_mct( l2a, l2x_l, begg, endg ) 2,6
!
! !DESCRIPTION:
!
! Convert the data to be sent from the clm model to the coupler from clm data types
! to MCT data types.
!
!---------------------------------------------------------------------------
! !USES:
use shr_kind_mod
, only : r8 => shr_kind_r8
use clm_time_manager
, only : get_nstep
use clm_atmlnd
, only : lnd2atm_type
use domainMod
, only : adomain
use seq_drydep_mod
, only : n_drydep
use seq_flds_indices
implicit none
! !ARGUMENTS:
type(lnd2atm_type), intent(inout) :: l2a ! clm land to atmosphere exchange data type
type(mct_aVect) , intent(inout) :: l2x_l ! Land to coupler export state on land grid
integer , intent(in) :: begg ! beginning grid cell index
integer , intent(in) :: endg ! ending grid cell index
!
! !LOCAL VARIABLES:
integer :: g,i ! Indices
!
! !REVISION HISTORY:
! Author: Mariana Vertenstein
!
!EOP
!---------------------------------------------------------------------------
l2x_l%rAttr(:,:) = 0.0_r8
! ccsm sign convention is that fluxes are positive downward
do g = begg,endg
i = 1 + (g-begg)
l2x_l%rAttr(index_l2x_Sl_landfrac,i) = 0._r8 ! Will be filled in later
l2x_l%rAttr(index_l2x_Sl_t,i) = l2a%t_rad(g)
l2x_l%rAttr(index_l2x_Sl_snowh,i) = l2a%h2osno(g)
l2x_l%rAttr(index_l2x_Sl_avsdr,i) = l2a%albd(g,1)
l2x_l%rAttr(index_l2x_Sl_anidr,i) = l2a%albd(g,2)
l2x_l%rAttr(index_l2x_Sl_avsdf,i) = l2a%albi(g,1)
l2x_l%rAttr(index_l2x_Sl_anidf,i) = l2a%albi(g,2)
l2x_l%rAttr(index_l2x_Sl_tref,i) = l2a%t_ref2m(g)
l2x_l%rAttr(index_l2x_Sl_qref,i) = l2a%q_ref2m(g)
l2x_l%rAttr(index_l2x_Fall_taux,i) = -l2a%taux(g)
l2x_l%rAttr(index_l2x_Fall_tauy,i) = -l2a%tauy(g)
l2x_l%rAttr(index_l2x_Fall_lat,i) = -l2a%eflx_lh_tot(g)
l2x_l%rAttr(index_l2x_Fall_sen,i) = -l2a%eflx_sh_tot(g)
l2x_l%rAttr(index_l2x_Fall_lwup,i) = -l2a%eflx_lwrad_out(g)
l2x_l%rAttr(index_l2x_Fall_evap,i) = -l2a%qflx_evap_tot(g)
l2x_l%rAttr(index_l2x_Fall_swnet,i) = l2a%fsa(g)
if (index_l2x_Fall_nee /= 0) then
l2x_l%rAttr(index_l2x_Fall_nee,i) = -l2a%nee(g)
end if
! optional fields for dust. The index = 0 is a good way to flag it,
! but I have set it up so that l2a doesn't have ram1,fv,flxdst[1-4] if
! progsslt or dust aren't running.
#if ( defined DUST || defined PROGSSLT )
if (index_l2x_Sl_ram1 /= 0 ) l2x_l%rAttr(index_l2x_Sl_ram1,i) = l2a%ram1(g)
if (index_l2x_Sl_fv /= 0 ) l2x_l%rAttr(index_l2x_Sl_fv,i) = l2a%fv(g)
#endif
#if ( defined DUST )
if (index_l2x_Fall_flxdst1 /= 0 ) l2x_l%rAttr(index_l2x_Fall_flxdst1,i)= -l2a%flxdst(g,1)
if (index_l2x_Fall_flxdst2 /= 0 ) l2x_l%rAttr(index_l2x_Fall_flxdst2,i)= -l2a%flxdst(g,2)
if (index_l2x_Fall_flxdst3 /= 0 ) l2x_l%rAttr(index_l2x_Fall_flxdst3,i)= -l2a%flxdst(g,3)
if (index_l2x_Fall_flxdst4 /= 0 ) l2x_l%rAttr(index_l2x_Fall_flxdst4,i)= -l2a%flxdst(g,4)
#endif
if ( index_l2x_Sl_ddvel /= 0 ) l2x_l%rAttr(index_l2x_Sl_ddvel:index_l2x_Sl_ddvel+n_drydep-1,i) = l2a%ddvel(g,:n_drydep)
#ifdef VOC
if (index_l2x_Fall_flxvoc1 /= 0 ) l2x_l%rAttr(index_l2x_Fall_flxvoc1,i)= -l2a%flxvoc(g,1)
if (index_l2x_Fall_flxvoc2 /= 0 ) l2x_l%rAttr(index_l2x_Fall_flxvoc2,i)= -l2a%flxvoc(g,2)
if (index_l2x_Fall_flxvoc3 /= 0 ) l2x_l%rAttr(index_l2x_Fall_flxvoc3,i)= -l2a%flxvoc(g,3)
if (index_l2x_Fall_flxvoc4 /= 0 ) l2x_l%rAttr(index_l2x_Fall_flxvoc4,i)= -l2a%flxvoc(g,4)
if (index_l2x_Fall_flxvoc5 /= 0 ) l2x_l%rAttr(index_l2x_Fall_flxvoc5,i)= -l2a%flxvoc(g,5)
#endif
end do
end subroutine lnd_export_mct
!====================================================================================
!---------------------------------------------------------------------------
!BOP
!
! !IROUTINE: lnd_import_mct
!
! !INTERFACE:
subroutine lnd_import_mct( x2l_l, a2l, begg, endg ) 2,13
!
! !DESCRIPTION:
!
! Convert the input data from the coupler to the land model from MCT import state
! into internal clm data types.
!
!---------------------------------------------------------------------------
! !USES:
use shr_kind_mod
, only: r8 => shr_kind_r8
use clm_atmlnd
, only: atm2lnd_type
use clm_varctl
, only: co2_type, co2_ppmv
use clm_varcon
, only: rair, o2_molar_const
#if (defined C13)
use clm_varcon
, only: c13ratio
#endif
use shr_const_mod
, only: SHR_CONST_TKFRZ
use abortutils
, only: endrun
use clm_varctl
, only: set_caerdep_from_file, set_dustdep_from_file
use clm_varctl
, only: iulog
use mct_mod
, only: mct_aVect
use seq_flds_indices
implicit none
! !ARGUMENTS:
type(mct_aVect) , intent(inout) :: x2l_l ! Driver MCT import state to land model
type(atm2lnd_type), intent(inout) :: a2l ! clm internal input data type
integer , intent(in) :: begg
integer , intent(in) :: endg
!
! !LOCAL VARIABLES:
integer :: g,i,nstep,ier ! indices, number of steps, and error code
real(r8) :: forc_rainc ! rainxy Atm flux mm/s
real(r8) :: e ! vapor pressure (Pa)
real(r8) :: qsat ! saturation specific humidity (kg/kg)
real(r8) :: forc_rainl ! rainxy Atm flux mm/s
real(r8) :: forc_snowc ! snowfxy Atm flux mm/s
real(r8) :: forc_snowl ! snowfxl Atm flux mm/s
real(r8) :: co2_ppmv_diag ! temporary
real(r8) :: co2_ppmv_prog ! temporary
real(r8) :: co2_ppmv_val ! temporary
integer :: co2_type_idx ! integer flag for co2_type options
real(r8) :: esatw ! saturation vapor pressure over water (Pa)
real(r8) :: esati ! saturation vapor pressure over ice (Pa)
real(r8) :: a0,a1,a2,a3,a4,a5,a6 ! coefficients for esat over water
real(r8) :: b0,b1,b2,b3,b4,b5,b6 ! coefficients for esat over ice
real(r8) :: tdc, t ! Kelvins to Celcius function and its input
character(len=32), parameter :: sub = 'lnd_import_mct'
! Constants to compute vapor pressure
parameter (a0=6.107799961_r8 , a1=4.436518521e-01_r8, &
a2=1.428945805e-02_r8, a3=2.650648471e-04_r8, &
a4=3.031240396e-06_r8, a5=2.034080948e-08_r8, &
a6=6.136820929e-11_r8)
parameter (b0=6.109177956_r8 , b1=5.034698970e-01_r8, &
b2=1.886013408e-02_r8, b3=4.176223716e-04_r8, &
b4=5.824720280e-06_r8, b5=4.838803174e-08_r8, &
b6=1.838826904e-10_r8)
!
! function declarations
!
tdc(t) = min( 50._r8, max(-50._r8,(t-SHR_CONST_TKFRZ)) )
esatw(t) = 100._r8*(a0+t*(a1+t*(a2+t*(a3+t*(a4+t*(a5+t*a6))))))
esati(t) = 100._r8*(b0+t*(b1+t*(b2+t*(b3+t*(b4+t*(b5+t*b6))))))
!
! !REVISION HISTORY:
! Author: Mariana Vertenstein
! 27 February 2008: Keith Oleson; Forcing height change
!
!EOP
!---------------------------------------------------------------------------
co2_type_idx = 0
if (co2_type == 'prognostic') then
co2_type_idx = 1
else if (co2_type == 'diagnostic') then
co2_type_idx = 2
end if
if (co2_type == 'prognostic' .and. index_x2l_Sa_co2prog == 0) then
call endrun
( sub//' ERROR: must have nonzero index_x2l_Sa_co2prog for co2_type equal to prognostic' )
else if (co2_type == 'diagnostic' .and. index_x2l_Sa_co2diag == 0) then
call endrun
( sub//' ERROR: must have nonzero index_x2l_Sa_co2diag for co2_type equal to diagnostic' )
end if
! Note that the precipitation fluxes received from the coupler
! are in units of kg/s/m^2. To convert these precipitation rates
! in units of mm/sec, one must divide by 1000 kg/m^3 and multiply
! by 1000 mm/m resulting in an overall factor of unity.
! Below the units are therefore given in mm/s.
do g = begg,endg
i = 1 + (g - begg)
! Determine required receive fields
a2l%forc_hgt(g) = x2l_l%rAttr(index_x2l_Sa_z,i) ! zgcmxy Atm state m
a2l%forc_u(g) = x2l_l%rAttr(index_x2l_Sa_u,i) ! forc_uxy Atm state m/s
a2l%forc_v(g) = x2l_l%rAttr(index_x2l_Sa_v,i) ! forc_vxy Atm state m/s
a2l%forc_th(g) = x2l_l%rAttr(index_x2l_Sa_ptem,i) ! forc_thxy Atm state K
a2l%forc_q(g) = x2l_l%rAttr(index_x2l_Sa_shum,i) ! forc_qxy Atm state kg/kg
a2l%forc_pbot(g) = x2l_l%rAttr(index_x2l_Sa_pbot,i) ! ptcmxy Atm state Pa
a2l%forc_t(g) = x2l_l%rAttr(index_x2l_Sa_tbot,i) ! forc_txy Atm state K
a2l%forc_lwrad(g) = x2l_l%rAttr(index_x2l_Faxa_lwdn,i) ! flwdsxy Atm flux W/m^2
forc_rainc = x2l_l%rAttr(index_x2l_Faxa_rainc,i) ! mm/s
forc_rainl = x2l_l%rAttr(index_x2l_Faxa_rainl,i) ! mm/s
forc_snowc = x2l_l%rAttr(index_x2l_Faxa_snowc,i) ! mm/s
forc_snowl = x2l_l%rAttr(index_x2l_Faxa_snowl,i) ! mm/s
a2l%forc_solad(g,2) = x2l_l%rAttr(index_x2l_Faxa_swndr,i) ! forc_sollxy Atm flux W/m^2
a2l%forc_solad(g,1) = x2l_l%rAttr(index_x2l_Faxa_swvdr,i) ! forc_solsxy Atm flux W/m^2
a2l%forc_solai(g,2) = x2l_l%rAttr(index_x2l_Faxa_swndf,i) ! forc_solldxy Atm flux W/m^2
a2l%forc_solai(g,1) = x2l_l%rAttr(index_x2l_Faxa_swvdf,i) ! forc_solsdxy Atm flux W/m^2
! atmosphere coupling, if using prognostic aerosols
if ( .not. set_caerdep_from_file ) then
a2l%forc_aer(g,1) = x2l_l%rAttr(index_x2l_Faxa_bcphidry,i)
a2l%forc_aer(g,2) = x2l_l%rAttr(index_x2l_Faxa_bcphodry,i)
a2l%forc_aer(g,3) = x2l_l%rAttr(index_x2l_Faxa_bcphiwet,i)
a2l%forc_aer(g,4) = x2l_l%rAttr(index_x2l_Faxa_ocphidry,i)
a2l%forc_aer(g,5) = x2l_l%rAttr(index_x2l_Faxa_ocphodry,i)
a2l%forc_aer(g,6) = x2l_l%rAttr(index_x2l_Faxa_ocphiwet,i)
endif
if ( .not. set_dustdep_from_file ) then
a2l%forc_aer(g,7) = x2l_l%rAttr(index_x2l_Faxa_dstwet1,i)
a2l%forc_aer(g,8) = x2l_l%rAttr(index_x2l_Faxa_dstdry1,i)
a2l%forc_aer(g,9) = x2l_l%rAttr(index_x2l_Faxa_dstwet2,i)
a2l%forc_aer(g,10) = x2l_l%rAttr(index_x2l_Faxa_dstdry2,i)
a2l%forc_aer(g,11) = x2l_l%rAttr(index_x2l_Faxa_dstwet3,i)
a2l%forc_aer(g,12) = x2l_l%rAttr(index_x2l_Faxa_dstdry3,i)
a2l%forc_aer(g,13) = x2l_l%rAttr(index_x2l_Faxa_dstwet4,i)
a2l%forc_aer(g,14) = x2l_l%rAttr(index_x2l_Faxa_dstdry4,i)
endif
! Determine optional receive fields
if (index_x2l_Sa_co2prog /= 0) then
co2_ppmv_prog = x2l_l%rAttr(index_x2l_Sa_co2prog,i) ! co2 atm state prognostic
else
co2_ppmv_prog = co2_ppmv
end if
if (index_x2l_Sa_co2diag /= 0) then
co2_ppmv_diag = x2l_l%rAttr(index_x2l_Sa_co2diag,i) ! co2 atm state diagnostic
else
co2_ppmv_diag = co2_ppmv
end if
! Determine derived quantities for required fields
a2l%forc_hgt_u(g) = a2l%forc_hgt(g) !observational height of wind [m]
a2l%forc_hgt_t(g) = a2l%forc_hgt(g) !observational height of temperature [m]
a2l%forc_hgt_q(g) = a2l%forc_hgt(g) !observational height of humidity [m]
a2l%forc_vp(g) = a2l%forc_q(g) * a2l%forc_pbot(g) &
/ (0.622_r8 + 0.378_r8 * a2l%forc_q(g))
a2l%forc_rho(g) = (a2l%forc_pbot(g) - 0.378_r8 * a2l%forc_vp(g)) &
/ (rair * a2l%forc_t(g))
a2l%forc_po2(g) = o2_molar_const * a2l%forc_pbot(g)
a2l%forc_wind(g) = sqrt(a2l%forc_u(g)**2 + a2l%forc_v(g)**2)
a2l%forc_solar(g) = a2l%forc_solad(g,1) + a2l%forc_solai(g,1) + &
a2l%forc_solad(g,2) + a2l%forc_solai(g,2)
a2l%forc_rain(g) = forc_rainc + forc_rainl
a2l%forc_snow(g) = forc_snowc + forc_snowl
a2l%rainf (g) = a2l%forc_rain(g) + a2l%forc_snow(g)
if (a2l%forc_t(g) > SHR_CONST_TKFRZ) then
e = esatw(tdc(a2l%forc_t(g)))
else
e = esati(tdc(a2l%forc_t(g)))
end if
qsat = 0.622_r8*e / (a2l%forc_pbot(g) - 0.378_r8*e)
a2l%forc_rh(g) = 100.0_r8*(a2l%forc_q(g) / qsat)
! Make sure relative humidity is properly bounded
! a2l%forc_rh(g) = min( 100.0_r8, a2l%forc_rh(g) )
! a2l%forc_rh(g) = max( 0.0_r8, a2l%forc_rh(g) )
! Determine derived quantities for optional fields
! Note that the following does unit conversions from ppmv to partial pressures (Pa)
! Note that forc_pbot is in Pa
if (co2_type_idx == 1) then
co2_ppmv_val = co2_ppmv_prog
else if (co2_type_idx == 2) then
co2_ppmv_val = co2_ppmv_diag
else
co2_ppmv_val = co2_ppmv
end if
a2l%forc_pco2(g) = co2_ppmv_val * 1.e-6_r8 * a2l%forc_pbot(g)
#if (defined C13)
a2l%forc_pc13o2(g) = co2_ppmv_val * c13ratio * 1.e-6_r8 * a2l%forc_pbot(g)
#endif
end do
end subroutine lnd_import_mct
!===============================================================================
!---------------------------------------------------------------------------
!BOP
!
! !IROUTINE: lnd_domain_mct
!
! !INTERFACE:
subroutine lnd_domain_mct( lsize, gsMap_l, dom_l ) 2,8
!
! !DESCRIPTION:
!
! Send the land model domain information to the coupler
!
!---------------------------------------------------------------------------
! !USES:
use shr_kind_mod
, only : r8 => shr_kind_r8
use clm_varcon
, only : re
use domainMod
, only : adomain
use decompMod
, only : get_proc_bounds_atm, adecomp
use spmdMod
, only : iam
use mct_mod
, only : mct_gsMap, mct_gGrid, mct_gGrid_importIAttr, &
mct_gGrid_importRAttr, mct_gGrid_init, &
mct_gsMap_orderedPoints
use seq_flds_mod
implicit none
! !ARGUMENTS:
integer , intent(in) :: lsize ! land model domain data size
type(mct_gsMap), intent(inout) :: gsMap_l ! Output land model MCT GS map
type(mct_ggrid), intent(out) :: dom_l ! Output domain information for land model
!
! !REVISION HISTORY:
! Author: Mariana Vertenstein
!
!EOP
!---------------------------------------------------------------------------
!
! Local Variables
!
integer :: g,i,j ! index
integer :: begg, endg ! beginning and ending gridcell indices
real(r8), pointer :: data(:) ! temporary
integer , pointer :: idata(:) ! temporary
!-------------------------------------------------------------------
!
! Initialize mct domain type
! lat/lon in degrees, area in radians^2, mask is 1 (land), 0 (non-land)
! Note that in addition land carries around landfrac for the purposes of domain checking
!
call mct_gGrid_init( GGrid=dom_l, CoordChars=trim(seq_flds_dom_coord), &
OtherChars=trim(seq_flds_dom_other), lsize=lsize )
!
! Allocate memory
!
allocate(data(lsize))
!
! Determine global gridpoint number attribute, GlobGridNum, which is set automatically by MCT
!
call mct_gsMap_orderedPoints(gsMap_l, iam, idata)
call mct_gGrid_importIAttr(dom_l,'GlobGridNum',idata,lsize)
!
! Determine domain (numbering scheme is: West to East and South to North to South pole)
! Initialize attribute vector with special value
!
data(:) = -9999.0_R8
call mct_gGrid_importRAttr(dom_l,"lat" ,data,lsize)
call mct_gGrid_importRAttr(dom_l,"lon" ,data,lsize)
call mct_gGrid_importRAttr(dom_l,"area" ,data,lsize)
call mct_gGrid_importRAttr(dom_l,"aream",data,lsize)
data(:) = 0.0_R8
call mct_gGrid_importRAttr(dom_l,"mask" ,data,lsize)
!
! Determine bounds
!
call get_proc_bounds_atm
(begg, endg)
!
! Fill in correct values for domain components
! Note aream will be filled in in the atm-lnd mapper
!
do g = begg,endg
i = 1 + (g - begg)
data(i) = adomain%lonc(g)
end do
call mct_gGrid_importRattr(dom_l,"lon",data,lsize)
do g = begg,endg
i = 1 + (g - begg)
data(i) = adomain%latc(g)
end do
call mct_gGrid_importRattr(dom_l,"lat",data,lsize)
do g = begg,endg
i = 1 + (g - begg)
data(i) = adomain%area(g)/(re*re)
end do
call mct_gGrid_importRattr(dom_l,"area",data,lsize)
do g = begg,endg
i = 1 + (g - begg)
data(i) = real(adomain%mask(g), r8)
end do
call mct_gGrid_importRattr(dom_l,"mask",data,lsize)
do g = begg,endg
i = 1 + (g - begg)
data(i) = real(adomain%frac(g), r8)
end do
call mct_gGrid_importRattr(dom_l,"frac",data,lsize)
deallocate(data)
deallocate(idata)
end subroutine lnd_domain_mct
!===============================================================================
#ifdef RTM
!---------------------------------------------------------------------------
!BOP
!
! !IROUTINE: rof_SetgsMap_mct
!
! !INTERFACE:
subroutine rof_SetgsMap_mct( mpicom_l, LNDID, gsMap_r ) 1,8
!
! !DESCRIPTION:
!
! Set the MCT GS map for the runoff model
!
!---------------------------------------------------------------------------
! !USES:
use shr_kind_mod
, only : r8 => shr_kind_r8
use clm_varpar
, only : rtmlon, rtmlat
use RunoffMod
, only : runoff
use abortutils
, only : endrun
use clm_varctl
, only : iulog
use mct_mod
, only : mct_gsMap, mct_gsMap_init
implicit none
! !ARGUMENTS:
integer , intent(in) :: mpicom_l ! MPI communicator for land model
integer , intent(in) :: LNDID ! Land model identifier
type(mct_gsMap), intent(out) :: gsMap_r ! MCT GS map for runoff model data
!
! !REVISION HISTORY:
! Author: Mariana Vertenstein
!
!EOP
!---------------------------------------------------------------------------
!
! Local Variables
!
integer,allocatable :: gindex(:) ! indexing for runoff grid cells
integer :: n, ni ! indices
integer :: lsize,gsize ! size of runoff data and number of grid cells
integer :: ier ! error code
character(len=32), parameter :: sub = 'rof_SetgsMap_mct'
!-------------------------------------------------------------------
! Build the rof grid numbering for MCT
! NOTE: Numbering scheme is: West to East and South to North
! starting at south pole. Should be the same as what's used in SCRIP
gsize = rtmlon*rtmlat
lsize = runoff%lnumro
allocate(gindex(lsize),stat=ier)
ni = 0
do n = runoff%begr,runoff%endr
if (runoff%mask(n) == 2) then
ni = ni + 1
if (ni > runoff%lnumro) then
write(iulog,*) sub, ' : ERROR runoff count',n,ni,runoff%lnumro
call endrun
( sub//' ERROR: runoff > expected' )
endif
gindex(ni) = runoff%gindex(n)
endif
end do
if (ni /= runoff%lnumro) then
write(iulog,*) sub, ' : ERROR runoff total count',ni,runoff%lnumro
call endrun
( sub//' ERROR: runoff not equal to expected' )
endif
call mct_gsMap_init( gsMap_r, gindex, mpicom_l, LNDID, lsize, gsize )
deallocate(gindex)
end subroutine rof_SetgsMap_mct
!===============================================================================
!---------------------------------------------------------------------------
!BOP
!
! !IROUTINE: rof_domain_mct
!
! !INTERFACE:
subroutine rof_domain_mct( lsize, gsMap_r, dom_r ) 1,11
!
! !DESCRIPTION:
!
! Send the runoff model domain information to the coupler
!
!---------------------------------------------------------------------------
! !USES:
use shr_kind_mod
, only : r8 => shr_kind_r8
use clm_varcon
, only : re
use RunoffMod
, only : runoff
use abortutils
, only : endrun
use clm_varctl
, only : iulog
use spmdMod
, only : iam
use mct_mod
, only : mct_gsMap, mct_gGrid, mct_gGrid_importIAttr, &
mct_gGrid_importRAttr, mct_gGrid_init, mct_gsMap_orderedPoints
use seq_flds_mod
use seq_flds_indices
implicit none
! !ARGUMENTS:
integer , intent(in) :: lsize ! Size of runoff domain information
type(mct_gsMap), intent(inout) :: gsMap_r ! Output MCT GS map for runoff model
type(mct_ggrid), intent(out) :: dom_r ! Domain information from the runoff model
!
! !REVISION HISTORY:
! Author: Mariana Vertenstein
!
!EOP
!---------------------------------------------------------------------------
!
! Local Variables
!
integer :: n, ni ! index
real(r8), pointer :: data(:) ! temporary
integer , pointer :: idata(:) ! temporary
character(len=32), parameter :: sub = 'rof_domain_mct'
!-------------------------------------------------------------------
!
! Initialize mct domain type
! lat/lon in degrees, area in radians^2, mask is 1 (land), 0 (non-land)
! Note that in addition land carries around landfrac for the purposes of domain checking
!
call mct_gGrid_init( GGrid=dom_r, CoordChars=trim(seq_flds_dom_coord), &
OtherChars=trim(seq_flds_dom_other), lsize=lsize )
!
! Allocate memory
!
allocate(data(lsize))
!
! Determine global gridpoint number attribute, GlobGridNum, which is set automatically by MCT
!
call mct_gsMap_orderedPoints(gsMap_r, iam, idata)
call mct_gGrid_importIAttr(dom_r,'GlobGridNum',idata,lsize)
!
! Determine domain (numbering scheme is: West to East and South to North to South pole)
! Initialize attribute vector with special value
!
data(:) = -9999.0_R8
call mct_gGrid_importRAttr(dom_r,"lat" ,data,lsize)
call mct_gGrid_importRAttr(dom_r,"lon" ,data,lsize)
call mct_gGrid_importRAttr(dom_r,"area" ,data,lsize)
call mct_gGrid_importRAttr(dom_r,"aream",data,lsize)
data(:) = 0.0_R8
call mct_gGrid_importRAttr(dom_r,"mask" ,data,lsize)
!
! Determine bounds numbering consistency
!
ni = 0
do n = runoff%begr,runoff%endr
if (runoff%mask(n) == 2) then
ni = ni + 1
if (ni > runoff%lnumro) then
write(iulog,*) sub, ' : ERROR runoff count',n,ni,runoff%lnumro
call endrun
( sub//' ERROR: runoff > expected' )
endif
end if
end do
if (ni /= runoff%lnumro) then
write(iulog,*) sub, ' : ERROR runoff total count',ni,runoff%lnumro
call endrun
( sub//' ERROR: runoff not equal to expected' )
endif
!
! Fill in correct values for domain components
! Note aream will be filled in in the atm-lnd mapper
!
ni = 0
do n = runoff%begr,runoff%endr
if (runoff%mask(n) == 2) then
ni = ni + 1
data(ni) = runoff%lonc(n)
end if
end do
call mct_gGrid_importRattr(dom_r,"lon",data,lsize)
ni = 0
do n = runoff%begr,runoff%endr
if (runoff%mask(n) == 2) then
ni = ni + 1
data(ni) = runoff%latc(n)
end if
end do
call mct_gGrid_importRattr(dom_r,"lat",data,lsize)
ni = 0
do n = runoff%begr,runoff%endr
if (runoff%mask(n) == 2) then
ni = ni + 1
data(ni) = runoff%area(n)*1.0e-6_r8/(re*re)
end if
end do
call mct_gGrid_importRattr(dom_r,"area",data,lsize)
ni = 0
do n = runoff%begr,runoff%endr
if (runoff%mask(n) == 2) then
ni = ni + 1
data(ni) = 1.0_r8
end if
end do
call mct_gGrid_importRattr(dom_r,"mask",data,lsize)
call mct_gGrid_importRattr(dom_r,"frac",data,lsize)
deallocate(data)
deallocate(idata)
end subroutine rof_domain_mct
!====================================================================================
!---------------------------------------------------------------------------
!BOP
!
! !IROUTINE: rof_export_mct
!
! !INTERFACE:
subroutine rof_export_mct( r2x_r) 2,10
!
! !DESCRIPTION:
!
! Send the runoff model export state to the CCSM coupler
!
!---------------------------------------------------------------------------
! !USES:
use shr_kind_mod
, only : r8 => shr_kind_r8
use RunoffMod
, only : runoff, nt_rtm, rtm_tracers
use abortutils
, only : endrun
use clm_varctl
, only : iulog, ice_runoff
use mct_mod
, only : mct_aVect
use seq_flds_indices
implicit none
! !ARGUMENTS:
type(mct_aVect), intent(inout) :: r2x_r ! Runoff to coupler export state
!
! !REVISION HISTORY:
! Author: Mariana Vertenstein
!
!EOP
!---------------------------------------------------------------------------
!
! Local variables
!
integer :: ni, n, nt, nliq, nfrz
character(len=32), parameter :: sub = 'rof_export_mct'
!-----------------------------------------------------
nliq = 0
nfrz = 0
do nt = 1,nt_rtm
if (trim(rtm_tracers(nt)) == 'LIQ') then
nliq = nt
endif
if (trim(rtm_tracers(nt)) == 'ICE') then
nfrz = nt
endif
enddo
if (nliq == 0 .or. nfrz == 0) then
write(iulog,*)'RtmUpdateInput: ERROR in rtm_tracers LIQ ICE ',nliq,nfrz,rtm_tracers
call endrun
()
endif
ni = 0
if ( ice_runoff )then
do n = runoff%begr,runoff%endr
if (runoff%mask(n) == 2) then
ni = ni + 1
! liquid and ice runoff are treated separately
r2x_r%rAttr(index_r2x_Forr_roff,ni) = runoff%runoff(n,nliq)/(runoff%area(n)*1.0e-6_r8*1000._r8)
r2x_r%rAttr(index_r2x_Forr_ioff,ni) = runoff%runoff(n,nfrz)/(runoff%area(n)*1.0e-6_r8*1000._r8)
if (ni > runoff%lnumro) then
write(iulog,*) sub, ' : ERROR runoff count',n,ni
call endrun
( sub//' : ERROR runoff > expected' )
endif
endif
end do
else
do n = runoff%begr,runoff%endr
if (runoff%mask(n) == 2) then
ni = ni + 1
! liquid and ice runoff are bundled together to liquid runoff, and then ice runoff set to zero
r2x_r%rAttr(index_r2x_Forr_roff,ni) = &
(runoff%runoff(n,nfrz)+runoff%runoff(n,nliq))/(runoff%area(n)*1.0e-6_r8*1000._r8)
r2x_r%rAttr(index_r2x_Forr_ioff,ni) = 0._r8
if (ni > runoff%lnumro) then
write(iulog,*) sub, ' : ERROR runoff count',n,ni
call endrun
( sub//' : ERROR runoff > expected' )
endif
endif
end do
end if
if (ni /= runoff%lnumro) then
write(iulog,*) sub, ' : ERROR runoff total count',ni,runoff%lnumro
call endrun
( sub//' : ERROR runoff not equal to expected' )
endif
end subroutine rof_export_mct
#endif
!====================================================================================
subroutine sno_export_mct( s2x, s2x_s ) 2,4
use clm_glclnd
, only : lnd2glc_type
use decompMod
, only : get_proc_bounds_atm
use seq_flds_indices
type(lnd2glc_type), intent(inout) :: s2x
type(mct_aVect) , intent(inout) :: s2x_s
integer :: g,i
integer :: begg, endg ! beginning and ending gridcell indices
call get_proc_bounds_atm
(begg, endg)
s2x_s%rAttr(:,:) = 0.0_r8
! qice is positive if ice is growing, negative if melting
do g = begg,endg
i = 1 + (g-begg)
#if (defined GLC_NEC_10 || defined GLC_NEC_5 || defined GLC_NEC_3 || defined GLC_NEC_1)
s2x_s%rAttr(index_s2x_Ss_tsrf01,i) = s2x%tsrf(g,1)
s2x_s%rAttr(index_s2x_Ss_topo01,i) = s2x%topo(g,1)
s2x_s%rAttr(index_s2x_Fgss_qice01,i) = s2x%qice(g,1)
#endif
#if (defined GLC_NEC_10 || defined GLC_NEC_5 || defined GLC_NEC_3 )
s2x_s%rAttr(index_s2x_Ss_tsrf02,i) = s2x%tsrf(g,2)
s2x_s%rAttr(index_s2x_Ss_topo02,i) = s2x%topo(g,2)
s2x_s%rAttr(index_s2x_Fgss_qice02,i) = s2x%qice(g,2)
s2x_s%rAttr(index_s2x_Ss_tsrf03,i) = s2x%tsrf(g,3)
s2x_s%rAttr(index_s2x_Ss_topo03,i) = s2x%topo(g,3)
s2x_s%rAttr(index_s2x_Fgss_qice03,i) = s2x%qice(g,3)
#endif
#if (defined GLC_NEC_10 || defined GLC_NEC_5 )
s2x_s%rAttr(index_s2x_Ss_tsrf04,i) = s2x%tsrf(g,4)
s2x_s%rAttr(index_s2x_Ss_topo04,i) = s2x%topo(g,4)
s2x_s%rAttr(index_s2x_Fgss_qice04,i) = s2x%qice(g,4)
s2x_s%rAttr(index_s2x_Ss_tsrf05,i) = s2x%tsrf(g,5)
s2x_s%rAttr(index_s2x_Ss_topo05,i) = s2x%topo(g,5)
s2x_s%rAttr(index_s2x_Fgss_qice05,i) = s2x%qice(g,5)
#endif
#if (defined GLC_NEC_10 )
s2x_s%rAttr(index_s2x_Ss_tsrf06,i) = s2x%tsrf(g,6)
s2x_s%rAttr(index_s2x_Ss_topo06,i) = s2x%topo(g,6)
s2x_s%rAttr(index_s2x_Fgss_qice06,i) = s2x%qice(g,6)
s2x_s%rAttr(index_s2x_Ss_tsrf07,i) = s2x%tsrf(g,7)
s2x_s%rAttr(index_s2x_Ss_topo07,i) = s2x%topo(g,7)
s2x_s%rAttr(index_s2x_Fgss_qice07,i) = s2x%qice(g,7)
s2x_s%rAttr(index_s2x_Ss_tsrf08,i) = s2x%tsrf(g,8)
s2x_s%rAttr(index_s2x_Ss_topo08,i) = s2x%topo(g,8)
s2x_s%rAttr(index_s2x_Fgss_qice08,i) = s2x%qice(g,8)
s2x_s%rAttr(index_s2x_Ss_tsrf09,i) = s2x%tsrf(g,9)
s2x_s%rAttr(index_s2x_Ss_topo09,i) = s2x%topo(g,9)
s2x_s%rAttr(index_s2x_Fgss_qice09,i) = s2x%qice(g,9)
s2x_s%rAttr(index_s2x_Ss_tsrf10,i) = s2x%tsrf(g,10)
s2x_s%rAttr(index_s2x_Ss_topo10,i) = s2x%topo(g,10)
s2x_s%rAttr(index_s2x_Fgss_qice10,i) = s2x%qice(g,10)
#endif
end do ! g
end subroutine sno_export_mct
!====================================================================================
subroutine sno_import_mct( x2s_s, x2s ) 1,7
use clm_glclnd
, only: glc2lnd_type
use decompMod
, only: get_proc_bounds_atm
use abortutils
, only: endrun
use clm_varctl
, only: iulog
use mct_mod
, only: mct_aVect
use seq_flds_indices
!
! Arguments
!
type(mct_aVect) , intent(inout) :: x2s_s
type(glc2lnd_type), intent(inout) :: x2s
!
! Local Variables
!
integer :: g,i
integer :: begg, endg ! beginning and ending gridcell indices
character(len=32), parameter :: sub = 'sno_import_mct'
!-----------------------------------------------------
call get_proc_bounds_atm
(begg, endg)
do g = begg,endg
i = 1 + (g - begg)
#if (defined GLC_NEC_10 || defined GLC_NEC_5 || defined GLC_NEC_3 || defined GLC_NEC_1)
x2s%frac(g,1) = x2s_s%rAttr(index_x2s_Sg_frac01,i)
x2s%topo(g,1) = x2s_s%rAttr(index_x2s_Sg_topo01,i)
x2s%hflx(g,1) = x2s_s%rAttr(index_x2s_Fsgg_hflx01,i)
x2s%rofi(g,1) = x2s_s%rAttr(index_x2s_Fsgg_rofi01,i)
x2s%rofl(g,1) = x2s_s%rAttr(index_x2s_Fsgg_rofl01,i)
#endif
#if (defined GLC_NEC_10 || defined GLC_NEC_5 || defined GLC_NEC_3 )
x2s%frac(g,2) = x2s_s%rAttr(index_x2s_Sg_frac02,i)
x2s%topo(g,2) = x2s_s%rAttr(index_x2s_Sg_topo02,i)
x2s%hflx(g,2) = x2s_s%rAttr(index_x2s_Fsgg_hflx02,i)
x2s%rofi(g,2) = x2s_s%rAttr(index_x2s_Fsgg_rofi02,i)
x2s%rofi(g,2) = x2s_s%rAttr(index_x2s_Fsgg_rofl02,i)
x2s%frac(g,3) = x2s_s%rAttr(index_x2s_Sg_frac03,i)
x2s%topo(g,3) = x2s_s%rAttr(index_x2s_Sg_topo03,i)
x2s%hflx(g,3) = x2s_s%rAttr(index_x2s_Fsgg_hflx03,i)
x2s%rofi(g,3) = x2s_s%rAttr(index_x2s_Fsgg_rofi03,i)
x2s%rofl(g,3) = x2s_s%rAttr(index_x2s_Fsgg_rofl03,i)
#endif
#if (defined GLC_NEC_10 || defined GLC_NEC_5 )
x2s%frac(g,4) = x2s_s%rAttr(index_x2s_Sg_frac04,i)
x2s%topo(g,4) = x2s_s%rAttr(index_x2s_Sg_topo04,i)
x2s%hflx(g,4) = x2s_s%rAttr(index_x2s_Fsgg_hflx04,i)
x2s%rofi(g,4) = x2s_s%rAttr(index_x2s_Fsgg_rofi04,i)
x2s%rofl(g,4) = x2s_s%rAttr(index_x2s_Fsgg_rofl04,i)
x2s%frac(g,5) = x2s_s%rAttr(index_x2s_Sg_frac05,i)
x2s%topo(g,5) = x2s_s%rAttr(index_x2s_Sg_topo05,i)
x2s%hflx(g,5) = x2s_s%rAttr(index_x2s_Fsgg_hflx05,i)
x2s%rofi(g,5) = x2s_s%rAttr(index_x2s_Fsgg_rofi05,i)
x2s%rofl(g,5) = x2s_s%rAttr(index_x2s_Fsgg_rofl05,i)
#endif
#if (defined GLC_NEC_10 )
x2s%frac(g,6) = x2s_s%rAttr(index_x2s_Sg_frac06,i)
x2s%topo(g,6) = x2s_s%rAttr(index_x2s_Sg_topo06,i)
x2s%hflx(g,6) = x2s_s%rAttr(index_x2s_Fsgg_hflx06,i)
x2s%rofi(g,6) = x2s_s%rAttr(index_x2s_Fsgg_rofi06,i)
x2s%rofi(g,6) = x2s_s%rAttr(index_x2s_Fsgg_rofl06,i)
x2s%frac(g,7) = x2s_s%rAttr(index_x2s_Sg_frac07,i)
x2s%topo(g,7) = x2s_s%rAttr(index_x2s_Sg_topo07,i)
x2s%hflx(g,7) = x2s_s%rAttr(index_x2s_Fsgg_hflx07,i)
x2s%rofi(g,7) = x2s_s%rAttr(index_x2s_Fsgg_rofi07,i)
x2s%rofi(g,7) = x2s_s%rAttr(index_x2s_Fsgg_rofl07,i)
x2s%frac(g,8) = x2s_s%rAttr(index_x2s_Sg_frac08,i)
x2s%topo(g,8) = x2s_s%rAttr(index_x2s_Sg_topo08,i)
x2s%hflx(g,8) = x2s_s%rAttr(index_x2s_Fsgg_hflx08,i)
x2s%rofi(g,8) = x2s_s%rAttr(index_x2s_Fsgg_rofi08,i)
x2s%rofl(g,8) = x2s_s%rAttr(index_x2s_Fsgg_rofl08,i)
x2s%frac(g,9) = x2s_s%rAttr(index_x2s_Sg_frac09,i)
x2s%topo(g,9) = x2s_s%rAttr(index_x2s_Sg_topo09,i)
x2s%hflx(g,9) = x2s_s%rAttr(index_x2s_Fsgg_hflx09,i)
x2s%rofi(g,9) = x2s_s%rAttr(index_x2s_Fsgg_rofi09,i)
x2s%rofl(g,9) = x2s_s%rAttr(index_x2s_Fsgg_rofl09,i)
x2s%frac(g,10) = x2s_s%rAttr(index_x2s_Sg_frac10,i)
x2s%topo(g,10) = x2s_s%rAttr(index_x2s_Sg_topo10,i)
x2s%hflx(g,10) = x2s_s%rAttr(index_x2s_Fsgg_hflx10,i)
x2s%rofi(g,10) = x2s_s%rAttr(index_x2s_Fsgg_rofi10,i)
x2s%rofl(g,10) = x2s_s%rAttr(index_x2s_Fsgg_rofl10,i)
#endif
end do ! g
end subroutine sno_import_mct
!====================================================================================
end module lnd_comp_mct