!===================================================
! DO NOT EDIT THIS FILE, it was generated using ./tools/genf90/genf90.pl
! Any changes you make to this file may be lost
!===================================================
module dynVarTimeUninterpMod

#include "shr_assert.h" 

  !---------------------------------------------------------------------------
  ! !DESCRIPTION:
  ! Contains a derived type and associated methods that extend the base class,
  ! dyn_var_type. The type defined here is for variables that should NOT be interpolated
  ! in time.  For variables of this type, the data will snap to their new value at the
  ! beginning of each year, and then stay fixed throughout the year. Before the start of
  ! the time series, the data are fixed at their value from the first year in the file;
  ! after the end of the time series, the data are fixed at their value from the last year
  ! in the file.
  !
  ! !USES:
  use shr_kind_mod   , only : r8 => shr_kind_r8
  use dynVarMod      , only : dyn_var_type

  implicit none
  private
  save

  ! !PUBLIC TYPES:
  public :: dyn_var_time_uninterp_type

  type, extends(dyn_var_type) :: dyn_var_time_uninterp_type
     private
     ! Note that data are stored as 1-d, then converted to the appropriate dimensionality
     ! as needed
     real(r8), allocatable :: data_at_tlower(:) ! data at time time_index_lower
     integer :: time_index_lower                       ! current time_index_lower corresponding to the data
# 32 "src/dyn_subgrid/dynVarTimeUninterpMod.F90.in"
   contains
     generic :: get_current_data => &      ! Get the current value of the data
          get_current_data_1d, get_current_data_2d
     procedure :: get_current_data_1d  ! Get the current value of the data, for a 1-d variable
     procedure :: get_current_data_2d  ! Get the current value of the data, for a 2-d variable
     procedure :: read_data_if_needed  ! Read the next time slice of data, if necessary
  end type dyn_var_time_uninterp_type

# 40 "src/dyn_subgrid/dynVarTimeUninterpMod.F90.in"
  interface dyn_var_time_uninterp_type
     module procedure constructor  ! initialize a new dyn_var_time_uninterp_type object
  end interface dyn_var_time_uninterp_type

# 44 "src/dyn_subgrid/dynVarTimeUninterpMod.F90.in"
contains
  
  ! ======================================================================
  ! Constructors
  ! ======================================================================

  !-----------------------------------------------------------------------
# 51 "src/dyn_subgrid/dynVarTimeUninterpMod.F90.in"
  type(dyn_var_time_uninterp_type) function constructor( &
       dyn_file, varname, dim1name, conversion_factor, &
       do_check_sums_equal_1, data_shape, allow_nodata)
    !
    ! !DESCRIPTION:
    ! Creates an object of type dyn_var_time_uninterp_type. This also reads the first
    ! set of data.
    !
    ! Assumes that dyn_file has already been initialized.
    !
    ! !USES:
    use dynFileMod     , only : dyn_file_type
    use dynTimeInfoMod , only : time_info_type
    !
    ! !ARGUMENTS:
    type(dyn_file_type), target, intent(in) :: dyn_file ! file containing this variable
    character(len=*), intent(in) :: varname             ! variable name on file
    character(len=*), intent(in) :: dim1name            ! dim1name on file
    real(r8), intent(in) :: conversion_factor           ! data are DIVIDED by conversion_factor immediately after reading them
    logical, optional, intent(in) :: allow_nodata       ! Flag to allow there to be no data if the field doesn't exist on the dataset

     ! Only relevant for 2-d variables: should we check to make sure that all sums equal 1?
    logical, intent(in) :: do_check_sums_equal_1
    
    ! Shape of data; max number of dimensions is given by dyn_var_max_dims in dynVarMod.
    ! First dimension is the spatial dimension.
    integer, intent(in) :: data_shape(:)

    logical :: lallow_nodata   ! Local version of allow_nodata which is by default FALSE
    !-----------------------------------------------------------------------
    
    lallow_nodata = .false.
    if ( present(allow_nodata) )then
       lallow_nodata = allow_nodata
    end if
    ! Set metadata common to all dyn_var_type objects
    call constructor%set_metadata( &
         dyn_file=dyn_file, &
         varname=varname, &
         dim1name=dim1name, &
         conversion_factor=conversion_factor, &
         do_check_sums_equal_1=do_check_sums_equal_1, &
         data_shape=data_shape, allow_nodata=lallow_nodata)

    ! Allocate space for data
    allocate(constructor%data_at_tlower(product(data_shape)))

    ! Read first set of data
    constructor%time_index_lower = dyn_file%time_info%get_time_index_lower()
    call constructor%read_variable(constructor%time_index_lower, constructor%data_at_tlower)
# 101 "src/dyn_subgrid/dynVarTimeUninterpMod.F90.in"
  end function constructor
    
  ! ======================================================================
  ! Public methods
  ! ======================================================================

  ! The following specific procedures are NOT actually public, but they can be accessed
  ! via the generic type-bound procedure, get_current_data

  ! DIMS 1,2
  !-----------------------------------------------------------------------
# 112 "src/dyn_subgrid/dynVarTimeUninterpMod.F90.in"
  subroutine get_current_data_1d(this, cur_data)
    !
    ! !DESCRIPTION:
    ! Get the current value of the data, in cur_data. cur_data should have the same
    ! dimensionality as the underlying data, as given by the data_shape argument that was
    ! passed to the constructor.
    ! 
    ! If necessary, new data are read from the file.
    !
    ! Should be called once per time step, AFTER calling set_current_year on the
    ! underlying dyn_file variable
    !
    ! !ARGUMENTS:
    class(dyn_var_time_uninterp_type) , intent(inout) :: this             ! this object
    real(r8)                          , intent(out)   :: cur_data(:) ! current value of data
    !
    ! !LOCAL VARIABLES:
    integer :: ndims   ! ndims of data in 'this'
    
    character(len=*), parameter :: subname = 'get_current_data_1d'
    !-----------------------------------------------------------------------
    
    ! Do some error checking
    ndims = size(this%get_data_shape())
    SHR_ASSERT(1 == ndims, subname//' ERROR: # dims of output argument must match ndims')
    SHR_ASSERT_ALL((shape(cur_data) == this%get_data_shape()), subname//' ERROR: shape of cur_data must match shape of data')

    ! Get current data
    call this%read_data_if_needed()
    cur_data = reshape(this%data_at_tlower, shape(cur_data))

# 143 "src/dyn_subgrid/dynVarTimeUninterpMod.F90.in"
  end subroutine get_current_data_1d
  ! DIMS 1,2
  !-----------------------------------------------------------------------
# 112 "src/dyn_subgrid/dynVarTimeUninterpMod.F90.in"
  subroutine get_current_data_2d(this, cur_data)
    !
    ! !DESCRIPTION:
    ! Get the current value of the data, in cur_data. cur_data should have the same
    ! dimensionality as the underlying data, as given by the data_shape argument that was
    ! passed to the constructor.
    ! 
    ! If necessary, new data are read from the file.
    !
    ! Should be called once per time step, AFTER calling set_current_year on the
    ! underlying dyn_file variable
    !
    ! !ARGUMENTS:
    class(dyn_var_time_uninterp_type) , intent(inout) :: this             ! this object
    real(r8)                          , intent(out)   :: cur_data(:,:) ! current value of data
    !
    ! !LOCAL VARIABLES:
    integer :: ndims   ! ndims of data in 'this'
    
    character(len=*), parameter :: subname = 'get_current_data_2d'
    !-----------------------------------------------------------------------
    
    ! Do some error checking
    ndims = size(this%get_data_shape())
    SHR_ASSERT(2 == ndims, subname//' ERROR: # dims of output argument must match ndims')
    SHR_ASSERT_ALL((shape(cur_data) == this%get_data_shape()), subname//' ERROR: shape of cur_data must match shape of data')

    ! Get current data
    call this%read_data_if_needed()
    cur_data = reshape(this%data_at_tlower, shape(cur_data))

# 143 "src/dyn_subgrid/dynVarTimeUninterpMod.F90.in"
  end subroutine get_current_data_2d
  
  ! ======================================================================
  ! Private methods
  ! ======================================================================

  !-----------------------------------------------------------------------
# 150 "src/dyn_subgrid/dynVarTimeUninterpMod.F90.in"
  subroutine read_data_if_needed(this)
    !
    ! !DESCRIPTION:
    ! Determine if new data need to be read from the file; if so, read them.
    ! 
    ! We need to read new data if the current time on dyn_file disagrees with the time
    ! for which we currently have stored data.
    !
    ! !USES:
    use dynFileMod     , only : dyn_file_type
    use dynTimeInfoMod , only : time_info_type
    !
    ! !ARGUMENTS:
    class(dyn_var_time_uninterp_type), intent(inout) :: this   ! this object
    !
    ! !LOCAL VARIABLES:
    type(dyn_file_type), pointer :: dyn_file ! the dyn_file of this object
    integer :: time_index_lower_cur                       ! current value of time_index_lower on dyn_file
    
    character(len=*), parameter :: subname = 'read_data_if_needed'
    !-----------------------------------------------------------------------

    dyn_file => this%get_dyn_file()
    time_index_lower_cur = dyn_file%time_info%get_time_index_lower()
    if (time_index_lower_cur /= this%time_index_lower) then
       call this%read_variable(time_index_lower_cur, this%data_at_tlower)
       this%time_index_lower = time_index_lower_cur
    end if
# 178 "src/dyn_subgrid/dynVarTimeUninterpMod.F90.in"
  end subroutine read_data_if_needed


end module dynVarTimeUninterpMod
