Beeman

Beeman’s algorithm is one of the simplest which allows a predictor-corrector implementation, and demonstrates an algorithm, including a self-consistent loop within one propagator time-step. The self-contistent predictor-corrector feature is implemented as optional.

For the Beeman propagator, we need to define the following operations:


  ! Specific beeman propagation operations identifiers
  character(len=ALGO_LABEL_LEN), public, parameter ::  &
    BEEMAN_START       = 'BEEMAN_START',               &
    BEEMAN_FINISH      = 'BEEMAN_FINISH',              &
    BEEMAN_COMPUTE_ACC = 'BEEMAN_COMPUTE_ACC',         &
    BEEMAN_PREDICT_POS = 'BEEMAN_PREDICT_POS',         &
    BEEMAN_PREDICT_VEL = 'BEEMAN_PREDICT_VEL',         &
    BEEMAN_CORRECT_POS = 'BEEMAN_CORRECT_POS',         &
    BEEMAN_CORRECT_VEL = 'BEEMAN_CORRECT_VEL'

  ! Specific beeman propagation operations
  type(algorithmic_operation_t), public, parameter :: &
    OP_BEEMAN_START       = algorithmic_operation_t(BEEMAN_START,       'Starting Beeman propagation'),               &
    OP_BEEMAN_FINISH      = algorithmic_operation_t(BEEMAN_FINISH,      'Finishing Beeman propagation'),              &
    OP_BEEMAN_COMPUTE_ACC = algorithmic_operation_t(BEEMAN_COMPUTE_ACC, 'Propagation step - Computing acceleration'), &
    OP_BEEMAN_PREDICT_POS = algorithmic_operation_t(BEEMAN_PREDICT_POS, 'Prediction step  - Computing position'),     &
    OP_BEEMAN_PREDICT_VEL = algorithmic_operation_t(BEEMAN_PREDICT_VEL, 'Prediction step  - Computing velocity'),     &
    OP_BEEMAN_CORRECT_POS = algorithmic_operation_t(BEEMAN_CORRECT_POS, 'Correction step  - Computing position'),     &
    OP_BEEMAN_CORRECT_VEL = algorithmic_operation_t(BEEMAN_CORRECT_VEL, 'Correction step  - Computing velocity')

These are used to define the algorithm, which is done in the constructor of the propagator:

  function propagator_beeman_constructor(dt, predictor_corrector) result(this)
    FLOAT,               intent(in)    :: dt
    logical,             intent(in)    :: predictor_corrector
    type(propagator_beeman_t), pointer :: this

    PUSH_SUB(propagator_beeman_constructor)

    SAFE_ALLOCATE(this)

    this%predictor_corrector = predictor_corrector

    this%start_step = OP_BEEMAN_START
    this%final_step = OP_BEEMAN_FINISH

    if (predictor_corrector) then

      call this%add_operation(OP_STORE_CURRENT_STATUS)
      call this%add_operation(OP_BEEMAN_PREDICT_POS)
      call this%add_operation(OP_START_SCF_LOOP)
      call this%add_operation(OP_UPDATE_INTERACTIONS)
      call this%add_operation(OP_BEEMAN_COMPUTE_ACC)
      call this%add_operation(OP_BEEMAN_CORRECT_POS)
      call this%add_operation(OP_BEEMAN_CORRECT_VEL)
      call this%add_operation(OP_END_SCF_LOOP)
      call this%add_operation(OP_FINISHED)

      this%max_scf_count = 2 !From Wikipedia
      this%scf_tol = CNST(1e-6) !At the moment arbitrary

    else

      call this%add_operation(OP_BEEMAN_PREDICT_POS)
      call this%add_operation(OP_UPDATE_INTERACTIONS)
      call this%add_operation(OP_BEEMAN_COMPUTE_ACC)
      call this%add_operation(OP_BEEMAN_PREDICT_VEL)
      call this%add_operation(OP_FINISHED)

    end if

    ! Beeman has only one algorithmic step
    this%algo_steps = 1

    this%dt = dt

    POP_SUB(propagator_beeman_constructor)
  end function propagator_beeman_constructor

The timeline explained


This graph illustrates how the state machine is stepping through the algorithm. Each system is picking the next algorithmic step from the propagator. For the containers (i.e. ‘‘root’’ and ‘‘earth’'), the only steps are ‘‘Updating interactions’’ and ‘‘Finished’’. The real systems, on the other hand, are progressing orderly through the operations, defined in the propagator.

Example with different time steps