CouplerMetaComponent.F90 Source File


This file depends on

sourcefile~~couplermetacomponent.f90~~EfferentGraph sourcefile~couplermetacomponent.f90 CouplerMetaComponent.F90 sourcefile~componentdriver.f90 ComponentDriver.F90 sourcefile~couplermetacomponent.f90->sourcefile~componentdriver.f90 sourcefile~componentdriverptrvector.f90 ComponentDriverPtrVector.F90 sourcefile~couplermetacomponent.f90->sourcefile~componentdriverptrvector.f90 sourcefile~componentdrivervector.f90 ComponentDriverVector.F90 sourcefile~couplermetacomponent.f90->sourcefile~componentdrivervector.f90 sourcefile~couplerphases.f90 CouplerPhases.F90 sourcefile~couplermetacomponent.f90->sourcefile~couplerphases.f90 sourcefile~errorhandling.f90 ErrorHandling.F90 sourcefile~couplermetacomponent.f90->sourcefile~errorhandling.f90 sourcefile~esmf_interfaces.f90 ESMF_Interfaces.F90 sourcefile~couplermetacomponent.f90->sourcefile~esmf_interfaces.f90 sourcefile~extensionaction.f90 ExtensionAction.F90 sourcefile~couplermetacomponent.f90->sourcefile~extensionaction.f90 sourcefile~griddedcomponentdriver.f90 GriddedComponentDriver.F90 sourcefile~couplermetacomponent.f90->sourcefile~griddedcomponentdriver.f90 sourcefile~verticalregridaction.f90 VerticalRegridAction.F90 sourcefile~couplermetacomponent.f90->sourcefile~verticalregridaction.f90 sourcefile~componentdriver.f90->sourcefile~errorhandling.f90 sourcefile~maplshared.f90 MaplShared.F90 sourcefile~componentdriver.f90->sourcefile~maplshared.f90 sourcefile~multistate.f90 MultiState.F90 sourcefile~componentdriver.f90->sourcefile~multistate.f90 sourcefile~componentdriverptrvector.f90->sourcefile~componentdriver.f90 sourcefile~componentdrivervector.f90->sourcefile~componentdriver.f90 sourcefile~mapl_throw.f90 MAPL_Throw.F90 sourcefile~errorhandling.f90->sourcefile~mapl_throw.f90 sourcefile~extensionaction.f90->sourcefile~errorhandling.f90 sourcefile~griddedcomponentdriver.f90->sourcefile~componentdriver.f90 sourcefile~griddedcomponentdriver.f90->sourcefile~componentdrivervector.f90 sourcefile~griddedcomponentdriver.f90->sourcefile~errorhandling.f90 sourcefile~keywordenforcer.f90 KeywordEnforcer.F90 sourcefile~griddedcomponentdriver.f90->sourcefile~keywordenforcer.f90 sourcefile~griddedcomponentdriver.f90->sourcefile~multistate.f90 sourcefile~verticalregridaction.f90->sourcefile~componentdriver.f90 sourcefile~verticalregridaction.f90->sourcefile~couplerphases.f90 sourcefile~verticalregridaction.f90->sourcefile~errorhandling.f90 sourcefile~verticalregridaction.f90->sourcefile~extensionaction.f90 sourcefile~csr_sparsematrix.f90 CSR_SparseMatrix.F90 sourcefile~verticalregridaction.f90->sourcefile~csr_sparsematrix.f90 sourcefile~fieldcondensedarray.f90 FieldCondensedArray.F90 sourcefile~verticalregridaction.f90->sourcefile~fieldcondensedarray.f90 sourcefile~verticallinearmap.f90 VerticalLinearMap.F90 sourcefile~verticalregridaction.f90->sourcefile~verticallinearmap.f90 sourcefile~verticalregridmethod.f90 VerticalRegridMethod.F90 sourcefile~verticalregridaction.f90->sourcefile~verticalregridmethod.f90

Files dependent on this one

sourcefile~~couplermetacomponent.f90~~AfferentGraph sourcefile~couplermetacomponent.f90 CouplerMetaComponent.F90 sourcefile~genericcoupler.f90 GenericCoupler.F90 sourcefile~genericcoupler.f90->sourcefile~couplermetacomponent.f90 sourcefile~stateitemextension.f90 StateItemExtension.F90 sourcefile~stateitemextension.f90->sourcefile~genericcoupler.f90 sourcefile~extensionfamily.f90 ExtensionFamily.F90 sourcefile~extensionfamily.f90->sourcefile~stateitemextension.f90 sourcefile~stateitemextensionptrvector.f90 StateItemExtensionPtrVector.F90 sourcefile~extensionfamily.f90->sourcefile~stateitemextensionptrvector.f90 sourcefile~mapl_generic.f90~2 MAPL_Generic.F90 sourcefile~mapl_generic.f90~2->sourcefile~stateitemextension.f90 sourcefile~mapl_generic.f90~2->sourcefile~extensionfamily.f90 sourcefile~stateregistry.f90 StateRegistry.F90 sourcefile~mapl_generic.f90~2->sourcefile~stateregistry.f90 sourcefile~matchconnection.f90 MatchConnection.F90 sourcefile~matchconnection.f90->sourcefile~stateitemextension.f90 sourcefile~simpleconnection.f90 SimpleConnection.F90 sourcefile~matchconnection.f90->sourcefile~simpleconnection.f90 sourcefile~matchconnection.f90->sourcefile~stateregistry.f90 sourcefile~modelverticalgrid.f90 ModelVerticalGrid.F90 sourcefile~modelverticalgrid.f90->sourcefile~stateitemextension.f90 sourcefile~modelverticalgrid.f90->sourcefile~extensionfamily.f90 sourcefile~modelverticalgrid.f90->sourcefile~stateregistry.f90 sourcefile~protoextdatagc.f90 ProtoExtDataGC.F90 sourcefile~protoextdatagc.f90->sourcefile~stateitemextension.f90 sourcefile~protoextdatagc.f90->sourcefile~mapl_generic.f90~2 sourcefile~protoextdatagc.f90->sourcefile~simpleconnection.f90 sourcefile~protoextdatagc.f90->sourcefile~stateregistry.f90 sourcefile~servicespec.f90 ServiceSpec.F90 sourcefile~servicespec.f90->sourcefile~stateitemextension.f90 sourcefile~servicespec.f90->sourcefile~stateregistry.f90 sourcefile~simpleconnection.f90->sourcefile~stateitemextension.f90 sourcefile~simpleconnection.f90->sourcefile~stateitemextensionptrvector.f90 sourcefile~stateitemextensionvector.f90 StateItemExtensionVector.F90 sourcefile~simpleconnection.f90->sourcefile~stateitemextensionvector.f90 sourcefile~simpleconnection.f90->sourcefile~stateregistry.f90 sourcefile~stateitemextensionptrvector.f90->sourcefile~stateitemextension.f90 sourcefile~stateitemextensionvector.f90->sourcefile~stateitemextension.f90 sourcefile~stateregistry.f90->sourcefile~stateitemextension.f90 sourcefile~stateregistry.f90->sourcefile~extensionfamily.f90 sourcefile~stateregistry.f90->sourcefile~stateitemextensionptrvector.f90 sourcefile~stateregistry.f90->sourcefile~stateitemextensionvector.f90 sourcefile~test_extensionfamily.pf Test_ExtensionFamily.pf sourcefile~test_extensionfamily.pf->sourcefile~stateitemextension.f90 sourcefile~test_extensionfamily.pf->sourcefile~extensionfamily.f90 sourcefile~test_extensionfamily.pf->sourcefile~stateregistry.f90 sourcefile~test_modelverticalgrid.pf Test_ModelVerticalGrid.pf sourcefile~test_modelverticalgrid.pf->sourcefile~stateitemextension.f90 sourcefile~test_modelverticalgrid.pf->sourcefile~modelverticalgrid.f90 sourcefile~test_modelverticalgrid.pf->sourcefile~stateregistry.f90 sourcefile~test_stateregistry.pf Test_StateRegistry.pf sourcefile~test_stateregistry.pf->sourcefile~stateitemextension.f90 sourcefile~test_stateregistry.pf->sourcefile~extensionfamily.f90 sourcefile~test_stateregistry.pf->sourcefile~simpleconnection.f90 sourcefile~test_stateregistry.pf->sourcefile~stateitemextensionptrvector.f90 sourcefile~test_stateregistry.pf->sourcefile~stateregistry.f90 sourcefile~componentspecparser.f90 ComponentSpecParser.F90 sourcefile~componentspecparser.f90->sourcefile~matchconnection.f90 sourcefile~componentspecparser.f90->sourcefile~simpleconnection.f90 sourcefile~componentspecparser.f90->sourcefile~stateregistry.f90 sourcefile~configurablegridcomp.f90 ConfigurableGridComp.F90 sourcefile~configurablegridcomp.f90->sourcefile~mapl_generic.f90~2 sourcefile~connect_all.f90 connect_all.F90 sourcefile~connect_all.f90->sourcefile~matchconnection.f90 sourcefile~generic3g.f90 Generic3g.F90 sourcefile~generic3g.f90->sourcefile~mapl_generic.f90~2 sourcefile~make_itemspec.f90 make_itemSpec.F90 sourcefile~make_itemspec.f90->sourcefile~servicespec.f90 sourcefile~make_itemspec.f90->sourcefile~stateregistry.f90 sourcefile~mapl3_deprecated.f90 MAPL3_Deprecated.F90 sourcefile~mapl3_deprecated.f90->sourcefile~mapl_generic.f90~2 sourcefile~outermetacomponent.f90 OuterMetaComponent.F90 sourcefile~outermetacomponent.f90->sourcefile~stateregistry.f90 sourcefile~parse_geometry_spec.f90 parse_geometry_spec.F90 sourcefile~parse_geometry_spec.f90->sourcefile~modelverticalgrid.f90 sourcefile~reexportconnection.f90 ReexportConnection.F90 sourcefile~reexportconnection.f90->sourcefile~extensionfamily.f90 sourcefile~reexportconnection.f90->sourcefile~stateregistry.f90 sourcefile~test_configurablegridcomp.pf Test_ConfigurableGridComp.pf sourcefile~test_configurablegridcomp.pf->sourcefile~mapl_generic.f90~2 sourcefile~test_scenarios.pf Test_Scenarios.pf sourcefile~test_scenarios.pf->sourcefile~mapl_generic.f90~2 sourcefile~variablespec.f90 VariableSpec.F90 sourcefile~variablespec.f90->sourcefile~stateregistry.f90 sourcefile~virtualptfamilymap.f90 VirtualPtFamilyMap.F90 sourcefile~virtualptfamilymap.f90->sourcefile~extensionfamily.f90

Source Code

#include "MAPL_Generic.h"

module mapl3g_CouplerMetaComponent

   use mapl3g_CouplerPhases, only: GENERIC_COUPLER_UPDATE, GENERIC_COUPLER_INVALIDATE
   use mapl3g_ComponentDriver, only: ComponentDriver, ComponentDriverPtr
   use mapl3g_GriddedComponentDriver, only: GriddedComponentDriver
   use mapl3g_ComponentDriverVector, only: ComponentDriverVector
   use mapl3g_ComponentDriverPtrVector, only: ComponentDriverPtrVector
   use mapl3g_ExtensionAction
   use mapl3g_VerticalRegridAction
   use mapl_ErrorHandlingMod
   use mapl3g_ESMF_Interfaces
   use esmf

   implicit none
   private

   ! Class
   public :: CouplerMetaComponent

   ! non TBF procedures
   public :: get_coupler_meta
   public :: attach_coupler_meta
   public :: free_coupler_meta

   type :: CouplerMetaComponent
      private
      class(ExtensionAction), allocatable :: action
      type(ComponentDriverPtrVector) :: sources
      type(ComponentDriverVector) :: consumers
      logical :: stale = .true.
   contains
      ! ESMF methods
      procedure :: initialize
      procedure :: update
      procedure :: invalidate
      procedure :: clock_advance

      ! Helper procedures
      procedure :: update_sources
      procedure :: invalidate_consumers
      procedure :: add_source
      procedure :: add_consumer

      ! Accessors
      procedure, non_overridable :: is_up_to_date
      procedure, non_overridable :: is_stale
      procedure, non_overridable :: set_up_to_date
      procedure, non_overridable :: set_stale
   end type CouplerMetaComponent

   character(len=*), parameter :: COUPLER_META_PRIVATE_STATE = "CouplerMetaComponent Private State"

   type CouplerMetaWrapper
      type(CouplerMetaComponent), pointer :: coupler_meta
   end type CouplerMetaWrapper

   interface CouplerMetaComponent
      procedure :: new_CouplerMetaComponent
   end interface CouplerMetaComponent

contains

   function new_CouplerMetaComponent(action, source) result (this)
      type(CouplerMetaComponent) :: this
      class(ExtensionAction), intent(in) :: action
      class(ComponentDriver), target, optional, intent(in) :: source

      type(ComponentDriverPtr) :: source_wrapper

      this%action = action
      if (present(source)) then
         source_wrapper%ptr => source
         call this%sources%push_back(source_wrapper)
      end if

   end function new_CouplerMetaComponent

   recursive subroutine initialize(this, importState, exportState, clock, rc)
      class(CouplerMetaComponent), intent(inout) :: this
      type(ESMF_State), intent(inout) :: importState
      type(ESMF_State), intent(inout) :: exportState
      type(ESMF_Clock), intent(inout) :: clock
      integer, optional, intent(out) :: rc

      integer :: status

      call this%action%initialize(importState, exportState, clock, _RC)
      
      _RETURN(_SUCCESS)
   end subroutine initialize

   ! Check if export item has been updated and update import item
   ! accordingly.
   recursive subroutine update_time_varying(this, importState, exportState, clock, rc)
      class(CouplerMetaComponent), intent(inout) :: this
      type(ESMF_State), intent(inout) :: importState
      type(ESMF_State), intent(inout) :: exportState
      type(ESMF_Clock), intent(inout) :: clock
      integer, optional, intent(out) :: rc

      integer :: status
      type(ESMF_Field) :: f_in, f_out

!#      _RETURN_UNLESS(this%export_is_time_varying())
      call ESMF_StateGet(importState, itemName='import[1]', field=f_in, _RC)
      call ESMF_StateGet(exportState, itemName='export[1]', field=f_out, _RC)

!#      call FieldUpdate(f_in, from=f_out, ignore=this%action%get_ignore(), _RC)
      
      _RETURN(_SUCCESS)
   end subroutine update_time_varying

   recursive subroutine update(this, importState, exportState, clock, rc)
      class(CouplerMetaComponent), intent(inout) :: this
      type(ESMF_State), intent(inout) :: importState
      type(ESMF_State), intent(inout) :: exportState
      type(ESMF_Clock), intent(inout) :: clock
      integer, optional, intent(out) :: rc

      integer :: status
      _RETURN_IF(this%is_up_to_date())

      !# call this%propagate_attributes(_RC)
      call this%update_sources(_RC)
      
      call this%action%update(importState, exportState, clock, _RC)
      call this%set_up_to_date()

      _RETURN(_SUCCESS)
   end subroutine update

   recursive subroutine update_sources(this, rc)
      class(CouplerMetaComponent) :: this
      integer, intent(out) :: rc

      integer :: status
      integer :: i
      type(ComponentDriverPtr), pointer :: source_wrapper

      do i = 1, this%sources%size()
         source_wrapper => this%sources%of(i)
         call source_wrapper%ptr%run(phase_idx=GENERIC_COUPLER_UPDATE, _RC)
      end do

      _RETURN(_SUCCESS)
   end subroutine update_sources

   ! Check if export item has been updated and update import item
   ! accordingly.
   recursive subroutine invalidate_time_varying(this, importState, exportState, clock, rc)
      class(CouplerMetaComponent), intent(inout) :: this
      type(ESMF_State), intent(inout) :: importState
      type(ESMF_State), intent(inout) :: exportState
      type(ESMF_Clock), intent(inout) :: clock
      integer, optional, intent(out) :: rc

      integer :: status
      type(ESMF_Field) :: f_in, f_out

!#      _RETURN_UNLESS(this%import_is_time_varying())
      call ESMF_StateGet(importState, itemName='import[1]', field=f_in, _RC)
      call ESMF_StateGet(exportState, itemName='export[1]', field=f_out, _RC)

!#      call FieldUpdate(f_out, from=f_in, ignore=this%action%get_ignore(), _RC)
      
      _RETURN(_SUCCESS)
   end subroutine invalidate_time_varying

   recursive subroutine invalidate(this, importState, exportState, clock, rc)
      class(CouplerMetaComponent) :: this
      type(ESMF_State) :: importState
      type(ESMF_State) :: exportState
      type(ESMF_Clock) :: clock
      integer, intent(out) :: rc

      integer :: status
        
      _RETURN_IF(this%is_stale())

      call this%invalidate_consumers(_RC)
      call this%set_stale()
  
      _RETURN(_SUCCESS)
      _UNUSED_DUMMY(clock)
      _UNUSED_DUMMY(exportState)
      _UNUSED_DUMMY(importState)
   end subroutine invalidate
      
   recursive subroutine invalidate_consumers(this, rc)
      class(CouplerMetaComponent), target :: this
      integer, intent(out) :: rc

      integer :: status
      class(ComponentDriver), pointer :: consumer
      integer :: i

      do i = 1, this%consumers%size()
         consumer => this%consumers%of(i)
         call consumer%run(phase_idx=GENERIC_COUPLER_INVALIDATE, _RC)
      end do

      _RETURN(_SUCCESS)
   end subroutine invalidate_consumers

   recursive subroutine clock_advance(this, importState, exportState, clock, rc)
      class(CouplerMetaComponent), intent(inout) :: this
      type(ESMF_State), intent(inout) :: importState
      type(ESMF_State), intent(inout) :: exportState
      type(ESMF_Clock), intent(inout) :: clock
      integer, optional, intent(out) :: rc

      integer :: status
      type(ESMF_Alarm) :: alarm
      logical :: is_ringing

      call ESMF_ClockGetAlarm(clock, "MAPL::RUN_ALARM", alarm, _RC)
      is_ringing = ESMF_AlarmIsRinging(alarm, _RC)
      _RETURN_UNLESS(is_ringing)

      _RETURN(_SUCCESS)
      _UNUSED_DUMMY(this)
      _UNUSED_DUMMY(exportState)
      _UNUSED_DUMMY(importState)
   end subroutine clock_advance
      
   function add_consumer(this) result(consumer)
      class(ComponentDriver), pointer :: consumer
      class(CouplerMetaComponent), target, intent(inout) :: this

      call this%consumers%resize(this%consumers%size() + 1)
      consumer => this%consumers%back()
   end function add_consumer

   subroutine add_source(this, source)
      class(CouplerMetaComponent), target, intent(inout) :: this
      type(GriddedComponentDriver), pointer, intent(in) :: source

      type(ComponentDriverPtr) :: source_wrapper
      source_wrapper%ptr => source

      call this%sources%push_back(source_wrapper)
   end subroutine add_source

   function get_coupler_meta(gridcomp, rc) result(meta)
      type(CouplerMetaComponent), pointer :: meta
      type(ESMF_GridComp), intent(inout) :: gridcomp
      integer, optional, intent(out) :: rc

      integer :: status

      !TODO: This block is a workaround for weird link error with NAG
      !      7.2 Appears to be a collision in numbering of local
      !      scopes.
      block
      end block
      _GET_NAMED_PRIVATE_STATE(gridcomp, CouplerMetaComponent, COUPLER_META_PRIVATE_STATE, meta)

      _RETURN(_SUCCESS)
   end function get_coupler_meta

   subroutine attach_coupler_meta(gridcomp, rc)
      type(ESMF_GridComp), intent(inout) :: gridcomp
      integer, optional, intent(out) :: rc

      integer :: status

      _SET_NAMED_PRIVATE_STATE(gridcomp, CouplerMetaComponent, COUPLER_META_PRIVATE_STATE)

      _RETURN(_SUCCESS)
   end subroutine attach_coupler_meta

   subroutine free_coupler_meta(gridcomp, rc)
      type(ESMF_GridComp), intent(inout) :: gridcomp
      integer, optional, intent(out) :: rc

      integer :: status
      type(CouplerMetaWrapper) :: wrapper

      call MAPL_UserCompGetInternalState(gridcomp, COUPLER_META_PRIVATE_STATE, wrapper, status)
      _ASSERT(status==ESMF_SUCCESS, "CouplerMetaComponent not created for this gridcomp")

      deallocate(wrapper%coupler_meta)

      _RETURN(_SUCCESS)
   end subroutine free_coupler_meta

   pure subroutine set_up_to_date(this)
      class(CouplerMetaComponent), intent(inout) :: this
      this%stale = .false.
   end subroutine set_up_to_date

   pure subroutine set_stale(this)
      class(CouplerMetaComponent), intent(inout) :: this
      this%stale = .true.
    end subroutine set_stale

    pure logical function is_up_to_date(this)
      class(CouplerMetaComponent), intent(in) :: this
      is_up_to_date = .not. this%stale
   end function is_up_to_date

   pure logical function is_stale(this)
      class(CouplerMetaComponent), intent(in) :: this
      is_stale = this%stale
   end function is_stale

end module mapl3g_CouplerMetaComponent