SimpleConnection.F90 Source File


This file depends on

sourcefile~~simpleconnection.f90~~EfferentGraph sourcefile~simpleconnection.f90 SimpleConnection.F90 sourcefile~actualconnectionpt.f90 ActualConnectionPt.F90 sourcefile~simpleconnection.f90->sourcefile~actualconnectionpt.f90 sourcefile~actualptvec_map.f90 ActualPtVec_Map.F90 sourcefile~simpleconnection.f90->sourcefile~actualptvec_map.f90 sourcefile~actualptvector.f90 ActualPtVector.F90 sourcefile~simpleconnection.f90->sourcefile~actualptvector.f90 sourcefile~connection.f90 Connection.F90 sourcefile~simpleconnection.f90->sourcefile~connection.f90 sourcefile~connectionpt.f90 ConnectionPt.F90 sourcefile~simpleconnection.f90->sourcefile~connectionpt.f90 sourcefile~errorhandling.f90 ErrorHandling.F90 sourcefile~simpleconnection.f90->sourcefile~errorhandling.f90 sourcefile~griddedcomponentdriver.f90 GriddedComponentDriver.F90 sourcefile~simpleconnection.f90->sourcefile~griddedcomponentdriver.f90 sourcefile~keywordenforcer.f90 KeywordEnforcer.F90 sourcefile~simpleconnection.f90->sourcefile~keywordenforcer.f90 sourcefile~multistate.f90 MultiState.F90 sourcefile~simpleconnection.f90->sourcefile~multistate.f90 sourcefile~stateitemextension.f90 StateItemExtension.F90 sourcefile~simpleconnection.f90->sourcefile~stateitemextension.f90 sourcefile~stateitemextensionptrvector.f90 StateItemExtensionPtrVector.F90 sourcefile~simpleconnection.f90->sourcefile~stateitemextensionptrvector.f90 sourcefile~stateitemextensionvector.f90 StateItemExtensionVector.F90 sourcefile~simpleconnection.f90->sourcefile~stateitemextensionvector.f90 sourcefile~stateitemspec.f90 StateItemSpec.F90 sourcefile~simpleconnection.f90->sourcefile~stateitemspec.f90 sourcefile~stateregistry.f90 StateRegistry.F90 sourcefile~simpleconnection.f90->sourcefile~stateregistry.f90 sourcefile~virtualconnectionpt.f90 VirtualConnectionPt.F90 sourcefile~simpleconnection.f90->sourcefile~virtualconnectionpt.f90 sourcefile~actualconnectionpt.f90->sourcefile~keywordenforcer.f90 sourcefile~actualconnectionpt.f90->sourcefile~virtualconnectionpt.f90 sourcefile~actualptvec_map.f90->sourcefile~actualptvector.f90 sourcefile~actualptvec_map.f90->sourcefile~virtualconnectionpt.f90 sourcefile~actualptvector.f90->sourcefile~actualconnectionpt.f90 sourcefile~connectionpt.f90->sourcefile~virtualconnectionpt.f90 sourcefile~mapl_throw.f90 MAPL_Throw.F90 sourcefile~errorhandling.f90->sourcefile~mapl_throw.f90 sourcefile~griddedcomponentdriver.f90->sourcefile~errorhandling.f90 sourcefile~griddedcomponentdriver.f90->sourcefile~keywordenforcer.f90 sourcefile~griddedcomponentdriver.f90->sourcefile~multistate.f90 sourcefile~componentdriver.f90 ComponentDriver.F90 sourcefile~griddedcomponentdriver.f90->sourcefile~componentdriver.f90 sourcefile~componentdrivervector.f90 ComponentDriverVector.F90 sourcefile~griddedcomponentdriver.f90->sourcefile~componentdrivervector.f90 sourcefile~multistate.f90->sourcefile~errorhandling.f90 sourcefile~multistate.f90->sourcefile~keywordenforcer.f90 sourcefile~esmf_utilities.f90 ESMF_Utilities.F90 sourcefile~multistate.f90->sourcefile~esmf_utilities.f90 sourcefile~stateitemextension.f90->sourcefile~errorhandling.f90 sourcefile~stateitemextension.f90->sourcefile~griddedcomponentdriver.f90 sourcefile~stateitemextension.f90->sourcefile~multistate.f90 sourcefile~stateitemextension.f90->sourcefile~stateitemspec.f90 sourcefile~stateitemextension.f90->sourcefile~componentdriver.f90 sourcefile~componentdriverptrvector.f90 ComponentDriverPtrVector.F90 sourcefile~stateitemextension.f90->sourcefile~componentdriverptrvector.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~nullaction.f90 NullAction.F90 sourcefile~stateitemextension.f90->sourcefile~nullaction.f90 sourcefile~stateitemextensionptrvector.f90->sourcefile~stateitemextension.f90 sourcefile~stateitemextensionvector.f90->sourcefile~stateitemextension.f90 sourcefile~stateitemspec.f90->sourcefile~actualptvector.f90 sourcefile~stateitemspec.f90->sourcefile~errorhandling.f90 sourcefile~stateregistry.f90->sourcefile~actualconnectionpt.f90 sourcefile~stateregistry.f90->sourcefile~connectionpt.f90 sourcefile~stateregistry.f90->sourcefile~errorhandling.f90 sourcefile~stateregistry.f90->sourcefile~griddedcomponentdriver.f90 sourcefile~stateregistry.f90->sourcefile~multistate.f90 sourcefile~stateregistry.f90->sourcefile~stateitemextension.f90 sourcefile~stateregistry.f90->sourcefile~stateitemextensionptrvector.f90 sourcefile~stateregistry.f90->sourcefile~stateitemextensionvector.f90 sourcefile~stateregistry.f90->sourcefile~stateitemspec.f90 sourcefile~stateregistry.f90->sourcefile~virtualconnectionpt.f90 sourcefile~abstractregistry.f90 AbstractRegistry.F90 sourcefile~stateregistry.f90->sourcefile~abstractregistry.f90 sourcefile~stateregistry.f90->sourcefile~componentdriver.f90 sourcefile~stateregistry.f90->sourcefile~componentdriverptrvector.f90 sourcefile~stateregistry.f90->sourcefile~componentdrivervector.f90 sourcefile~extensionfamily.f90 ExtensionFamily.F90 sourcefile~stateregistry.f90->sourcefile~extensionfamily.f90 sourcefile~registryptr.f90 RegistryPtr.F90 sourcefile~stateregistry.f90->sourcefile~registryptr.f90 sourcefile~registryptrmap.f90 RegistryPtrMap.F90 sourcefile~stateregistry.f90->sourcefile~registryptrmap.f90 sourcefile~stateitemvector.f90 StateItemVector.F90 sourcefile~stateregistry.f90->sourcefile~stateitemvector.f90 sourcefile~verticalgrid.f90 VerticalGrid.F90 sourcefile~stateregistry.f90->sourcefile~verticalgrid.f90 sourcefile~virtualconnectionptvector.f90 VirtualConnectionPtVector.F90 sourcefile~stateregistry.f90->sourcefile~virtualconnectionptvector.f90 sourcefile~virtualptfamilymap.f90 VirtualPtFamilyMap.F90 sourcefile~stateregistry.f90->sourcefile~virtualptfamilymap.f90 sourcefile~virtualconnectionpt.f90->sourcefile~keywordenforcer.f90

Files dependent on this one

sourcefile~~simpleconnection.f90~~AfferentGraph sourcefile~simpleconnection.f90 SimpleConnection.F90 sourcefile~componentspecparser.f90 ComponentSpecParser.F90 sourcefile~componentspecparser.f90->sourcefile~simpleconnection.f90 sourcefile~matchconnection.f90 MatchConnection.F90 sourcefile~componentspecparser.f90->sourcefile~matchconnection.f90 sourcefile~matchconnection.f90->sourcefile~simpleconnection.f90 sourcefile~protoextdatagc.f90 ProtoExtDataGC.F90 sourcefile~protoextdatagc.f90->sourcefile~simpleconnection.f90 sourcefile~test_stateregistry.pf Test_StateRegistry.pf sourcefile~test_stateregistry.pf->sourcefile~simpleconnection.f90 sourcefile~add_child_by_name.f90 add_child_by_name.F90 sourcefile~add_child_by_name.f90->sourcefile~componentspecparser.f90 sourcefile~outermetacomponent.f90 OuterMetaComponent.F90 sourcefile~outermetacomponent.f90->sourcefile~matchconnection.f90 sourcefile~parse_child.f90 parse_child.F90 sourcefile~parse_child.f90->sourcefile~componentspecparser.f90 sourcefile~parse_children.f90 parse_children.F90 sourcefile~parse_children.f90->sourcefile~componentspecparser.f90 sourcefile~parse_component_spec.f90 parse_component_spec.F90 sourcefile~parse_component_spec.f90->sourcefile~componentspecparser.f90 sourcefile~parse_connections.f90 parse_connections.F90 sourcefile~parse_connections.f90->sourcefile~componentspecparser.f90 sourcefile~parse_geometry_spec.f90 parse_geometry_spec.F90 sourcefile~parse_geometry_spec.f90->sourcefile~componentspecparser.f90 sourcefile~parse_setservices.f90 parse_setservices.F90 sourcefile~parse_setservices.f90->sourcefile~componentspecparser.f90 sourcefile~parse_var_specs.f90 parse_var_specs.F90 sourcefile~parse_var_specs.f90->sourcefile~componentspecparser.f90 sourcefile~setservices.f90 SetServices.F90 sourcefile~setservices.f90->sourcefile~componentspecparser.f90 sourcefile~test_componentspecparser.pf Test_ComponentSpecParser.pf sourcefile~test_componentspecparser.pf->sourcefile~componentspecparser.f90

Source Code

#include "MAPL_Generic.h"

module mapl3g_SimpleConnection
   use mapl3g_StateItemSpec
   use mapl3g_Connection
   use mapl3g_ConnectionPt
   use mapl3g_StateRegistry
   use mapl3g_VirtualConnectionPt
   use mapl3g_ActualConnectionPt
   use mapl3g_ActualPtVec_Map
   use mapl3g_ActualPtVector
   use mapl3g_GriddedComponentDriver
   use mapl3g_StateItemExtension
   use mapl3g_StateItemExtensionVector
   use mapl3g_StateItemExtensionPtrVector
   use mapl3g_MultiState
   use mapl_KeywordEnforcer
   use mapl_ErrorHandling
   use gFTL2_StringVector, only: StringVector
   use esmf

   implicit none
   private

   public :: SimpleConnection

   type, extends(Connection) :: SimpleConnection
      private
      type(ConnectionPt) :: source
      type(ConnectionPt) :: destination
   contains
      procedure :: get_source
      procedure :: get_destination
      procedure :: activate
      procedure :: connect
      procedure :: connect_sibling
   end type SimpleConnection

   interface SimpleConnection
      module procedure :: new_SimpleConnection
   end interface SimpleConnection

contains

   function new_SimpleConnection(source, destination) result(this)
      type(SimpleConnection) :: this
      type(ConnectionPt), intent(in) :: source
      type(ConnectionPt), intent(in) :: destination

      this%source = source
      this%destination = destination

   end function new_SimpleConnection

   function get_source(this) result(source)
      type(ConnectionPt) :: source
      class(SimpleConnection), intent(in) :: this
      source = this%source
   end function get_source

   function get_destination(this) result(destination)
      type(ConnectionPt) :: destination
      class(SimpleConnection), intent(in) :: this
      destination = this%destination
   end function get_destination

   recursive subroutine activate(this, registry, rc)
      class(SimpleConnection), intent(in) :: this
      type(StateRegistry), target, intent(inout) :: registry
      integer, optional, intent(out) :: rc

      type(StateRegistry), pointer :: src_registry, dst_registry
      type(ConnectionPt) :: src_pt, dst_pt
      type(StateItemExtensionPtr), target, allocatable :: src_extensions(:), dst_extensions(:)
      type(StateItemExtension), pointer :: src_extension, dst_extension
      class(StateItemSpec), pointer :: spec
      integer :: i
      integer :: status

      src_pt = this%get_source()
      dst_pt = this%get_destination()

      dst_registry => registry%get_subregistry(dst_pt)
      src_registry => registry%get_subregistry(src_pt)
        
      _ASSERT(associated(src_registry), 'Unknown source registry')
      _ASSERT(associated(dst_registry), 'Unknown destination registry')
        
      dst_extensions = dst_registry%get_extensions(dst_pt%v_pt, _RC)
      src_extensions = src_registry%get_extensions(src_pt%v_pt, _RC)

      do i = 1, size(dst_extensions)
         dst_extension => dst_extensions(i)%ptr
         spec => dst_extension%get_spec()
         call spec%set_active()
      end do

      do i = 1, size(src_extensions)
         src_extension => src_extensions(i)%ptr
         spec => src_extension%get_spec()
         call spec%set_active()
         call activate_dependencies(src_extension, src_registry, _RC)
      end do
        
      _RETURN(_SUCCESS)
   end subroutine activate


   recursive subroutine connect(this, registry, rc)
      class(SimpleConnection), intent(in) :: this
      type(StateRegistry), target, intent(inout) :: registry
      integer, optional, intent(out) :: rc

      type(StateRegistry), pointer :: src_registry, dst_registry
      type(ConnectionPt) :: src_pt, dst_pt
      integer :: status

      src_pt = this%get_source()
      dst_pt = this%get_destination()

      dst_registry => registry%get_subregistry(dst_pt)
      src_registry => registry%get_subregistry(src_pt)
        
      _ASSERT(associated(src_registry), 'Unknown source registry')
      _ASSERT(associated(dst_registry), 'Unknown destination registry')
        
      call this%connect_sibling(dst_registry, src_registry, _RC)
        
      _RETURN(_SUCCESS)
   end subroutine connect


   recursive subroutine connect_sibling(this, dst_registry, src_registry, unusable, rc)
      class(SimpleConnection), intent(in) :: this
      type(StateRegistry), target, intent(inout) :: dst_registry
      type(StateRegistry), target, intent(inout) :: src_registry
      class(KeywordEnforcer), optional, intent(in) :: unusable
      integer, optional, intent(out) :: rc


      type(StateItemExtensionPtr), target, allocatable :: src_extensions(:), dst_extensions(:)
      type(StateItemExtension), pointer :: src_extension, dst_extension
      class(StateItemSpec), pointer :: src_spec, dst_spec
      integer :: i
      integer :: status
      type(ConnectionPt) :: src_pt, dst_pt
      integer :: i_extension
      integer :: lowest_cost
      type(StateItemExtension), pointer :: best_extension
      type(StateItemExtension), pointer :: last_extension
      type(StateItemExtension) :: extension
      type(StateItemExtension), pointer :: new_extension
      class(StateItemSpec), pointer :: last_spec
      class(StateItemSpec), pointer :: new_spec
      class(StateItemSpec), pointer :: best_spec
      type(ActualConnectionPt) :: effective_pt

      type(GriddedComponentDriver), pointer :: coupler
      type(ActualConnectionPt) :: a_pt
      type(MultiState) :: coupler_states

      src_pt = this%get_source()
      dst_pt = this%get_destination()

      dst_extensions = dst_registry%get_extensions(dst_pt%v_pt, _RC)

      do i = 1, size(dst_extensions)
         dst_extension => dst_extensions(i)%ptr
         dst_spec => dst_extension%get_spec()

         last_extension => src_registry%extend(src_pt%v_pt, dst_spec, _RC)

!#         src_extensions = src_registry%get_extensions(src_pt%v_pt, _RC)
!#
!#
!#         ! Connection is transitive -- if any src_specs can connect, all can connect.
!#         ! So we can just check this property on the 1st item.
!#         src_extension => src_extensions(1)%ptr
!#         src_spec => src_extension%get_spec()
!#         if (.not. dst_spec%can_connect_to(src_spec)) then
!#            _HERE, 'cannot connect: ', src_pt%v_pt, ' --> ', dst_pt%v_pt
!#         end if
!#
!#         call find_closest_extension(dst_extension, src_extensions, closest_extension=best_extension, lowest_cost=lowest_cost, _RC)
!#         best_spec => best_extension%get_spec()
!#         call best_spec%set_active()
!#
!#         last_extension => best_extension
!#
!#
!#         do i_extension = 1, lowest_cost
!#
!#            extension = last_extension%make_extension(dst_spec, _RC)
!#                 
!#            new_extension => src_registry%add_extension(src_pt%v_pt, extension, _RC)
!#            coupler => new_extension%get_producer()
!#
!#            ! WARNING TO FUTURE DEVELOPERS: There may be issues if
!#            ! some spec needs to be a bit different in import and
!#            ! export roles.  Here we use "last_extension" as an export
!#            ! of src and an import of coupler.
!#            coupler_states = coupler%get_states()
!#            a_pt = ActualConnectionPt(VirtualConnectionPt(state_intent='import', short_name='import[1]'))
!#            last_spec => last_extension%get_spec()
!#            call last_spec%add_to_state(coupler_states, a_pt, _RC)
!#            a_pt = ActualConnectionPt(VirtualConnectionPt(state_intent='export', short_name='export[1]'))
!#            new_spec => new_extension%get_spec()
!#            call new_spec%add_to_state(coupler_states, a_pt, _RC)
!#            
!#            call last_extension%add_consumer(coupler)
!#            last_extension => new_extension
!#         end do

         ! In the case of wildcard specs, we need to pass an actual_pt to
         ! the dst_spec to support multiple matches.  A bit of a kludge.
         effective_pt = ActualConnectionPt(VirtualConnectionPt(ESMF_STATEINTENT_IMPORT, &
              src_pt%v_pt%get_comp_name()//'/'//src_pt%v_pt%get_esmf_name()))
         last_spec => last_extension%get_spec()
         call dst_spec%connect_to(last_spec, effective_pt, _RC)
         call dst_spec%set_active()
            
      end do
         
      _RETURN(_SUCCESS)
      _UNUSED_DUMMY(unusable)
   end subroutine connect_sibling

   ! This activates _within_ the user gridcomp.   Some exports may require
   ! other exports to be computed even when no external connection is made to those
   ! exports.
   subroutine activate_dependencies(extension, registry, rc)
      type(StateItemExtension), intent(in) :: extension
      type(StateRegistry), target, intent(in) :: registry
      integer, optional, intent(out) :: rc

      integer :: status
      integer :: i
      type(StringVector) :: dependencies
      class(StateItemExtension), pointer :: dep_extension
      class(StateItemSpec), pointer :: spec
      class(StateItemSpec), pointer :: dep_spec

      spec => extension%get_spec()
      dependencies = spec%get_raw_dependencies()
      do i = 1, dependencies%size()
         associate (v_pt => VirtualConnectionPt(state_intent='export', short_name=dependencies%of(i)) )
           dep_extension => registry%get_primary_extension(v_pt, _RC)
         end associate
         dep_spec => dep_extension%get_spec()
         call dep_spec%set_active()
      end do

      _RETURN(_SUCCESS)
   end subroutine activate_dependencies

   subroutine find_closest_extension(goal_extension, candidate_extensions, closest_extension, lowest_cost, rc)
      type(StateItemExtension), intent(in) :: goal_extension
      type(StateItemExtensionPtr), target, intent(in) :: candidate_extensions(:)
      type(StateItemExtension), pointer :: closest_extension
      integer, intent(out) :: lowest_cost
      integer, optional, intent(out) :: rc

      integer :: status
      type(StateItemExtension), pointer :: extension
      class(StateItemSpec), pointer :: spec
      class(StateItemSpec), pointer :: goal_spec
      integer :: cost
      integer :: j
      
      _ASSERT(size(candidate_extensions) > 0, 'no candidates found')

      goal_spec => goal_extension%get_spec()
      closest_extension => candidate_extensions(1)%ptr
      spec => closest_extension%get_spec()
      lowest_cost = goal_spec%extension_cost(spec, _RC)
      do j = 2, size(candidate_extensions)
         if (lowest_cost == 0) exit

         extension => candidate_extensions(j)%ptr
         spec => extension%get_spec()
         cost = goal_spec%extension_cost(spec)
         if (cost < lowest_cost) then
            lowest_cost = cost
            closest_extension => extension
         end if

      end do

   end subroutine find_closest_extension

end module mapl3g_SimpleConnection