In Octopus, many operations, such as time propagations, geometry optimization, etc. are implemented in terms of algorithms.
An algorithm, in general, contains a set of instructions, which are performed in a well-defined order.
Algorithm container
The algorithm_t class itself, is only an extension of the linked list.
Definition of algorithm_t
type,extends(linked_list_t),abstract::algorithm_tprivatetype(algorithm_iterator_t),public::iter!< Iterator for algorithmic operations
type(algorithmic_operation_t)::current_ops!< The current operation
type(algorithmic_operation_t),public::start_operation!< @brief algorithm specific initialization operation;
!!
!! this operation is performed only once before the algorithm loop starts.
type(algorithmic_operation_t),public::final_operation!< @brief algorithm specific finalization operation
!!
!! this operation is performed only once after the algorithm loop ends.
integer,public::algo_steps!< @brief Number of 'algorithmic steps' per algorithmic iteration
!!
!! This describes the granularity of the iteration. The algorithm iteration
!! counter will advance algo_steps per iteration.
!!
!! This also means that the interactions have to be updated at
!! algo_steps times per algorithm iteration.
logical::iteration_done!< Indicate whether the current iteration is done.
type(iteration_counter_t),public::iteration!< Keep track at which iteration this algorithm is.
real(real64)::start_time=M_ZERO!< Keep the wall clock time when the algorithm started,
real(real64),public::elapsed_time=M_ZERO!< Elapsed wall clock time for printing info
containsprocedure::add_operation=>algorithm_add_operation!< @copydoc algorithm_add_operation
procedure::do_operation=>algorithm_do_operation!< @copydoc algorithm_do_operation
procedure::update_elapsed_time=>algorithm_update_elapsed_time!< @copydoc algorithm_update_elapsed_time
procedure::rewind=>algorithm_rewind!< @copydoc algorithm_rewind
procedure::next=>algorithm_next!< @copydoc algorithm_next
procedure::get_current_operation=>algorithm_get_current_operation!< @copydoc algorithm_get_current_operation
procedure(algorithm_finished),deferred::finished!< @copydoc algorithm_finished
procedure(algorithm_init_iteration_counters),deferred::init_iteration_counters!< @copydoc algorithm_init_iteration_counters
endtypealgorithm_t
type::algorithmic_operation_tcharacter(len=ALGO_LABEL_LEN)::id!< Operation identifier. We use a string instead of
!! an integer to minimize the chance of having duplicated identifiers.
character(len=ALGO_LABEL_LEN)::label!< Label describing what the code is doing when performing this operation.
endtypealgorithmic_operation_t
! Known propagation operations
character(len=ALGO_LABEL_LEN),public,parameter::&START_SCF_LOOP='START_SCF_LOOP',&END_SCF_LOOP='END_SCF_LOOP',&STORE_CURRENT_STATUS='STORE_CURRENT_STATUS'type(algorithmic_operation_t),public,parameter::&OP_START_SCF_LOOP=algorithmic_operation_t(START_SCF_LOOP,'Starting SCF loop'),&OP_END_SCF_LOOP=algorithmic_operation_t(END_SCF_LOOP,'End of SCF iteration'),&OP_STORE_CURRENT_STATUS=algorithmic_operation_t(STORE_CURRENT_STATUS,'Store current status')
It is important to stress here, that one algorithmic step, in general, does not advance any clock. Clocks are only advanced in steps which update the corresponding entity, which could be a system, an exposed quantity or an interaction. It is therefore quite common, that at a specific state of the algorithm, clocks or different entities have different values.