SetServices.F90 Source File


This file depends on

sourcefile~~setservices.f90~~EfferentGraph sourcefile~setservices.f90 SetServices.F90 sourcefile~basicverticalgrid.f90 BasicVerticalGrid.F90 sourcefile~setservices.f90->sourcefile~basicverticalgrid.f90 sourcefile~childspec.f90 ChildSpec.F90 sourcefile~setservices.f90->sourcefile~childspec.f90 sourcefile~childspecmap.f90 ChildSpecMap.F90 sourcefile~setservices.f90->sourcefile~childspecmap.f90 sourcefile~componentspecparser.f90 ComponentSpecParser.F90 sourcefile~setservices.f90->sourcefile~componentspecparser.f90 sourcefile~genericgridcomp.f90 GenericGridComp.F90 sourcefile~setservices.f90->sourcefile~genericgridcomp.f90 sourcefile~griddedcomponentdrivermap.f90 GriddedComponentDriverMap.F90 sourcefile~setservices.f90->sourcefile~griddedcomponentdrivermap.f90 sourcefile~outermetacomponent.f90 OuterMetaComponent.F90 sourcefile~setservices.f90->sourcefile~outermetacomponent.f90

Source Code

#include "MAPL_Generic.h"

submodule (mapl3g_OuterMetaComponent) SetServices_smod
   use mapl3g_ComponentSpecParser
   use mapl3g_ChildSpec
   use mapl3g_ChildSpecMap
   use mapl3g_GenericGridComp
   use mapl3g_BasicVerticalGrid
   use mapl3g_GriddedComponentDriverMap
   implicit none

contains

   ! Note we spell the following routine with trailing underscore as a workaround
   ! for a bug in gfortran-12 that "leaks" private names into client code.
   !========================================================================
   ! Generic SetServices order of operations:
   !
   ! 1) Parse any generic aspects of the hconfig.
   ! 2) Add children from config
   ! 3) Create inner (user) gridcomp and call its setservices.
   !
   ! Note that specs are processed depth first, but that this may
   ! reverse when step (3) is moved to a new generic initialization phase.
   !=========================================================================
   
   recursive module subroutine SetServices_(this, rc)
      use mapl3g_GenericGridComp, only: generic_setservices => setservices
      class(OuterMetaComponent), intent(inout) :: this
      integer, intent(out) :: rc

      integer :: status
      type(ESMF_GridComp) :: user_gridcomp

      this%component_spec = parse_component_spec(this%hconfig, _RC)
      user_gridcomp = this%user_gc_driver%get_gridcomp()
      call attach_inner_meta(user_gridcomp, this%self_gridcomp, _RC)
      call this%user_setservices%run(user_gridcomp, _RC)
      call add_children(this, _RC)
      call run_children_setservices(this, _RC)

      _RETURN(ESMF_SUCCESS)

   contains

      recursive subroutine add_children(this, rc)
         class(OuterMetaComponent), target, intent(inout) :: this
         integer, optional, intent(out) :: rc
         
         integer :: status
         type(ChildSpecMapIterator) :: iter
         type(ChildSpec), pointer :: child_spec
         type(ESMF_HConfig), allocatable :: child_hconfig
         character(:), allocatable :: child_name

         associate ( e => this%component_spec%children%ftn_end() )
           iter = this%component_spec%children%ftn_begin()
           do while (iter /= e)
              call iter%next()
              child_name = iter%first()
              child_spec => iter%second()

              if (allocated(child_spec%config_file)) then
                 child_hconfig = ESMF_HConfigCreate(filename=child_spec%config_file, rc=status)
                 _ASSERT(status==0,'problem with config file: '//child_spec%config_file)
              end if
              call this%add_child(child_name, child_spec%user_setservices, child_hconfig, _RC)
           end do
         end associate

         _RETURN(_SUCCESS)
      end subroutine add_children

      ! By now children have either been added by specs or by direct
      ! calls in the parent gc's setservices.
      recursive subroutine run_children_setservices(this, rc)
         class(OuterMetaComponent), target, intent(inout) :: this
         integer, optional, intent(out) :: rc

         integer :: status
         type(GriddedComponentDriver), pointer :: child_comp
         type(ESMF_GridComp) :: child_outer_gc
         type(GriddedComponentDriverMapIterator) :: iter

          associate ( e => this%children%ftn_end() )
            iter = this%children%ftn_begin()
            do while (iter /= e)
               call iter%next()
               child_comp => iter%second()
               child_outer_gc = child_comp%get_gridcomp()
               call ESMF_GridCompSetServices(child_outer_gc, generic_setservices, _RC)
            end do
         end associate

         _RETURN(ESMF_SUCCESS)
      end subroutine run_children_setservices

   end subroutine SetServices_

end submodule SetServices_smod