FrequencyAspect.F90 Source File


This file depends on

sourcefile~~frequencyaspect.f90~~EfferentGraph sourcefile~frequencyaspect.f90 FrequencyAspect.F90 sourcefile~accumulatoractioninterface.f90 AccumulatorActionInterface.F90 sourcefile~frequencyaspect.f90->sourcefile~accumulatoractioninterface.f90 sourcefile~extensionaction.f90 ExtensionAction.F90 sourcefile~frequencyaspect.f90->sourcefile~extensionaction.f90 sourcefile~stateitemaspect.f90 StateItemAspect.F90 sourcefile~frequencyaspect.f90->sourcefile~stateitemaspect.f90 sourcefile~accumulatoractioninterface.f90->sourcefile~extensionaction.f90 sourcefile~accumulatoraction.f90 AccumulatorAction.F90 sourcefile~accumulatoractioninterface.f90->sourcefile~accumulatoraction.f90 sourcefile~errorhandling.f90 ErrorHandling.F90 sourcefile~accumulatoractioninterface.f90->sourcefile~errorhandling.f90 sourcefile~keywordenforcer.f90 KeywordEnforcer.F90 sourcefile~accumulatoractioninterface.f90->sourcefile~keywordenforcer.f90 sourcefile~maxaction.f90 MaxAction.F90 sourcefile~accumulatoractioninterface.f90->sourcefile~maxaction.f90 sourcefile~meanaction.f90 MeanAction.F90 sourcefile~accumulatoractioninterface.f90->sourcefile~meanaction.f90 sourcefile~minaction.f90 MinAction.F90 sourcefile~accumulatoractioninterface.f90->sourcefile~minaction.f90 sourcefile~nullaction.f90 NullAction.F90 sourcefile~accumulatoractioninterface.f90->sourcefile~nullaction.f90 sourcefile~extensionaction.f90->sourcefile~errorhandling.f90 sourcefile~stateitemaspect.f90->sourcefile~errorhandling.f90 sourcefile~accumulatoraction.f90->sourcefile~extensionaction.f90 sourcefile~fieldpointerutilities.f90 FieldPointerUtilities.F90 sourcefile~accumulatoraction.f90->sourcefile~fieldpointerutilities.f90 sourcefile~fieldutilities.f90 FieldUtilities.F90 sourcefile~accumulatoraction.f90->sourcefile~fieldutilities.f90 sourcefile~internalconstants.f90 InternalConstants.F90 sourcefile~accumulatoraction.f90->sourcefile~internalconstants.f90 sourcefile~mapl_exceptionhandling.f90 MAPL_ExceptionHandling.F90 sourcefile~accumulatoraction.f90->sourcefile~mapl_exceptionhandling.f90 sourcefile~mapl_throw.f90 MAPL_Throw.F90 sourcefile~errorhandling.f90->sourcefile~mapl_throw.f90 sourcefile~maxaction.f90->sourcefile~accumulatoraction.f90 sourcefile~maxaction.f90->sourcefile~fieldpointerutilities.f90 sourcefile~maxaction.f90->sourcefile~internalconstants.f90 sourcefile~maxaction.f90->sourcefile~mapl_exceptionhandling.f90 sourcefile~meanaction.f90->sourcefile~accumulatoraction.f90 sourcefile~fieldcreate.f90 FieldCreate.F90 sourcefile~meanaction.f90->sourcefile~fieldcreate.f90 sourcefile~fieldget.f90 FieldGet.F90 sourcefile~meanaction.f90->sourcefile~fieldget.f90 sourcefile~meanaction.f90->sourcefile~fieldpointerutilities.f90 sourcefile~meanaction.f90->sourcefile~fieldutilities.f90 sourcefile~meanaction.f90->sourcefile~internalconstants.f90 sourcefile~meanaction.f90->sourcefile~mapl_exceptionhandling.f90 sourcefile~minaction.f90->sourcefile~accumulatoraction.f90 sourcefile~minaction.f90->sourcefile~fieldpointerutilities.f90 sourcefile~minaction.f90->sourcefile~internalconstants.f90 sourcefile~minaction.f90->sourcefile~mapl_exceptionhandling.f90 sourcefile~nullaction.f90->sourcefile~extensionaction.f90 sourcefile~nullaction.f90->sourcefile~errorhandling.f90 sourcefile~fieldcreate.f90->sourcefile~errorhandling.f90 sourcefile~fieldcreate.f90->sourcefile~keywordenforcer.f90 sourcefile~fieldinfo.f90 FieldInfo.F90 sourcefile~fieldcreate.f90->sourcefile~fieldinfo.f90 sourcefile~lu_bound.f90 LU_Bound.F90 sourcefile~fieldcreate.f90->sourcefile~lu_bound.f90 sourcefile~ungriddeddims.f90 UngriddedDims.F90 sourcefile~fieldcreate.f90->sourcefile~ungriddeddims.f90 sourcefile~verticalstaggerloc.f90 VerticalStaggerLoc.F90 sourcefile~fieldcreate.f90->sourcefile~verticalstaggerloc.f90 sourcefile~fieldget.f90->sourcefile~errorhandling.f90 sourcefile~fieldget.f90->sourcefile~keywordenforcer.f90 sourcefile~fieldget.f90->sourcefile~fieldinfo.f90 sourcefile~fieldget.f90->sourcefile~ungriddeddims.f90 sourcefile~fieldget.f90->sourcefile~verticalstaggerloc.f90 sourcefile~fieldpointerutilities.f90->sourcefile~mapl_exceptionhandling.f90 sourcefile~fieldutilities.f90->sourcefile~errorhandling.f90 sourcefile~fieldutilities.f90->sourcefile~keywordenforcer.f90 sourcefile~fieldutilities.f90->sourcefile~fieldpointerutilities.f90 sourcefile~fieldutilities.f90->sourcefile~fieldinfo.f90 sourcefile~infoutilities.f90 InfoUtilities.F90 sourcefile~fieldutilities.f90->sourcefile~infoutilities.f90 sourcefile~fieldutilities.f90->sourcefile~lu_bound.f90 sourcefile~fieldutilities.f90->sourcefile~ungriddeddims.f90 sourcefile~mapl_exceptionhandling.f90->sourcefile~errorhandling.f90 sourcefile~mapl_exceptionhandling.f90->sourcefile~mapl_throw.f90

Files dependent on this one

sourcefile~~frequencyaspect.f90~~AfferentGraph sourcefile~frequencyaspect.f90 FrequencyAspect.F90 sourcefile~aspectcollection.f90 AspectCollection.F90 sourcefile~aspectcollection.f90->sourcefile~frequencyaspect.f90 sourcefile~fieldspec.f90 FieldSpec.F90 sourcefile~fieldspec.f90->sourcefile~frequencyaspect.f90 sourcefile~fieldspec.f90->sourcefile~aspectcollection.f90 sourcefile~variablespec.f90 VariableSpec.F90 sourcefile~fieldspec.f90->sourcefile~variablespec.f90 sourcefile~test_fieldspec.pf Test_FieldSpec.pf sourcefile~test_fieldspec.pf->sourcefile~frequencyaspect.f90 sourcefile~test_fieldspec.pf->sourcefile~aspectcollection.f90 sourcefile~test_fieldspec.pf->sourcefile~fieldspec.f90 sourcefile~variablespec.f90->sourcefile~frequencyaspect.f90 sourcefile~variablespec.f90->sourcefile~aspectcollection.f90 sourcefile~bracketspec.f90 BracketSpec.F90 sourcefile~bracketspec.f90->sourcefile~fieldspec.f90 sourcefile~componentspec.f90 ComponentSpec.F90 sourcefile~componentspec.f90->sourcefile~variablespec.f90 sourcefile~componentspecparser.f90 ComponentSpecParser.F90 sourcefile~componentspecparser.f90->sourcefile~variablespec.f90 sourcefile~historycollectiongridcomp_private.f90 HistoryCollectionGridComp_private.F90 sourcefile~historycollectiongridcomp_private.f90->sourcefile~variablespec.f90 sourcefile~initialize_advertise.f90 initialize_advertise.F90 sourcefile~initialize_advertise.f90->sourcefile~variablespec.f90 sourcefile~make_itemspec.f90 make_itemSpec.F90 sourcefile~make_itemspec.f90->sourcefile~fieldspec.f90 sourcefile~make_itemspec.f90->sourcefile~variablespec.f90 sourcefile~mapl_generic.f90~2 MAPL_Generic.F90 sourcefile~mapl_generic.f90~2->sourcefile~variablespec.f90 sourcefile~mockitemspec.f90 MockItemSpec.F90 sourcefile~mockitemspec.f90->sourcefile~aspectcollection.f90 sourcefile~mockitemspec.f90->sourcefile~variablespec.f90 sourcefile~modelverticalgrid.f90 ModelVerticalGrid.F90 sourcefile~modelverticalgrid.f90->sourcefile~fieldspec.f90 sourcefile~servicespec.f90 ServiceSpec.F90 sourcefile~servicespec.f90->sourcefile~variablespec.f90 sourcefile~stateitemspec.f90 StateItemSpec.F90 sourcefile~stateitemspec.f90->sourcefile~aspectcollection.f90 sourcefile~statespec.f90 StateSpec.F90 sourcefile~statespec.f90->sourcefile~variablespec.f90 sourcefile~test_addfieldspec.pf Test_AddFieldSpec.pf sourcefile~test_addfieldspec.pf->sourcefile~fieldspec.f90 sourcefile~test_bracketspec.pf Test_BracketSpec.pf sourcefile~test_bracketspec.pf->sourcefile~fieldspec.f90 sourcefile~test_modelverticalgrid.pf Test_ModelVerticalGrid.pf sourcefile~test_modelverticalgrid.pf->sourcefile~variablespec.f90 sourcefile~variablespecvector.f90 VariableSpecVector.F90 sourcefile~variablespecvector.f90->sourcefile~variablespec.f90 sourcefile~wildcardspec.f90 WildcardSpec.F90 sourcefile~wildcardspec.f90->sourcefile~aspectcollection.f90

Source Code

#include "MAPL_Generic.h"
#include "unused_dummy.H"
module mapl3g_FrequencyAspect
   use mapl3g_StateItemAspect
   use mapl3g_AccumulatorActionInterface
   use esmf
   implicit none
   private

   public :: FrequencyAspect

   type, extends(StateItemAspect) :: FrequencyAspect
      private
      type(ESMF_TimeInterval) :: timestep_
      character(len=:), allocatable :: accumulation_type_
   contains
      ! These are implementations of extended derived type.
      procedure :: matches
      procedure :: supports_conversion_general
      procedure :: supports_conversion_specific
      procedure :: make_action
      ! These are specific to FrequencyAspect.
      procedure :: get_timestep
      procedure :: set_timestep
      procedure :: get_accumulation_type
      procedure :: set_accumulation_type
      procedure, private :: zero_timestep
   end type FrequencyAspect

   interface FrequencyAspect
      module procedure :: construct_frequency_aspect
   end interface FrequencyAspect

   interface operator(.divides.)
      module procedure :: aspect_divides
   end interface operator(.divides.)

   ! This value should not be accessed directly. Use get_zero() instead.
   ! There is no constructor for ESMF_TimeInterval, so the value cannot be initialized
   ! at construction. The get_zero() function initializes the value the first time
   ! and returns a pointer to the value.
   type(ESMF_TimeInterval), target :: ZERO_TI

contains

   function construct_frequency_aspect(timestep, accumulation_type) result(aspect)
      type(FrequencyAspect) :: aspect
      type(ESMF_TimeInterval), optional, intent(in) :: timestep
      character(len=*), optional, intent(in) :: accumulation_type

      call aspect%set_mirror(.FALSE.)
      call aspect%set_time_dependent(.FALSE.)
      call aspect%set_accumulation_type(INSTANTANEOUS)
      call aspect%zero_timestep()
      if(present(timestep)) aspect%timestep_ = timestep
      if(present(accumulation_type)) aspect%accumulation_type_ = accumulation_type
      
   end function construct_frequency_aspect

   function get_timestep(this) result(ts)
      type(ESMF_TimeInterval) :: ts
      class(FrequencyAspect), intent(in) :: this

      ts = this%timestep_

   end function get_timestep

   subroutine set_timestep(this, timestep)
      class(FrequencyAspect), intent(inout) :: this
      type(ESMF_TimeInterval), intent(in) :: timestep

      this%timestep_ = timestep

   end subroutine set_timestep

   subroutine zero_timestep(this)
      class(FrequencyAspect), intent(inout) :: this

      call ESMF_TimeIntervalSet(this%timestep_, ns=0)

   end subroutine zero_timestep

   function get_accumulation_type(this) result(at)
      character(len=:), allocatable :: at
      class(FrequencyAspect), intent(in) :: this

      at = ''
      if(allocated(this%accumulation_type_)) at = this%accumulation_type_

   end function get_accumulation_type

   subroutine set_accumulation_type(this, accumulation_type)
      class(FrequencyAspect), intent(inout) :: this
      character(len=*), intent(in) :: accumulation_type

      if(accumulation_type == INSTANTANEOUS .or. accumulation_type_is_valid(accumulation_type)) then
         this%accumulation_type_ = accumulation_type
      end if

   end subroutine set_accumulation_type

   logical function matches(src, dst) result(does_match)
      class(FrequencyAspect), intent(in) :: src
      class(StateItemAspect), intent(in) :: dst
      type(ESMF_TimeInterval) :: src_timestep, dst_timestep
      type(ESMF_TimeInterval), pointer :: zero

      does_match = .TRUE.
      zero => get_zero()
      src_timestep = src%get_timestep()
      if(src_timestep == zero) return
      select type(dst)
      class is (FrequencyAspect)
         dst_timestep = dst%get_timestep()
         if(dst_timestep == zero) return
         if(.not. accumulation_type_is_valid(dst%get_accumulation_type())) return
         does_match = dst_timestep == src_timestep
      end select

   end function matches

   function make_action(src, dst, rc) result(action)
      use mapl3g_ExtensionAction
      class(ExtensionAction), allocatable :: action
      class(FrequencyAspect), intent(in) :: src
      class(StateItemAspect), intent(in) :: dst
      integer, optional, intent(out) :: rc
      integer :: status

      select type(dst)
      class is (FrequencyAspect)
         call get_accumulator_action(dst%get_accumulation_type(), ESMF_TYPEKIND_R4, action, _RC) 
         _ASSERT(allocated(action), 'Unable to allocate action')
      class default
         _FAIL('FrequencyAspect cannot convert from other class.')
      end select
      _RETURN(_SUCCESS)
      _UNUSED_DUMMY(src)

   end function make_action

   logical function supports_conversion_general(src) result(supports)
      class(FrequencyAspect), intent(in) :: src

      supports = .TRUE.
      _UNUSED_DUMMY(src)

   end function supports_conversion_general

   logical function supports_conversion_specific(src, dst) result(supports)
      class(FrequencyAspect), intent(in) :: src
      class(StateItemAspect), intent(in) :: dst

      select type(dst)
      class is (FrequencyAspect)
         supports = src .divides. dst
      end select

   end function supports_conversion_specific

   logical function aspect_divides(factor, base)
      class(FrequencyAspect), intent(in) :: factor
      class(FrequencyAspect), intent(in) :: base

      aspect_divides = interval_divides(factor%get_timestep(), base%get_timestep())

   end function aspect_divides

   logical function interval_divides(factor, base) result(lval)
      type(ESMF_TimeInterval), intent(in) :: factor
      type(ESMF_TimeInterval), intent(in) :: base
      type(ESMF_TimeInterval), pointer :: zero

      lval = .FALSE.
      zero => get_zero()
      if(factor == zero) return
      lval = mod(base, factor) == zero

   end function interval_divides

   function get_zero() result(zero)
      type(ESMF_TimeInterval), pointer :: zero
      logical, save :: zero_is_uninitialized = .TRUE.

      if(zero_is_uninitialized) then
         call ESMF_TimeIntervalSet(ZERO_TI, ns=0)
         zero_is_uninitialized = .FALSE.
      end if
      zero => ZERO_TI

   end function get_zero

end module mapl3g_FrequencyAspect