!------------------------------------------------------------------- ! manages reading and interpolation of linoz data ! Created by: Francis Vitt !------------------------------------------------------------------- module linoz_data use shr_kind_mod, only : r8 => shr_kind_r8 use abortutils, only : endrun use spmd_utils, only : masterproc use tracer_data, only : trfld,trfile use cam_logfile, only : iulog implicit none type(trfld), pointer :: fields(:) type(trfile), save :: file private ! all unless made public save public :: fields public :: linoz_data_init public :: linoz_data_adv public :: init_linoz_data_restart public :: write_linoz_data_restart public :: read_linoz_data_restart public :: has_linoz_data public :: linoz_data_defaultopts public :: linoz_data_setopts logical :: has_linoz_data = .false. integer, parameter, public :: N_FLDS = 8 integer :: number_flds character(len=256) :: filename = '' character(len=256) :: filelist = '' character(len=256) :: datapath = '' character(len=32) :: datatype = 'CYCLICAL' logical :: rmv_file = .false. integer :: cycle_yr = 0 integer :: fixed_ymd = 0 integer :: fixed_tod = 0 character(len=16), dimension(N_FLDS), parameter :: fld_names = & ! data field names (/'o3_clim ','t_clim ','o3col_clim ','PmL_clim ', & 'dPmL_dO3 ','dPmL_dT ','dPmL_dO3col ','cariolle_pscs '/) character(len=16), dimension(N_FLDS), parameter :: fld_units = & ! data field names (/'vmr ','K ','Dobson Units ','mr/s ', & '/s ','mr/K ','mr/DU ','/s '/) integer :: index_map(N_FLDS) integer, public, parameter :: o3_clim_ndx = 1 integer, public, parameter :: t_clim_ndx = 2 integer, public, parameter :: o3col_clim_ndx = 3 integer, public, parameter :: PmL_clim_ndx = 4 integer, public, parameter :: dPmL_dO3_ndx = 5 integer, public, parameter :: dPmL_dT_ndx = 6 integer, public, parameter :: dPmL_dO3col_ndx = 7 integer, public, parameter :: cariolle_pscs_ndx = 8 contains !------------------------------------------------------------------- !------------------------------------------------------------------- subroutine linoz_data_init() use tracer_data, only : trcdata_init use cam_history, only : addfld, phys_decomp use ppgrid, only : pver use error_messages, only: handle_err use ppgrid, only: pcols, pver, begchunk, endchunk use physics_buffer, only : physics_buffer_desc implicit none integer :: ndx, istat, i if ( has_linoz_data ) then if ( masterproc ) then write(iulog,*) 'linoz_data_ini: linoz data :'//trim(filename) endif else return endif call trcdata_init( fld_names, filename, filelist, datapath, fields, file, & rmv_file, cycle_yr, fixed_ymd, fixed_tod, datatype) number_flds = 0 if (associated(fields)) number_flds = size( fields ) if( number_flds < 1 ) then if ( masterproc ) then write(iulog,*) 'linoz_data_init: There are no linoz data' write(iulog,*) ' ' endif return end if do i = 1,number_flds ndx = get_ndx( fields(i)%fldnam ) index_map(i) = ndx if (ndx < 1) then call endrun('linoz_data_init: '//trim(fields(i)%fldnam)//' is not one of the named linoz data fields ') endif call addfld(fld_names(i), fld_units(i), pver, 'I', 'linoz data', phys_decomp ) enddo end subroutine linoz_data_init !------------------------------------------------------------------- !------------------------------------------------------------------- subroutine linoz_data_setopts(& linoz_data_file_in, & linoz_data_filelist_in, & linoz_data_path_in, & linoz_data_type_in, & linoz_data_rmfile_in, & linoz_data_cycle_yr_in, & linoz_data_fixed_ymd_in, & linoz_data_fixed_tod_in & ) implicit none character(len=*), intent(in), optional :: linoz_data_file_in character(len=*), intent(in), optional :: linoz_data_filelist_in character(len=*), intent(in), optional :: linoz_data_path_in character(len=*), intent(in), optional :: linoz_data_type_in logical, intent(in), optional :: linoz_data_rmfile_in integer, intent(in), optional :: linoz_data_cycle_yr_in integer, intent(in), optional :: linoz_data_fixed_ymd_in integer, intent(in), optional :: linoz_data_fixed_tod_in if ( present(linoz_data_file_in) ) then filename = linoz_data_file_in endif if ( present(linoz_data_filelist_in) ) then filelist = linoz_data_filelist_in endif if ( present(linoz_data_path_in) ) then datapath = linoz_data_path_in endif if ( present(linoz_data_type_in) ) then datatype = linoz_data_type_in endif if ( present(linoz_data_rmfile_in) ) then rmv_file = linoz_data_rmfile_in endif if ( present(linoz_data_cycle_yr_in) ) then cycle_yr = linoz_data_cycle_yr_in endif if ( present(linoz_data_fixed_ymd_in) ) then fixed_ymd = linoz_data_fixed_ymd_in endif if ( present(linoz_data_fixed_tod_in) ) then fixed_tod = linoz_data_fixed_tod_in endif if (len_trim(filename) > 0 ) has_linoz_data = .true. endsubroutine linoz_data_setopts !------------------------------------------------------------------- !------------------------------------------------------------------- subroutine linoz_data_defaultopts( & linoz_data_file_out, & linoz_data_filelist_out, & linoz_data_path_out, & linoz_data_type_out, & linoz_data_rmfile_out, & linoz_data_cycle_yr_out, & linoz_data_fixed_ymd_out,& linoz_data_fixed_tod_out & ) implicit none character(len=*), intent(out), optional :: linoz_data_file_out character(len=*), intent(out), optional :: linoz_data_filelist_out character(len=*), intent(out), optional :: linoz_data_path_out character(len=*), intent(out), optional :: linoz_data_type_out logical, intent(out), optional :: linoz_data_rmfile_out integer, intent(out), optional :: linoz_data_cycle_yr_out integer, intent(out), optional :: linoz_data_fixed_ymd_out integer, intent(out), optional :: linoz_data_fixed_tod_out if ( present(linoz_data_file_out) ) then linoz_data_file_out = filename endif if ( present(linoz_data_filelist_out) ) then linoz_data_filelist_out = filelist endif if ( present(linoz_data_path_out) ) then linoz_data_path_out = datapath endif if ( present(linoz_data_type_out) ) then linoz_data_type_out = datatype endif if ( present(linoz_data_rmfile_out) ) then linoz_data_rmfile_out = rmv_file endif if ( present(linoz_data_cycle_yr_out) ) then linoz_data_cycle_yr_out = cycle_yr endif if ( present(linoz_data_fixed_ymd_out) ) then linoz_data_fixed_ymd_out = fixed_ymd endif if ( present(linoz_data_fixed_tod_out) ) then linoz_data_fixed_tod_out = fixed_tod endif endsubroutine linoz_data_defaultopts !------------------------------------------------------------------- !------------------------------------------------------------------- subroutine linoz_data_adv( pbuf2d, state ) use tracer_data, only : advance_trcdata use physics_types,only : physics_state use ppgrid, only : begchunk, endchunk use ppgrid, only : pcols, pver use string_utils, only : to_lower, GLC use cam_history, only : outfld use physconst, only : boltz ! J/K/molecule use physics_buffer, only : physics_buffer_desc implicit none type(physics_state), intent(in):: state(begchunk:endchunk) integer :: ind,c,ncol,i real(r8) :: to_mmr(pcols,pver) type(physics_buffer_desc), pointer :: pbuf2d(:,:) if( .not. has_linoz_data ) return call advance_trcdata( fields, file, state, pbuf2d ) ! set the tracer fields with the correct units do i = 1,number_flds ind = index_map(i) do c = begchunk,endchunk ncol = state(c)%ncol call outfld( fields(i)%fldnam, fields(i)%data(:ncol,:,c), ncol, state(c)%lchnk ) enddo enddo end subroutine linoz_data_adv !------------------------------------------------------------------- !------------------------------------------------------------------- subroutine init_linoz_data_restart( piofile ) use pio, only : file_desc_t use tracer_data, only : init_trc_restart implicit none type(file_desc_t),intent(inout) :: piofile ! pio File pointer call init_trc_restart( 'linoz_data', piofile, file ) end subroutine init_linoz_data_restart !------------------------------------------------------------------- subroutine write_linoz_data_restart( PioFile ) use tracer_data, only : write_trc_restart use pio, only : file_desc_t implicit none type(file_desc_T) :: piofile call write_trc_restart( piofile, file ) end subroutine write_linoz_data_restart !------------------------------------------------------------------- !------------------------------------------------------------------- subroutine read_linoz_data_restart( PioFile ) use tracer_data, only : read_trc_restart use pio, only : file_desc_t implicit none type(file_desc_T) :: piofile call read_trc_restart( 'linoz_data', piofile, file ) end subroutine read_linoz_data_restart !------------------------------------------------------------------- !------------------------------------------------------------------- integer function get_ndx( name ) implicit none character(len=*), intent(in) :: name integer :: i get_ndx = 0 do i = 1,N_FLDS if ( trim(name) == trim(fld_names(i)) ) then get_ndx = i return endif enddo end function get_ndx end module linoz_data