ExtensionFamily.F90 Source File


This file depends on

sourcefile~~extensionfamily.f90~~EfferentGraph sourcefile~extensionfamily.f90 ExtensionFamily.F90 sourcefile~errorhandling.f90 ErrorHandling.F90 sourcefile~extensionfamily.f90->sourcefile~errorhandling.f90 sourcefile~stateitemextension.f90 StateItemExtension.F90 sourcefile~extensionfamily.f90->sourcefile~stateitemextension.f90 sourcefile~stateitemextensionptrvector.f90 StateItemExtensionPtrVector.F90 sourcefile~extensionfamily.f90->sourcefile~stateitemextensionptrvector.f90 sourcefile~stateitemspec.f90 StateItemSpec.F90 sourcefile~extensionfamily.f90->sourcefile~stateitemspec.f90 sourcefile~mapl_throw.f90 MAPL_Throw.F90 sourcefile~errorhandling.f90->sourcefile~mapl_throw.f90 sourcefile~stateitemextension.f90->sourcefile~errorhandling.f90 sourcefile~stateitemextension.f90->sourcefile~stateitemspec.f90 sourcefile~componentdriver.f90 ComponentDriver.F90 sourcefile~stateitemextension.f90->sourcefile~componentdriver.f90 sourcefile~componentdriverptrvector.f90 ComponentDriverPtrVector.F90 sourcefile~stateitemextension.f90->sourcefile~componentdriverptrvector.f90 sourcefile~componentdrivervector.f90 ComponentDriverVector.F90 sourcefile~stateitemextension.f90->sourcefile~componentdrivervector.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~nullaction.f90 NullAction.F90 sourcefile~stateitemextension.f90->sourcefile~nullaction.f90 sourcefile~stateitemextensionptrvector.f90->sourcefile~stateitemextension.f90 sourcefile~stateitemspec.f90->sourcefile~errorhandling.f90 sourcefile~actualptvector.f90 ActualPtVector.F90 sourcefile~stateitemspec.f90->sourcefile~actualptvector.f90 sourcefile~actualconnectionpt.f90 ActualConnectionPt.F90 sourcefile~actualptvector.f90->sourcefile~actualconnectionpt.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~componentdriverptrvector.f90->sourcefile~componentdriver.f90 sourcefile~componentdrivervector.f90->sourcefile~componentdriver.f90 sourcefile~genericcoupler.f90->sourcefile~errorhandling.f90 sourcefile~genericcoupler.f90->sourcefile~extensionaction.f90 sourcefile~genericcoupler.f90->sourcefile~griddedcomponentdriver.f90 sourcefile~couplermetacomponent.f90 CouplerMetaComponent.F90 sourcefile~genericcoupler.f90->sourcefile~couplermetacomponent.f90 sourcefile~griddedcomponentdriver.f90->sourcefile~errorhandling.f90 sourcefile~griddedcomponentdriver.f90->sourcefile~componentdriver.f90 sourcefile~griddedcomponentdriver.f90->sourcefile~componentdrivervector.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~nullaction.f90->sourcefile~errorhandling.f90 sourcefile~nullaction.f90->sourcefile~extensionaction.f90

Files dependent on this one

sourcefile~~extensionfamily.f90~~AfferentGraph sourcefile~extensionfamily.f90 ExtensionFamily.F90 sourcefile~mapl_generic.f90~2 MAPL_Generic.F90 sourcefile~mapl_generic.f90~2->sourcefile~extensionfamily.f90 sourcefile~stateregistry.f90 StateRegistry.F90 sourcefile~mapl_generic.f90~2->sourcefile~stateregistry.f90 sourcefile~modelverticalgrid.f90 ModelVerticalGrid.F90 sourcefile~modelverticalgrid.f90->sourcefile~extensionfamily.f90 sourcefile~modelverticalgrid.f90->sourcefile~stateregistry.f90 sourcefile~reexportconnection.f90 ReexportConnection.F90 sourcefile~reexportconnection.f90->sourcefile~extensionfamily.f90 sourcefile~reexportconnection.f90->sourcefile~stateregistry.f90 sourcefile~stateregistry.f90->sourcefile~extensionfamily.f90 sourcefile~virtualptfamilymap.f90 VirtualPtFamilyMap.F90 sourcefile~stateregistry.f90->sourcefile~virtualptfamilymap.f90 sourcefile~test_extensionfamily.pf Test_ExtensionFamily.pf sourcefile~test_extensionfamily.pf->sourcefile~extensionfamily.f90 sourcefile~test_extensionfamily.pf->sourcefile~stateregistry.f90 sourcefile~test_stateregistry.pf Test_StateRegistry.pf sourcefile~test_stateregistry.pf->sourcefile~extensionfamily.f90 sourcefile~test_stateregistry.pf->sourcefile~stateregistry.f90 sourcefile~virtualptfamilymap.f90->sourcefile~extensionfamily.f90 sourcefile~can_connect_to.f90 can_connect_to.F90 sourcefile~can_connect_to.f90->sourcefile~modelverticalgrid.f90 sourcefile~can_connect_to.f90~2 can_connect_to.F90 sourcefile~can_connect_to.f90~2->sourcefile~modelverticalgrid.f90 sourcefile~can_connect_to.f90~3 can_connect_to.F90 sourcefile~can_connect_to.f90~3->sourcefile~modelverticalgrid.f90 sourcefile~componentspecparser.f90 ComponentSpecParser.F90 sourcefile~componentspecparser.f90->sourcefile~reexportconnection.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~stateregistry.f90 sourcefile~mapl3_deprecated.f90 MAPL3_Deprecated.F90 sourcefile~mapl3_deprecated.f90->sourcefile~mapl_generic.f90~2 sourcefile~matchconnection.f90 MatchConnection.F90 sourcefile~matchconnection.f90->sourcefile~stateregistry.f90 sourcefile~outermetacomponent.f90 OuterMetaComponent.F90 sourcefile~outermetacomponent.f90->sourcefile~stateregistry.f90 sourcefile~protoextdatagc.f90 ProtoExtDataGC.F90 sourcefile~protoextdatagc.f90->sourcefile~mapl_generic.f90~2 sourcefile~protoextdatagc.f90->sourcefile~stateregistry.f90 sourcefile~servicespec.f90 ServiceSpec.F90 sourcefile~servicespec.f90->sourcefile~stateregistry.f90 sourcefile~simpleconnection.f90 SimpleConnection.F90 sourcefile~simpleconnection.f90->sourcefile~stateregistry.f90 sourcefile~simpleleafgridcomp.f90 SimpleLeafGridComp.F90 sourcefile~simpleleafgridcomp.f90->sourcefile~mapl_generic.f90~2 sourcefile~simpleparentgridcomp.f90 SimpleParentGridComp.F90 sourcefile~simpleparentgridcomp.f90->sourcefile~mapl_generic.f90~2 sourcefile~test_modelverticalgrid.pf Test_ModelVerticalGrid.pf sourcefile~test_modelverticalgrid.pf->sourcefile~modelverticalgrid.f90 sourcefile~test_modelverticalgrid.pf->sourcefile~stateregistry.f90 sourcefile~test_runchild.pf Test_RunChild.pf sourcefile~test_runchild.pf->sourcefile~mapl_generic.f90~2 sourcefile~test_scenarios.pf Test_Scenarios.pf sourcefile~test_scenarios.pf->sourcefile~mapl_generic.f90~2 sourcefile~test_simpleleafgridcomp.pf Test_SimpleLeafGridComp.pf sourcefile~test_simpleleafgridcomp.pf->sourcefile~mapl_generic.f90~2 sourcefile~test_simpleparentgridcomp.pf Test_SimpleParentGridComp.pf sourcefile~test_simpleparentgridcomp.pf->sourcefile~mapl_generic.f90~2 sourcefile~variablespec.f90 VariableSpec.F90 sourcefile~variablespec.f90->sourcefile~stateregistry.f90

Source Code

#include "MAPL_Generic.h"

! A StateItem can be extended by means of a coupler.  The
! set of all such related extensions are encapsulated
! in objects of type ExtensionFamily.


module mapl3g_ExtensionFamily
   use mapl3g_StateItemSpec
   use mapl3g_StateItemExtension
   use mapl3g_StateItemExtensionPtrVector
   use mapl_ErrorHandling
   implicit none
   private

   public :: ExtensionFamily

   ! The primary/base item spec is tracked separately to enable
   ! control of which will appear in user states with its short-name.
   type :: ExtensionFamily
      private
      logical :: has_primary_ = .false.
      type(StateItemExtensionPtrVector) :: extensions
   contains
      procedure :: has_primary
      procedure :: get_primary
      procedure :: get_extensions
      procedure :: get_extension
      procedure :: add_extension
      procedure :: num_variants

      procedure :: find_closest_extension
   end type ExtensionFamily

   interface ExtensionFamily
      procedure new_ExtensionFamily_empty
      procedure new_ExtensionFamily_primary
   end interface ExtensionFamily

contains

   function new_ExtensionFamily_empty() result(family)
      type(ExtensionFamily) :: family
      family%has_primary_ = .false.
   end function new_ExtensionFamily_empty

   function new_ExtensionFamily_primary(primary) result(family)
      type(ExtensionFamily) :: family
      type(StateItemExtension), pointer, intent(in) :: primary

      type(StateItemExtensionPtr) :: wrapper

      family%has_primary_ = .true.
      wrapper%ptr => primary
      call family%extensions%push_back(wrapper)

   end function new_ExtensionFamily_primary

   logical function has_primary(this)
      class(ExtensionFamily), intent(in) :: this
      has_primary = this%has_primary_
   end function has_primary

   function get_primary(this, rc) result(primary)
      type(StateItemExtension), pointer :: primary
      class(ExtensionFamily), target, intent(in) :: this
      integer, optional, intent(out) :: rc
      type(StateItemExtensionPtr), pointer :: wrapper

      primary => null()
      _ASSERT(this%has_primary_, "No primary item spec")
      _ASSERT(this%extensions%size() > 0, "No primary item spec")
      wrapper => this%extensions%front()
      primary => wrapper%ptr
      _RETURN(_SUCCESS)
   end function get_primary

   function get_extensions(this) result(extensions)
      type(StateItemExtensionPtrVector), pointer :: extensions
      class(ExtensionFamily), target, intent(in) :: this
      extensions => this%extensions
   end function get_extensions

   function get_extension(this, i) result(extension)
      type(StateItemExtension), pointer :: extension
      integer, intent(in) :: i
      class(ExtensionFamily), target, intent(in) :: this

      type(StateItemExtensionPtr), pointer :: wrapper
      wrapper => this%extensions%at(i)
      extension => wrapper%ptr
   end function get_extension

   subroutine add_extension(this, extension)
      class(ExtensionFamily), intent(inout) :: this
      type(StateItemExtension), pointer, intent(in) :: extension

      type(StateItemExtensionPtr) :: wrapper

      wrapper%ptr => extension
      call this%extensions%push_back(wrapper)

   end subroutine add_extension

   integer function num_variants(this)
      class(ExtensionFamily), intent(in) :: this
      num_variants = this%extensions%size()
   end function num_variants


   function find_closest_extension(family, goal_spec, rc) result(closest_extension)
      type(StateItemExtension), pointer :: closest_extension
      class(ExtensionFamily), intent(in) :: family
      class(StateItemSpec), intent(in) :: goal_spec
      integer, optional, intent(out) :: rc

      type(StateItemExtensionPtrVector) :: subgroup, new_subgroup
      class(StateItemSpec), pointer :: archetype
      integer :: i, j
      type(StateItemAdapterWrapper), allocatable :: adapters(:)
      integer :: status
      type(StateItemExtensionPtr) :: extension_ptr
      type(StateItemExtension), pointer :: primary
      class(StateItemSpec), pointer :: spec
      
      closest_extension => null()
      subgroup = family%get_extensions()
      primary => family%get_primary()  ! archetype defines the rules
      archetype => primary%get_spec()
      adapters = archetype%make_adapters(goal_spec, _RC)

      do i = 1, size(adapters)
         new_subgroup = StateItemExtensionPtrVector()
         do j = 1, subgroup%size()
            extension_ptr = subgroup%of(j)
            spec => extension_ptr%ptr%get_spec()
            associate (adapter => adapters(i)%adapter)
              if (adapter%apply(spec)) then
                 call new_subgroup%push_back(extension_ptr)
              end if
            end associate
         end do
         
         if (new_subgroup%size() == 0) exit
         subgroup = new_subgroup
      end do

      extension_ptr = subgroup%front()
      closest_extension => extension_ptr%ptr

      _RETURN(_SUCCESS)
   end function find_closest_extension

   
end module mapl3g_ExtensionFamily