module kind_defs_m

  implicit none

  integer, parameter :: dp=selected_real_kind(P=15) ! double precision

end module kind_defs_m

module element_defs_m

  use kind_defs_m

  implicit none

! encapsulated function pointers for use in coefficients

  type func_p
    procedure (dum_func), pointer, nopass :: p => null()
  end type func_p

  type coefficients_t

!   array of func procedure pointers 
    type(func_p), allocatable, dimension(:) :: func1 

  end type coefficients_t

contains

! dummy scalar function
 
  function dum_func ()
    real(dp) :: dum_func

    write(*,'(/a/)') 'Scalar function (func interface) has not been defined'
    dum_func = 0
    stop

  end function dum_func 


end module element_defs_m

module element_utils_m

  implicit none

contains

  subroutine evaluate_scalar_coefficient ( func )
    interface
      function func ()
        use kind_defs_m
        real(dp) :: func
      end function func
    end interface
  end subroutine evaluate_scalar_coefficient

end module element_utils_m

module convection_diffusion_elements_generic_m

  use kind_defs_m
  use element_defs_m
  use element_utils_m

  implicit none

contains

  subroutine scalar_dcdt_elem ( coefficients )

    type(coefficients_t), intent(in) :: coefficients

    call evaluate_scalar_coefficient ( func=coefficients%func1(3)%p )

  end subroutine scalar_dcdt_elem

end module convection_diffusion_elements_generic_m
