Cap.F90 Source File


This file depends on

sourcefile~~cap.f90~~EfferentGraph sourcefile~cap.f90 Cap.F90 sourcefile~applicationsupport.f90 ApplicationSupport.F90 sourcefile~cap.f90->sourcefile~applicationsupport.f90 sourcefile~capgridcomp.f90 CapGridComp.F90 sourcefile~cap.f90->sourcefile~capgridcomp.f90 sourcefile~errorhandling.f90 ErrorHandling.F90 sourcefile~cap.f90->sourcefile~errorhandling.f90 sourcefile~generic3g.f90 Generic3g.F90 sourcefile~cap.f90->sourcefile~generic3g.f90 sourcefile~genericgridcomp.f90 GenericGridComp.F90 sourcefile~cap.f90->sourcefile~genericgridcomp.f90 sourcefile~keywordenforcer.f90 KeywordEnforcer.F90 sourcefile~cap.f90->sourcefile~keywordenforcer.f90 sourcefile~multistate.f90 MultiState.F90 sourcefile~cap.f90->sourcefile~multistate.f90 sourcefile~timestringconversion.f90 TimeStringConversion.F90 sourcefile~cap.f90->sourcefile~timestringconversion.f90 sourcefile~applicationsupport.f90->sourcefile~errorhandling.f90 sourcefile~applicationsupport.f90->sourcefile~keywordenforcer.f90 sourcefile~mapl_profiler.f90~2 MAPL_Profiler.F90 sourcefile~applicationsupport.f90->sourcefile~mapl_profiler.f90~2 sourcefile~pflogger_stub.f90 pflogger_stub.F90 sourcefile~applicationsupport.f90->sourcefile~pflogger_stub.f90 sourcefile~simulationtime.f90 SimulationTime.F90 sourcefile~applicationsupport.f90->sourcefile~simulationtime.f90 sourcefile~capgridcomp.f90->sourcefile~errorhandling.f90 sourcefile~capgridcomp.f90->sourcefile~generic3g.f90 sourcefile~mapl_throw.f90 MAPL_Throw.F90 sourcefile~errorhandling.f90->sourcefile~mapl_throw.f90 sourcefile~generic3g.f90->sourcefile~genericgridcomp.f90 sourcefile~componentdriver.f90 ComponentDriver.F90 sourcefile~generic3g.f90->sourcefile~componentdriver.f90 sourcefile~esmf_hconfigutilities.f90 ESMF_HConfigUtilities.F90 sourcefile~generic3g.f90->sourcefile~esmf_hconfigutilities.f90 sourcefile~esmf_interfaces.f90 ESMF_Interfaces.F90 sourcefile~generic3g.f90->sourcefile~esmf_interfaces.f90 sourcefile~griddedcomponentdriver.f90 GriddedComponentDriver.F90 sourcefile~generic3g.f90->sourcefile~griddedcomponentdriver.f90 sourcefile~mapl_generic.f90 MAPL_Generic.F90 sourcefile~generic3g.f90->sourcefile~mapl_generic.f90 sourcefile~outermetacomponent.f90 OuterMetaComponent.F90 sourcefile~generic3g.f90->sourcefile~outermetacomponent.f90 sourcefile~usersetservices.f90 UserSetServices.F90 sourcefile~generic3g.f90->sourcefile~usersetservices.f90 sourcefile~verticaldimspec.f90 VerticalDimSpec.F90 sourcefile~generic3g.f90->sourcefile~verticaldimspec.f90 sourcefile~verticalgrid.f90 VerticalGrid.F90 sourcefile~generic3g.f90->sourcefile~verticalgrid.f90 sourcefile~genericgridcomp.f90->sourcefile~errorhandling.f90 sourcefile~genericgridcomp.f90->sourcefile~keywordenforcer.f90 sourcefile~genericgridcomp.f90->sourcefile~multistate.f90 sourcefile~genericgridcomp.f90->sourcefile~griddedcomponentdriver.f90 sourcefile~genericgridcomp.f90->sourcefile~outermetacomponent.f90 sourcefile~genericgridcomp.f90->sourcefile~usersetservices.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~timestringconversion.f90->sourcefile~keywordenforcer.f90 sourcefile~mapl_exceptionhandling.f90 MAPL_ExceptionHandling.F90 sourcefile~timestringconversion.f90->sourcefile~mapl_exceptionhandling.f90

Files dependent on this one

sourcefile~~cap.f90~~AfferentGraph sourcefile~cap.f90 Cap.F90 sourcefile~mapl3g.f90 mapl3g.F90 sourcefile~mapl3g.f90->sourcefile~cap.f90 sourcefile~geos.f90 GEOS.F90 sourcefile~geos.f90->sourcefile~mapl3g.f90

Source Code

#include "MAPL_Generic.h"

module mapl3g_Cap
   use mapl3g_CapGridComp, only: cap_setservices => setServices
   use generic3g
   use mapl3g_GenericPhases
   use mapl3g_MultiState
   use mapl_KeywordEnforcerMod
   use mapl_ErrorHandling
   use esmf
   use MAPL_TimeStringConversion, only: hconfig_to_esmf_timeinterval
   implicit none
   private

   public :: MAPL_run_driver

contains


   subroutine MAPL_run_driver(hconfig, is_model_pet, unusable, servers, rc)
      USE MAPL_ApplicationSupport
      type(ESMF_HConfig), intent(inout) :: hconfig
      logical, intent(in) :: is_model_pet
      class(KeywordEnforcer), optional, intent(in) :: unusable
      type(ESMF_GridComp), optional, intent(in) :: servers(:)
      integer, optional, intent(out) :: rc

      type(GriddedComponentDriver) :: driver
      integer :: status

      driver = make_driver(hconfig, is_model_pet, _RC)

      if (is_model_pet) then
         call initialize_phases(driver, phases=GENERIC_INIT_PHASE_SEQUENCE, _RC)
         call driver%read_restart(_RC)
         call integrate(driver, _RC)
         call driver%write_restart(_RC)
         call driver%finalize(_RC)
      end if

      _RETURN(_SUCCESS)
      _UNUSED_DUMMY(unusable)
   end subroutine MAPL_run_driver

   function make_driver(hconfig, is_model_pet, rc) result(driver)
      use mapl3g_GenericGridComp, only: generic_SetServices => setServices
      type(GriddedComponentDriver) :: driver
      type(ESMF_HConfig), intent(inout) :: hconfig
      logical, intent(in) :: is_model_pet
      integer, optional, intent(out) :: rc

      type(ESMF_GridComp) :: cap_gridcomp
      type(ESMF_Clock) :: clock
      character(:), allocatable :: cap_name
      integer :: status, user_status
      type(ESMF_HConfig) :: cap_gc_hconfig
      integer, allocatable :: petList(:)

      cap_name = ESMF_HConfigAsString(hconfig, keystring='name', _RC)
      clock = create_clock(hconfig, _RC)

      cap_gc_hconfig = ESMF_HConfigCreateAt(hconfig, keystring='cap_gc', _RC)
      petList = get_model_pets(is_model_pet, _RC)
      cap_gridcomp = create_grid_comp(cap_name, user_setservices(cap_setservices), cap_gc_hconfig, clock, petList=petList, _RC)

      call ESMF_GridCompSetServices(cap_gridcomp, generic_setServices, userRC=user_status, _RC)
      _VERIFY(user_status)

      driver = GriddedComponentDriver(cap_gridcomp, clock, MultiState())

      _RETURN(_SUCCESS)
   end function make_driver

   ! Create function that accepts a logical flag returns list of mpi processes that have .true..
   function get_model_pets(flag, rc) result(petList)
      use mpi
      integer, allocatable :: petList(:)
      logical, intent(in) :: flag
      integer, optional, intent(out) :: rc

      integer :: status
      type(ESMF_VM) :: vm
      logical, allocatable, target :: flags(:)
      integer :: world_comm
      integer :: i, petCount
      
      call ESMF_VMGetCurrent(vm, _RC)
      call ESMF_VMGet(vm, petCount=petCount, mpiCommunicator=world_comm, _RC)
      allocate(flags(petCount))
      call MPI_Allgather(flag, 1, MPI_LOGICAL, flags, 1, MPI_LOGICAL, world_comm, status)
      _VERIFY(status)
      petList = pack([(i, i=0,petCount-1)], flags)

      _RETURN(_SUCCESS)
   end function get_model_pets

   function create_clock(hconfig, rc) result(clock)
      type(ESMF_Clock) :: clock
      type(ESMF_HConfig), intent(in) :: hconfig
      integer, optional, intent(out) :: rc

      integer :: status
      type(ESMF_Time) :: startTime, stopTime, end_of_segment
      type(ESMF_TimeInterval) :: timeStep, segment_duration
      type(ESMF_HConfig) :: clock_config
      
      clock_config = ESMF_HConfigCreateAt(hconfig, keystring='clock', _RC)

      call ESMF_CalendarSetDefault(ESMF_CALKIND_GREGORIAN,_RC)
      call set_time(startTime, 'start', clock_config, _RC)
      call ESMF_TimePrint(startTime, options='string', prestring='start time set: ' ,_RC)
      call set_time(stopTime, 'stop', clock_config, _RC)
      call ESMF_TimePrint(stopTime, options='string', prestring='stop time set: ', _RC)
      timeStep = hconfig_to_esmf_timeinterval(clock_config, 'dt', _RC)
      segment_duration = hconfig_to_esmf_timeinterval(clock_config, 'segment_duration', _RC)

      end_of_segment = startTime + segment_duration
      if (end_of_segment < stopTime) stopTime = end_of_segment
      call ESMF_TimePrint(stopTime, options='string', prestring='actual stop time set: ', _RC)
      clock = ESMF_ClockCreate(timeStep=timeStep, startTime=startTime, stopTime=stopTime, _RC)
      
      _RETURN(_SUCCESS)
   end function create_clock

   subroutine set_time(time, key, hconfig, rc)
      type(ESMF_Time), intent(out) :: time
      character(*), intent(in) :: key
      type(ESMF_HConfig), intent(in) :: hconfig
      integer, optional, intent(out) :: rc
      
      integer :: status
      character(:), allocatable :: iso_time
      
      iso_time = ESMF_HConfigAsString(hconfig, keystring=key, _RC)
      call ESMF_TimeSet(time, timeString=iso_time, _RC)
      
      _RETURN(_SUCCESS)
   end subroutine set_time

   subroutine integrate(driver, rc)
      type(GriddedComponentDriver), intent(inout) :: driver
      integer, optional, intent(out) :: rc

      integer :: status
      type(ESMF_Clock) :: clock
      type(ESMF_Time) :: currTime, stopTime

      clock = driver%get_clock()
      call ESMF_ClockGet(clock, currTime=currTime, stopTime=stopTime, _RC)

      do while (currTime < stopTime)
         ! TODO:  include Bill's monitoring log messages here
         call driver%run(phase_idx=GENERIC_RUN_USER, _RC)
         call driver%run(phase_idx=GENERIC_RUN_CLOCK_ADVANCE, _RC)
         call driver%clock_advance(_RC)
         call ESMF_ClockGet(clock, currTime=currTime, _RC)
      end do
      call ESMF_TimePrint(currTime, options='string', preString='Cap time after loop: ', _RC)

      _RETURN(_SUCCESS)
      
   end subroutine integrate

end module mapl3g_Cap