module filenames 23,3
!-----------------------------------------------------------------------
!
! BOP
!
! !MODULE: filenames
!
! DESCRIPTION
!
! Module and methods to handle filenames needed for the model. This
! includes input filenames, and most output filenames that the model
! uses. All filenames that the model uses will use methods or data
! constructed by this module. In some cases (such as the history module)
! other modules or routines will store the actual filenames used, but
! this module is used to determine the names.
!
!-----------------------------------------------------------------------
! $Id$
!-----------------------------------------------------------------------
use time_manager
, only: get_curr_date, get_prev_date, get_step_size
use shr_kind_mod
, only: shr_kind_cs, shr_kind_cl
use abortutils
, only: endrun
implicit none
!
! !PUBLIC MEMBER FUNCTIONS
!
public init_filepaths ! Initialize filepaths
public get_archivedir ! Get the specific archive directory name
public interpret_filename_spec ! Interpret a filename specifier
!
! !PUBLIC DATA MEMBERS:
!
! Note: Only make data needed for namelist public, everything else should be private.
!
! Input datasets
!
character(shr_kind_cl), public :: ncdata = 'ncdata' ! full pathname for initial dataset
character(shr_kind_cl), public :: bndtvs = 'bndtvs' ! full pathname for time-variant sst dataset
character(shr_kind_cl), public :: bndtvo = 'bndtvo' ! full pathname for time-variant ozone dataset
character(len=256), public :: bndtvaer = 'bndtvaer' ! full pathname for time-variant aerosol mass climatology dataset
character(len=256), public :: bndtvcarbonscale = 'bndtvcarbonscale' ! full pathname for time-variant population dataset
character(len=256), public :: bndtvvolc = 'bndtvvolc' ! full pathname for time-variant stratospheric volcanic aerosol masses
character(len=256), public :: aeroptics = 'aeroptics' ! full pathname for aerosol optical dataset
character(shr_kind_cl), public :: co_emis = 'co_emis' ! full pathname for time-variant carbon emission dataset
character(shr_kind_cl), public :: bndtvdms = 'bndtvdms' ! full pathname for time-variant DMS emission dataset
character(shr_kind_cl), public :: soil_erod = 'soil_erod' ! full pathname for time-variant soil erodibility dataset
character(shr_kind_cl), public :: bndtvoxid = 'bndtvoxid' ! full pathname for time-variant oxidant dataset
character(shr_kind_cl), public :: bndtvsox = 'bndtvsox' ! full pathname for time-variant SOx emission dataset
character(shr_kind_cl), public :: absems_data = 'absems_data' ! full pathname for time-invariant absorption dataset
character(shr_kind_cl), public :: bndtvg = 'bndtvg' ! full pathname for time-variant greenhouse gas loss rate
character(shr_kind_cl), public :: isccpdata = 'isccpdata' ! full pathname for ISCCP input data
character(shr_kind_cl), public :: bndtvsf6 = 'bndtvsf6' ! full pathname for time-variant sf6 tracer emission rate
!
! Filenames used for restart or branch
!
character(shr_kind_cl), public :: nrevsn = ' ' ! Dataset to branch from, in namelist
character(shr_kind_cl), public :: rest_pfile = ' ' ! File name for restart dataset
!
! Variables associated with archival (MSS) pathnames
!
character(shr_kind_cs), public :: caseid = ' ' ! Case identifier
character(len= 8), public :: mss_wpass = ' ' ! MSS write password
integer, public :: mss_irt = 365 ! Mass Store retention period for output files
logical, public :: brnch_retain_casename = .false.
!-----------------------------------------------------------------------
! EOP
!-----------------------------------------------------------------------
!
! Private data used for filenames
!
PRIVATE
character(shr_kind_cl), private :: archive_dir = ' ' ! Root archival directory
! (ie MSS directory)
integer, parameter :: nlen = shr_kind_cl ! String length
CONTAINS
!-----------------------------------------------------------------------
! BOP
!
! !ROUTINE: init_filepaths
!
! !DESCRIPTION: Initialize the filepaths.
!
!-----------------------------------------------------------------------
! !INTERFACE:
subroutine init_filepaths( archivedirname ) 1,9
!
! !Uses:
!
use shr_kind_mod
, only: r8 => shr_kind_r8
use shr_sys_mod
, only: shr_sys_getenv
use string_utils
, only: to_upper
!
! !PARAMETERS:
!
character(len=*), intent(in), optional :: archivedirname ! Archive directory name
!
! EOP
!
!-------------------------- Common blocks ------------------------------
! For nrefrq
#include <comctl.h>
!
! Local variables
!
character(len=80) :: logname ! user name
character(len=80) :: upcaselogname ! user name in upper-case
character(len=80) :: home_dir = ' ' ! Pathname for regeneration dataset nsrest=2
integer :: ind ! Index into directory name
integer :: rcode ! shr_sys_getenv return code
!
! Get the users home directory to write restart pointer file
!
call shr_sys_getenv
('HOME',home_dir,rcode)
if (rcode /= 0) then
call endrun
('INIT_FILEPATHS: Cannot find HOME environment variable')
end if
if (nrefrq == 1 .and. len_trim(rest_pfile) == 0 ) then
rest_pfile = trim(home_dir) //'/cam2.'// trim(caseid) //'.rpointer'
end if
!
! Set archive_dir if not initialized, and make sure has trailing "/"
!
if ( present(archivedirname) )then
archive_dir = archivedirname
end if
if ( len_trim(archive_dir) == 0 )then
logname = ' '
call shr_sys_getenv
('LOGNAME',logname,rcode)
if (rcode /= 0) then
call endrun
('INIT_FILEPATHS: Cannot find LOGNAME environment variable')
end if
upcaselogname = to_upper
(logname)
archive_dir = '/'//trim(upcaselogname)//'/csm/'//trim(caseid)//'/atm/'
end if
ind = len_trim(archive_dir)
if ( archive_dir(ind:ind) /= '/' )then
archive_dir = trim(archive_dir) // '/'
end if
if ( archive_dir(1:1) /= '/' )then
call endrun
('INIT_FILEPATHS: archive_dir must be an absolute directory name = '//archive_dir)
end if
end subroutine init_filepaths
!-----------------------------------------------------------------------
! BOP
!
! !ROUTINE: get_archivedir
!
! !DESCRIPTION: Return the archive directory for the specific type
! of file given.
!
!-----------------------------------------------------------------------
! !INTERFACE:
character(len=nlen) function get_archivedir( type ),1
!
! !PARAMETERS:
!
character(len=*), intent(in) :: type ! Type of filename to create (init, rest, or hist)
!
! EOP
!
if ( type /= 'hist' .and. type /= 'init' .and. type /= 'rest' )then
write(6,*) 'GET_ARCHIVEDIR: Invalid type: ', type
call endrun
end if
get_archivedir = trim(archive_dir) // trim(type) // '/'
end function get_archivedir
!-----------------------------------------------------------------------
! BOP
!
! !ROUTINE: interpret_filename_spec
!
! !DESCRIPTION: Create a filename from a filename specifyer. The
! filename specifyer includes codes for setting things such as the
! year, month, day, seconds in day, caseid, and tape number. This
! routine is private to filenames.F90
!
! Interpret filename specifyer string with:
!
! %c for case,
! %t for optional number argument sent into function
! %y for year
! %m for month
! %d for day
! %s for second
! %% for the "%" character
!
! If the filename specifyer has spaces " ", they will be trimmed out
! of the resulting filename.
!
!-----------------------------------------------------------------------
! !INTERFACE:
character(len=nlen) function interpret_filename_spec( filename_spec, number, prev ) 5,12
use dycore
, only: dycore_is
!
! !PARAMETERS:
!
character(len=*), intent(in) :: filename_spec ! Filename specifier to use
integer, intent(in), optional :: number ! Number to use for %t field
logical, intent(in), optional :: prev ! If should label with previous time-step
!
! EOP
!
integer :: dtime ! timestep size
integer :: year ! Simulation year
integer :: month ! Simulation month
integer :: day ! Simulation day
integer :: ncsec ! Seconds into current simulation day
character(len=nlen) :: string ! Temporary character string
character(len=nlen) :: format ! Format character string
integer :: i, n ! Loop variables
logical :: previous ! If should label with previous time-step
logical :: done
if ( len_trim(filename_spec) == 0 )then
call endrun
('INTERPRET_FILENAME_SPEC: filename specifier is empty')
end if
if ( index(trim(filename_spec)," ") /= 0 )then
call endrun
('INTERPRET_FILENAME_SPEC: filename specifier can not contain a space:'//trim(filename_spec))
end if
if ( .not. present(prev) ) then
previous = .false.
else
previous = prev
end if
if ( previous ) then
call get_prev_date
(year, month, day, ncsec)
else
dtime = get_step_size
()
call get_curr_date
(year, month, day, ncsec)
if(dycore_is ('SLD') ) then
i = 1
done = .false.
do while ( i <= len_trim(filename_spec) .and. .not. done)
if ( filename_spec(i:i+2) == ".i." )then
call get_curr_date
(year, month, day, ncsec,offset=dtime)
done = .true.
endif
i = i + 1
end do
end if
end if
!
! Go through each character in the filename specifyer and interpret if special string
!
i = 1
interpret_filename_spec = ''
do while ( i <= len_trim(filename_spec) )
!
! If following is an expansion string
!
if ( filename_spec(i:i) == "%" )then
i = i + 1
select case( filename_spec(i:i) )
case( 'c' ) ! caseid
string = trim(caseid)
case( 't' ) ! number
if ( .not. present(number) )then
write(6,*) 'INTERPRET_FILENAME_SPEC: number needed in filename_spec' &
, ', but not provided to subroutine'
write(6,*) 'filename_spec = ', filename_spec
call endrun
end if
if ( number > 999 ) then
format = '(i4.4)'
if ( number > 9999 ) then
write(6,*) 'INTERPRET_FILENAME_SPEC: number is too large: ', number
call endrun
end if
else if ( number > 99 ) then
format = '(i3.3)'
else if ( number > 9 ) then
format = '(i2.2)'
else
format = '(i1.1)'
end if
write(string,format) number
case( 'y' ) ! year
if ( year > 99999 ) then
format = '(i6.6)'
else if ( year > 9999 ) then
format = '(i5.5)'
else
format = '(i4.4)'
end if
write(string,format) year
case( 'm' ) ! month
write(string,'(i2.2)') month
case( 'd' ) ! day
write(string,'(i2.2)') day
case( 's' ) ! second
write(string,'(i5.5)') ncsec
case( '%' ) ! percent character
string = "%"
case default
call endrun
('INTERPRET_FILENAME_SPEC: Invalid expansion character: '//filename_spec(i:i))
end select
!
! Otherwise take normal text up to the next "%" character
!
else
n = index( filename_spec(i:), "%" )
if ( n == 0 ) n = len_trim( filename_spec(i:) ) + 1
if ( n == 0 ) exit
string = filename_spec(i:n+i-2)
i = n + i - 2
end if
if ( len_trim(interpret_filename_spec) == 0 )then
interpret_filename_spec = trim(string)
else
if ( (len_trim(interpret_filename_spec)+len_trim(string)) >= nlen )then
call endrun
('INTERPRET_FILENAME_SPEC: Resultant filename too long')
end if
interpret_filename_spec = trim(interpret_filename_spec) // trim(string)
end if
i = i + 1
end do
if ( len_trim(interpret_filename_spec) == 0 )then
call endrun
('INTERPRET_FILENAME_SPEC: Resulting filename is empty')
end if
end function interpret_filename_spec
end module filenames