285 lines
9.9 KiB
Fortran
285 lines
9.9 KiB
Fortran
module ndepStreamMod
|
|
|
|
!-----------------------------------------------------------------------
|
|
!BOP
|
|
!
|
|
! !MODULE: ndepStreamMod
|
|
!
|
|
! !DESCRIPTION:
|
|
! Contains methods for reading in nitrogen deposition data file
|
|
! Also includes functions for dynamic ndep file handling and
|
|
! interpolation.
|
|
!
|
|
! !USES
|
|
use shr_kind_mod, only: r8 => shr_kind_r8, CL => shr_kind_cl
|
|
use shr_strdata_mod
|
|
use shr_stream_mod
|
|
use shr_string_mod
|
|
use shr_sys_mod
|
|
use shr_mct_mod
|
|
use mct_mod
|
|
|
|
use spmdMod , only: mpicom, masterproc, comp_id, iam
|
|
use clm_varctl , only: iulog
|
|
use controlMod , only: NLFilename
|
|
use abortutils , only: endrun
|
|
use fileutils , only: getavu, relavu
|
|
use decompMod , only: get_proc_bounds, ldecomp, gsmap_lnd_gdc2glo
|
|
use domainMod , only: ldomain
|
|
|
|
! !PUBLIC TYPES:
|
|
implicit none
|
|
private
|
|
save
|
|
|
|
! !PUBLIC MEMBER FUNCTIONS:
|
|
public :: ndep_init ! position datasets for dynamic ndep
|
|
public :: ndep_interp ! interpolates between two years of ndep file data
|
|
public :: clm_domain_mct ! Sets up MCT domain for this resolution
|
|
!
|
|
!EOP
|
|
|
|
! ! PRIVATE TYPES
|
|
|
|
type(shr_strdata_type) :: sdat ! input data stream
|
|
integer :: stream_year_first_ndep ! first year in stream to use
|
|
integer :: stream_year_last_ndep ! last year in stream to use
|
|
integer :: model_year_align_ndep ! align stream_year_firstndep with
|
|
|
|
!=======================================================================
|
|
contains
|
|
!=======================================================================
|
|
|
|
subroutine ndep_init( )
|
|
|
|
!-----------------------------------------------------------------------
|
|
! Initialize data stream information.
|
|
!-----------------------------------------------------------------------
|
|
! Uses:
|
|
use clm_varctl , only : inst_name
|
|
use clm_time_manager , only : get_calendar
|
|
use ncdio_pio , only : pio_subsystem
|
|
use shr_pio_mod , only : shr_pio_getiotype
|
|
use shr_nl_mod , only : shr_nl_find_group_name
|
|
! arguments
|
|
implicit none
|
|
|
|
! local variables
|
|
integer :: nu_nml ! unit for namelist file
|
|
integer :: nml_error ! namelist i/o error flag
|
|
type(mct_ggrid) :: dom_clm ! domain information
|
|
character(len=CL) :: stream_fldFileName_ndep
|
|
character(len=CL) :: ndepmapalgo = 'bilinear'
|
|
character(*), parameter :: shr_strdata_unset = 'NOT_SET'
|
|
character(*), parameter :: subName = "('ndepdyn_init')"
|
|
character(*), parameter :: F00 = "('(ndepdyn_init) ',4a)"
|
|
!-----------------------------------------------------------------------
|
|
|
|
namelist /ndepdyn_nml/ &
|
|
stream_year_first_ndep, &
|
|
stream_year_last_ndep, &
|
|
model_year_align_ndep, &
|
|
ndepmapalgo, &
|
|
stream_fldFileName_ndep
|
|
|
|
! Default values for namelist
|
|
stream_year_first_ndep = 1 ! first year in stream to use
|
|
stream_year_last_ndep = 1 ! last year in stream to use
|
|
model_year_align_ndep = 1 ! align stream_year_first_ndep with this model year
|
|
stream_fldFileName_ndep = ' '
|
|
|
|
! Read ndepdyn_nml namelist
|
|
if (masterproc) then
|
|
nu_nml = getavu()
|
|
open( nu_nml, file=trim(NLFilename), status='old', iostat=nml_error )
|
|
call shr_nl_find_group_name(nu_nml, 'ndepdyn_nml', status=nml_error)
|
|
if (nml_error == 0) then
|
|
read(nu_nml, nml=ndepdyn_nml,iostat=nml_error)
|
|
if (nml_error /= 0) then
|
|
call endrun(subname // ':: ERROR reading ndepdyn_nml namelist')
|
|
end if
|
|
end if
|
|
close(nu_nml)
|
|
call relavu( nu_nml )
|
|
endif
|
|
|
|
call shr_mpi_bcast(stream_year_first_ndep, mpicom)
|
|
call shr_mpi_bcast(stream_year_last_ndep, mpicom)
|
|
call shr_mpi_bcast(model_year_align_ndep, mpicom)
|
|
call shr_mpi_bcast(stream_fldFileName_ndep, mpicom)
|
|
|
|
if (masterproc) then
|
|
write(iulog,*) ' '
|
|
write(iulog,*) 'ndepdyn stream settings:'
|
|
write(iulog,*) ' stream_year_first_ndep = ',stream_year_first_ndep
|
|
write(iulog,*) ' stream_year_last_ndep = ',stream_year_last_ndep
|
|
write(iulog,*) ' model_year_align_ndep = ',model_year_align_ndep
|
|
write(iulog,*) ' stream_fldFileName_ndep = ',stream_fldFileName_ndep
|
|
write(iulog,*) ' '
|
|
endif
|
|
|
|
call clm_domain_mct (dom_clm)
|
|
|
|
call shr_strdata_create(sdat,name="clmndep", &
|
|
pio_subsystem=pio_subsystem, &
|
|
pio_iotype=shr_pio_getiotype(inst_name), &
|
|
mpicom=mpicom, compid=comp_id, &
|
|
gsmap=gsmap_lnd_gdc2glo, ggrid=dom_clm, &
|
|
nxg=ldomain%ni, nyg=ldomain%nj, &
|
|
yearFirst=stream_year_first_ndep, &
|
|
yearLast=stream_year_last_ndep, &
|
|
yearAlign=model_year_align_ndep, &
|
|
offset=0, &
|
|
domFilePath='', &
|
|
domFileName=trim(stream_fldFileName_ndep), &
|
|
domTvarName='time', &
|
|
domXvarName='lon' , &
|
|
domYvarName='lat' , &
|
|
domAreaName='area', &
|
|
domMaskName='mask', &
|
|
filePath='', &
|
|
filename=(/trim(stream_fldFileName_ndep)/),&
|
|
fldListFile='NDEP_year', &
|
|
fldListModel='NDEP_year', &
|
|
fillalgo='none', &
|
|
mapalgo=ndepmapalgo, &
|
|
calendar=get_calendar(), &
|
|
taxmode='extend' )
|
|
|
|
if (masterproc) then
|
|
call shr_strdata_print(sdat,'CLMNDEP data')
|
|
endif
|
|
|
|
end subroutine ndep_init
|
|
|
|
!================================================================
|
|
|
|
subroutine ndep_interp( )
|
|
|
|
!-----------------------------------------------------------------------
|
|
use decompMod , only : get_proc_bounds
|
|
use clm_time_manager, only : get_curr_date, get_days_per_year
|
|
use clm_varcon , only : secspday
|
|
use clm_atmlnd , only : clm_a2l
|
|
|
|
! Local variables
|
|
implicit none
|
|
integer :: g, ig, begg, endg
|
|
integer :: year ! year (0, ...) for nstep+1
|
|
integer :: mon ! month (1, ..., 12) for nstep+1
|
|
integer :: day ! day of month (1, ..., 31) for nstep+1
|
|
integer :: sec ! seconds into current date for nstep+1
|
|
integer :: mcdate ! Current model date (yyyymmdd)
|
|
integer :: dayspyr ! days per year
|
|
!-----------------------------------------------------------------------
|
|
|
|
call get_curr_date(year, mon, day, sec)
|
|
mcdate = year*10000 + mon*100 + day
|
|
|
|
call shr_strdata_advance(sdat, mcdate, sec, mpicom, 'ndepdyn')
|
|
|
|
call get_proc_bounds(begg, endg)
|
|
ig = 0
|
|
dayspyr = get_days_per_year( )
|
|
do g = begg,endg
|
|
ig = ig+1
|
|
clm_a2l%forc_ndep(g) = sdat%avs(1)%rAttr(1,ig) / (secspday * dayspyr)
|
|
end do
|
|
|
|
end subroutine ndep_interp
|
|
|
|
!==============================================================================
|
|
|
|
subroutine clm_domain_mct( dom_clm )
|
|
|
|
!-------------------------------------------------------------------
|
|
! Set domain data type for internal clm grid
|
|
use clm_varcon , only : re
|
|
use domainMod , only : ldomain
|
|
use seq_flds_mod
|
|
implicit none
|
|
!
|
|
! arguments
|
|
type(mct_ggrid), intent(out) :: dom_clm ! Output domain information for land model
|
|
!
|
|
! local variables
|
|
integer :: g,i,j ! index
|
|
integer :: begg, endg ! beginning and ending gridcell indices
|
|
integer :: lsize ! land model domain data size
|
|
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
|
|
!
|
|
lsize = mct_gsMap_lsize(gsmap_lnd_gdc2glo, mpicom)
|
|
call mct_gGrid_init( GGrid=dom_clm, 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_lnd_gdc2glo, iam, idata)
|
|
call mct_gGrid_importIAttr(dom_clm,'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_clm,"lat" ,data,lsize)
|
|
call mct_gGrid_importRAttr(dom_clm,"lon" ,data,lsize)
|
|
call mct_gGrid_importRAttr(dom_clm,"area" ,data,lsize)
|
|
call mct_gGrid_importRAttr(dom_clm,"aream",data,lsize)
|
|
data(:) = 0.0_R8
|
|
call mct_gGrid_importRAttr(dom_clm,"mask" ,data,lsize)
|
|
!
|
|
! Determine bounds
|
|
!
|
|
call get_proc_bounds(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) = ldomain%lonc(g)
|
|
end do
|
|
call mct_gGrid_importRattr(dom_clm,"lon",data,lsize)
|
|
|
|
do g = begg,endg
|
|
i = 1 + (g - begg)
|
|
data(i) = ldomain%latc(g)
|
|
end do
|
|
call mct_gGrid_importRattr(dom_clm,"lat",data,lsize)
|
|
|
|
do g = begg,endg
|
|
i = 1 + (g - begg)
|
|
data(i) = ldomain%area(g)/(re*re)
|
|
end do
|
|
call mct_gGrid_importRattr(dom_clm,"area",data,lsize)
|
|
|
|
do g = begg,endg
|
|
i = 1 + (g - begg)
|
|
data(i) = real(ldomain%mask(g), r8)
|
|
end do
|
|
call mct_gGrid_importRattr(dom_clm,"mask",data,lsize)
|
|
|
|
do g = begg,endg
|
|
i = 1 + (g - begg)
|
|
data(i) = real(ldomain%frac(g), r8)
|
|
end do
|
|
call mct_gGrid_importRattr(dom_clm,"frac",data,lsize)
|
|
|
|
deallocate(data)
|
|
deallocate(idata)
|
|
|
|
end subroutine clm_domain_mct
|
|
|
|
end module ndepStreamMod
|
|
|