autosave.f90 Source File


Source Code

#include "Includes.h"
module AutosaveClass
   use SMConstants
   use FTValueDictionaryClass
   use Utilities, only: almostEqual, toLower

   private
   public   Autosave_t, AUTOSAVE_BY_TIME, AUTOSAVE_BY_ITERATION, AUTOSAVE_UNDEFINED

   integer, parameter :: AUTOSAVE_UNDEFINED    = 0
   integer, parameter :: AUTOSAVE_BY_TIME      = 1
   integer, parameter :: AUTOSAVE_BY_ITERATION = 2

   type Autosave_t
      logical        :: performAutosave
      logical        :: enable
      integer        :: iter_interval
      real(kind=RP)  :: time_interval
      real(kind=RP)  :: nextAutosaveTime
      integer        :: mode
      contains
         procedure   :: Configure => Autosave_Configure
         procedure   :: Autosave  => Autosave_Autosave
   end type Autosave_t

   contains
!
!////////////////////////////////////////////////////////////////////////////////////
!
!     Autosave procedures
!     -------------------
!
!////////////////////////////////////////////////////////////////////////////////////
!
   subroutine Autosave_Configure(self, controlVariables, t0)
      implicit none
      class(Autosave_t)          :: self
      class(FTValueDictionary)   :: controlVariables
      real(kind=RP), intent(in)  :: t0
!
!     ---------------
!     Local variables
!     ---------------
!
      class(FTObject), pointer   :: obj
      character(len=LINE_LENGTH) :: autosaveMode
      character(len=LINE_LENGTH), parameter :: autosaveModeKey = "autosave mode"
      character(len=LINE_LENGTH), parameter :: autosaveIntervalKey = "autosave interval"
      character(len=LINE_LENGTH), parameter :: autosaveByIteration = "iteration"
      character(len=LINE_LENGTH), parameter :: autosaveByTime = "time"
!
!     Check whether the autosave mode is present
!     ------------------------------------------
      obj => controlVariables % objectForKey(trim(autosaveModeKey))

      if ( associated(obj) ) then
!
!        Present: associate the appropriate mode
!        ---------------------------------------
         autosaveMode = controlVariables % stringValueForKey(trim(autosaveModeKey), requestedLength = LINE_LENGTH)
         call ToLower(autosaveMode)

         if ( trim(autosaveMode) .eq. trim(autosaveByIteration) ) then
            self % mode = AUTOSAVE_BY_ITERATION

         elseif ( trim(autosaveMode) .eq. trim(autosaveByTime) ) then
            self % mode = AUTOSAVE_BY_TIME

         else
            print*, 'Unknown autosave mode "',trim(autosaveMode),'".'
            print*, "Implemented modes are:"
            print*, "   * iteration"
            print*, "   * time"
            errorMessage(STD_OUT)
            error stop
         end if
   
      else 
!
!        Not present: undefined. It can be determined with the interval data kind
!        ------------------------------------------------------------------------
         self % mode = AUTOSAVE_UNDEFINED
   
      end if
!
!     Check whether the autosave interval is present
!     ----------------------------------------------
      obj => controlVariables % objectForKey(trim(autosaveIntervalKey))

      if ( associated(obj) ) then
!
!        Present: assign to time/iter depending on the mode (see below for the undefined case)
!        --------------------------------------------------         
         select case ( self % mode )

         case (AUTOSAVE_BY_ITERATION)
            self % enable = .true.
            self % iter_interval = controlVariables % integerValueForKey(trim(autosaveIntervalKey))
            self % time_interval = huge(1.0_RP)
   
         case (AUTOSAVE_BY_TIME)
            self % enable = .true.
            self % time_interval = controlVariables % doublePrecisionValueForKey(trim(autosaveIntervalKey))
            self % iter_interval = huge(1)
         
         case (AUTOSAVE_UNDEFINED)
!
!           If time_interval is integer, autosave by iteration is selected. Otherwise, autosave by time
!           -------------------------------------------------------------------------------------------
            self % time_interval = controlVariables % doublePrecisionValueForKey(trim(autosaveIntervalKey))

            if ( almostEqual( self % time_interval, fraction(self % time_interval) ) ) then
               self % enable = .true.
               self % mode = AUTOSAVE_BY_ITERATION
               self % iter_interval = controlVariables % integerValueForKey(trim(autosaveIntervalKey))
               self % time_interval = huge(1.0_RP)

            else
               self % enable = .true.
               self % mode = AUTOSAVE_BY_TIME
               self % iter_interval = huge(1)

            end if

         end select

      else  
!
!        Not present: disable autosave
!        -----------------------------
         self % enable = .false.
         self % mode   = AUTOSAVE_UNDEFINED

      end if
!
!     Reset the last autosave time
!     ----------------------------
      self % nextAutosaveTime = t0 + self % time_interval
      self % performAutosave = .false.
         
   end subroutine Autosave_Configure

   logical function Autosave_Autosave(self,iter)
      class(Autosave_t),   intent(in)     :: self
      integer,             intent(in)     :: iter

      if ( .not. self % enable ) then
         Autosave_Autosave = .false.
         return
      end if

      select case ( self % mode )
      case (AUTOSAVE_BY_ITERATION)
         if ( mod(iter,self % iter_interval) .eq. 0 ) then
            Autosave_Autosave = .true.
         else
            Autosave_Autosave = .false.
         end if
   
      case (AUTOSAVE_BY_TIME)
         Autosave_Autosave = self % performAutosave
      
      end select
   end function Autosave_Autosave

end module AutosaveClass