StateItemExtension.F90 Source File


This file depends on

sourcefile~~stateitemextension.f90~~EfferentGraph sourcefile~stateitemextension.f90 StateItemExtension.F90 sourcefile~componentdriver.f90 ComponentDriver.F90 sourcefile~stateitemextension.f90->sourcefile~componentdriver.f90 sourcefile~componentdrivervector.f90 ComponentDriverVector.F90 sourcefile~stateitemextension.f90->sourcefile~componentdrivervector.f90 sourcefile~errorhandling.f90 ErrorHandling.F90 sourcefile~stateitemextension.f90->sourcefile~errorhandling.f90 sourcefile~extensionaction.f90 ExtensionAction.F90 sourcefile~stateitemextension.f90->sourcefile~extensionaction.f90 sourcefile~genericcoupler.f90 GenericCoupler.F90 sourcefile~stateitemextension.f90->sourcefile~genericcoupler.f90 sourcefile~griddedcomponentdriver.f90 GriddedComponentDriver.F90 sourcefile~stateitemextension.f90->sourcefile~griddedcomponentdriver.f90 sourcefile~multistate.f90 MultiState.F90 sourcefile~stateitemextension.f90->sourcefile~multistate.f90 sourcefile~stateitemaspect.f90 StateItemAspect.F90 sourcefile~stateitemextension.f90->sourcefile~stateitemaspect.f90 sourcefile~stateitemspec.f90 StateItemSpec.F90 sourcefile~stateitemextension.f90->sourcefile~stateitemspec.f90 sourcefile~componentdriver.f90->sourcefile~errorhandling.f90 sourcefile~componentdriver.f90->sourcefile~multistate.f90 sourcefile~maplshared.f90 MaplShared.F90 sourcefile~componentdriver.f90->sourcefile~maplshared.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~genericcoupler.f90->sourcefile~componentdriver.f90 sourcefile~genericcoupler.f90->sourcefile~errorhandling.f90 sourcefile~genericcoupler.f90->sourcefile~extensionaction.f90 sourcefile~couplermetacomponent.f90 CouplerMetaComponent.F90 sourcefile~genericcoupler.f90->sourcefile~couplermetacomponent.f90 sourcefile~couplerphases.f90 CouplerPhases.F90 sourcefile~genericcoupler.f90->sourcefile~couplerphases.f90 sourcefile~verticalregridaction.f90 VerticalRegridAction.F90 sourcefile~genericcoupler.f90->sourcefile~verticalregridaction.f90 sourcefile~griddedcomponentdriver.f90->sourcefile~componentdriver.f90 sourcefile~griddedcomponentdriver.f90->sourcefile~componentdrivervector.f90 sourcefile~griddedcomponentdriver.f90->sourcefile~errorhandling.f90 sourcefile~griddedcomponentdriver.f90->sourcefile~multistate.f90 sourcefile~keywordenforcer.f90 KeywordEnforcer.F90 sourcefile~griddedcomponentdriver.f90->sourcefile~keywordenforcer.f90 sourcefile~multistate.f90->sourcefile~errorhandling.f90 sourcefile~esmf_utilities.f90 ESMF_Utilities.F90 sourcefile~multistate.f90->sourcefile~esmf_utilities.f90 sourcefile~multistate.f90->sourcefile~keywordenforcer.f90 sourcefile~stateitemaspect.f90->sourcefile~errorhandling.f90 sourcefile~stateitemspec.f90->sourcefile~errorhandling.f90 sourcefile~stateitemspec.f90->sourcefile~extensionaction.f90 sourcefile~stateitemspec.f90->sourcefile~stateitemaspect.f90 sourcefile~actualptvector.f90 ActualPtVector.F90 sourcefile~stateitemspec.f90->sourcefile~actualptvector.f90 sourcefile~aspectcollection.f90 AspectCollection.F90 sourcefile~stateitemspec.f90->sourcefile~aspectcollection.f90

Files dependent on this one

sourcefile~~stateitemextension.f90~~AfferentGraph sourcefile~stateitemextension.f90 StateItemExtension.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_StateItemExtension
   use mapl3g_StateItemSpec
   use mapl3g_ComponentDriver
   use mapl3g_GriddedComponentDriver
   use mapl3g_ComponentDriverVector
   use mapl3g_ComponentDriverVector
   use mapl3g_ExtensionAction
   use mapl3g_GenericCoupler
   use mapl3g_StateItemAspect
   use mapl3g_MultiState
   use mapl_ErrorHandling
   use gftl2_StringVector
   use esmf
   implicit none
   private

   public :: StateItemExtension
   public :: StateItemExtensionPtr

   ! A StateItemExtension "owns" a spec as well as the coupler
   ! that produces it (if any).

   type StateItemExtension
      private
      class(StateItemSpec), allocatable :: spec
      type(ComponentDriverVector) :: consumers ! couplers that depend on spec
      class(ComponentDriver), pointer :: producer => null() ! coupler that computes spec
   contains
      procedure :: get_spec

      procedure :: has_producer
      procedure :: get_producer
      procedure :: set_producer

      procedure :: has_consumers
      procedure :: add_consumer
      procedure :: get_consumers

      procedure :: make_extension
   end type StateItemExtension

   type :: StateItemExtensionPtr
      type(StateItemExtension), pointer :: ptr => null()
   end type StateItemExtensionPtr

   interface StateItemExtension
      procedure :: new_StateItemExtension_spec
   end interface StateItemExtension

contains

   function new_StateItemExtension_spec(spec) result(ext)
      type(StateItemExtension) :: ext
      class(StateItemSpec), intent(in) :: spec
      ext%spec = spec
   end function new_StateItemExtension_spec

   function get_spec(this) result(spec)
      class(StateItemExtension), target, intent(in) :: this
      class(StateItemSpec), pointer :: spec
      spec => this%spec
   end function get_spec

   logical function has_producer(this)
      class(StateItemExtension), target, intent(in) :: this
      has_producer = associated(this%producer)
   end function has_producer

   function get_producer(this) result(producer)
      class(StateItemExtension), target, intent(in) :: this
      class(ComponentDriver), pointer :: producer

      producer => this%producer

   end function get_producer

   subroutine set_producer(this, producer, rc)
      class(StateItemExtension), intent(inout) :: this
      class(ComponentDriver), pointer, intent(in) :: producer
      integer, optional, intent(out) :: rc

      _ASSERT(.not. this%has_producer(), 'cannot set producer for extension that already has one')
      this%producer => producer

      _RETURN(_SUCCESS)
   end subroutine set_producer


  logical function has_consumers(this)
      class(StateItemExtension), target, intent(in) :: this
      has_consumers = this%consumers%size() > 0
   end function has_consumers


   function get_consumers(this) result(consumers)
      class(StateItemExtension), target, intent(in) :: this
      type(ComponentDriverVector), pointer :: consumers
      consumers => this%consumers
   end function get_consumers

   function add_consumer(this, consumer) result(reference)
      class(ComponentDriver), pointer :: reference
      class(StateItemExtension), target, intent(inout) :: this
      type(GriddedComponentDriver), intent(in) :: consumer

      call this%consumers%push_back(consumer)
      reference => this%consumers%back()

   end function add_consumer

   ! Creation of an extension requires a new coupler that transforms
   ! from source (this) spec to dest (extension) spec.
   ! This coupler is a "consumer" of the original spec (this), and a "producer" of
   ! the new spec (extension).

   recursive function make_extension(this, goal, rc) result(extension)
      type(StateItemExtension) :: extension
      class(StateItemExtension), target, intent(inout) :: this
      class(StateItemSpec), target, intent(in) :: goal
      integer, intent(out) :: rc

      integer :: status
      integer :: i
      class(StateItemSpec), target, allocatable :: new_spec
      class(ExtensionAction), allocatable :: action
      class(ComponentDriver), pointer :: producer
      class(ComponentDriver), pointer :: source
      type(ESMF_GridComp) :: coupler_gridcomp
      type(StateItemAdapterWrapper), allocatable :: adapters(:)
      type(ESMF_Clock) :: fake_clock
      logical :: match
      type(StringVector), target :: aspect_names
      character(:), pointer :: aspect_name
      class(StateItemAspect), pointer :: src_aspect, dst_aspect


      call this%spec%set_active()

      new_spec = this%spec

      aspect_names = this%spec%get_aspect_order(goal)
      do i = 1, aspect_names%size()
         aspect_name => aspect_names%of(i)
         src_aspect => new_spec%get_aspect(aspect_name, _RC)
         _ASSERT(associated(src_aspect), 'src aspect not found')

         dst_aspect => goal%get_aspect(aspect_name, _RC)
         _ASSERT(associated(dst_aspect), 'dst aspect not found')

         _ASSERT(src_aspect%can_connect_to(dst_aspect), 'cannot connect aspect ' // aspect_name)

         if (src_aspect%needs_extension_for(dst_aspect)) then
            allocate(action, source=src_aspect%make_action(dst_aspect, rc=status))
            _VERIFY(status)
            call new_spec%set_aspect(dst_aspect, _RC)
            exit
         end if

      end do

      if (allocated(action)) then
         call new_spec%create(_RC)
         call new_spec%set_active()
         source => this%get_producer()
         coupler_gridcomp = make_coupler(action, source, _RC)
         producer => this%add_consumer(GriddedComponentDriver(coupler_gridcomp, fake_clock, MultiState()))
         extension = StateItemExtension(new_spec)
         call extension%set_producer(producer)
         _RETURN(_SUCCESS)
      end if

      _RETURN(_SUCCESS)
   end function make_extension

end module mapl3g_StateItemExtension