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~stateitemaspect.f90 StateItemAspect.F90 sourcefile~extensionfamily.f90->sourcefile~stateitemaspect.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~stateitemaspect.f90->sourcefile~errorhandling.f90 sourcefile~stateitemextension.f90->sourcefile~errorhandling.f90 sourcefile~stateitemextension.f90->sourcefile~stateitemaspect.f90 sourcefile~stateitemextension.f90->sourcefile~stateitemspec.f90 sourcefile~componentdriver.f90 ComponentDriver.F90 sourcefile~stateitemextension.f90->sourcefile~componentdriver.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~stateitemextensionptrvector.f90->sourcefile~stateitemextension.f90 sourcefile~stateitemspec.f90->sourcefile~errorhandling.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 sourcefile~stateitemspec.f90->sourcefile~extensionaction.f90 sourcefile~actualconnectionpt.f90 ActualConnectionPt.F90 sourcefile~actualptvector.f90->sourcefile~actualconnectionpt.f90 sourcefile~aspectcollection.f90->sourcefile~errorhandling.f90 sourcefile~aspectcollection.f90->sourcefile~stateitemaspect.f90 sourcefile~attributesaspect.f90 AttributesAspect.F90 sourcefile~aspectcollection.f90->sourcefile~attributesaspect.f90 sourcefile~frequencyaspect.f90 FrequencyAspect.F90 sourcefile~aspectcollection.f90->sourcefile~frequencyaspect.f90 sourcefile~geomaspect.f90 GeomAspect.F90 sourcefile~aspectcollection.f90->sourcefile~geomaspect.f90 sourcefile~keywordenforcer.f90 KeywordEnforcer.F90 sourcefile~aspectcollection.f90->sourcefile~keywordenforcer.f90 sourcefile~typekindaspect.f90 TypekindAspect.F90 sourcefile~aspectcollection.f90->sourcefile~typekindaspect.f90 sourcefile~ungriddeddimsaspect.f90 UngriddedDimsAspect.F90 sourcefile~aspectcollection.f90->sourcefile~ungriddeddimsaspect.f90 sourcefile~unitsaspect.f90 UnitsAspect.F90 sourcefile~aspectcollection.f90->sourcefile~unitsaspect.f90 sourcefile~verticalgridaspect.f90 VerticalGridAspect.F90 sourcefile~aspectcollection.f90->sourcefile~verticalgridaspect.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~extensionaction.f90->sourcefile~errorhandling.f90 sourcefile~genericcoupler.f90->sourcefile~errorhandling.f90 sourcefile~genericcoupler.f90->sourcefile~componentdriver.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~errorhandling.f90 sourcefile~griddedcomponentdriver.f90->sourcefile~componentdriver.f90 sourcefile~griddedcomponentdriver.f90->sourcefile~componentdrivervector.f90 sourcefile~griddedcomponentdriver.f90->sourcefile~multistate.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

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~componentspecparser.f90 ComponentSpecParser.F90 sourcefile~componentspecparser.f90->sourcefile~reexportconnection.f90 sourcefile~componentspecparser.f90->sourcefile~stateregistry.f90 sourcefile~configurablegridcomp.f90 ConfigurableGridComp.F90 sourcefile~configurablegridcomp.f90->sourcefile~mapl_generic.f90~2 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~parse_geometry_spec.f90 parse_geometry_spec.F90 sourcefile~parse_geometry_spec.f90->sourcefile~modelverticalgrid.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~test_configurablegridcomp.pf Test_ConfigurableGridComp.pf sourcefile~test_configurablegridcomp.pf->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_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

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_StateItemAspect
   use mapl3g_StateItemExtension
   use mapl3g_StateItemExtensionPtrVector
   use mapl_ErrorHandling
   use gFTL2_StringVector
   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 :: merge

      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
      logical :: match
      type(StringVector), target :: aspect_names
      character(:), pointer :: aspect_name
      class(StateItemAspect), pointer :: src_aspect, dst_aspect

      closest_extension => null()
      subgroup = family%get_extensions()
      primary => family%get_primary()  ! archetype defines the rules
      archetype => primary%get_spec()
      ! new
      aspect_names = archetype%get_aspect_order(goal_spec)
      do i = 1, aspect_names%size()
         aspect_name => aspect_names%of(i)
         dst_aspect => goal_spec%get_aspect(aspect_name, _RC)
         _ASSERT(associated(dst_aspect), 'expected aspect '//aspect_name//' is missing')

         ! Find subset that match current aspect
         new_subgroup = StateItemExtensionPtrVector()
         do j = 1, subgroup%size()
            extension_ptr = subgroup%of(j)
            spec => extension_ptr%ptr%get_spec()

            src_aspect => spec%get_aspect(aspect_name, _RC)
            _ASSERT(associated(src_aspect),'aspect '// aspect_name// ' not found')

            if (src_aspect%needs_extension_for(dst_aspect)) cycle
            call new_subgroup%push_back(extension_ptr)

         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

   subroutine merge(this, other)
      class(ExtensionFamily), target, intent(inout) :: this
      type(ExtensionFamily), target, intent(in) :: other

      integer :: i, j
      type(StateItemExtensionPtr) :: extension, other_extension

      outer: do i = 1, other%num_variants()
         other_extension = other%extensions%of(i)

         do j = 1, this%num_variants()
            extension = this%extensions%of(j)
            if (associated(extension%ptr, other_extension%ptr)) cycle outer
         end do
         call this%extensions%push_back(other_extension)
         
      end do outer
      this%has_primary_ = other%has_primary_

   end subroutine merge
   
end module mapl3g_ExtensionFamily