Octopus
propagator.F90
Go to the documentation of this file.
1!! Copyright (C) 2019 N. Tancogne-Dejean
2!! Copyright (C) 2020 M. Oliveira
3!!
4!! This program is free software; you can redistribute it and/or modify
5!! it under the terms of the GNU General Public License as published by
6!! the Free Software Foundation; either version 2, or (at your option)
7!! any later version.
8!!
9!! This program is distributed in the hope that it will be useful,
10!! but WITHOUT ANY WARRANTY; without even the implied warranty of
11!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12!! GNU General Public License for more details.
13!!
14!! You should have received a copy of the GNU General Public License
15!! along with this program; if not, write to the Free Software
16!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17!! 02110-1301, USA.
18!!
19
20#include "global.h"
21
26 use clock_oct_m
27 use debug_oct_m
28 use global_oct_m
32 use system_oct_m
33
34 implicit none
35
36 private
37 public :: &
39
45 type, extends(algorithm_t), abstract :: propagator_t
46 private
47 class(system_t), pointer, public :: system
48
49 type(algorithm_iterator_t) :: scf_start
50
51
52 logical, public :: predictor_corrector = .false.
53 integer, public :: scf_count
54 integer, public :: max_scf_count
55 float, public :: scf_tol
56
57 float, public :: final_time = m_zero
58 contains
59 ! Below are the list of operations that needs to be implemented
60 procedure :: do_operation => propagator_do_operation
61 procedure :: finished => propagator_finished
62 procedure :: save_scf_start => propagator_save_scf_start
63 procedure :: rewind_scf_loop => propagator_rewind_scf_loop
64 end type propagator_t
65
66 !# doc_start general_propagation_operations
67 ! Known propagation operations
68 character(len=ALGO_LABEL_LEN), public, parameter :: &
69 START_SCF_LOOP = 'START_SCF_LOOP', &
70 end_scf_loop = 'END_SCF_LOOP', &
71 store_current_status = 'STORE_CURRENT_STATUS'
72
73 type(algorithmic_operation_t), public, parameter :: &
74 OP_START_SCF_LOOP = algorithmic_operation_t(start_scf_loop, 'Starting SCF loop'), &
75 op_end_scf_loop = algorithmic_operation_t(end_scf_loop, 'End of SCF iteration'), &
77 !# doc_end
78
79
80contains
81
86 logical function propagator_do_operation(this, operation) result(done)
87 class(propagator_t), intent(inout) :: this
88 type(algorithmic_operation_t), intent(in) :: operation
89
90 done = .true.
91
92 select case (operation%id)
93 case (start_scf_loop)
94 assert(this%predictor_corrector)
95
96 call this%save_scf_start()
97 this%inside_scf = .true.
98 this%system%accumulated_loop_ticks = 0
99
100 if (debug%info) then
101 write(message(1), '(a,i3,a)') "Debug: -- SCF iter ", this%scf_count, " for '" + trim(this%system%namespace%get()) + "'"
102 call messages_info(1, namespace=this%system%namespace)
103 end if
104
105 case (end_scf_loop)
106 ! Here we first check if we did the maximum number of steps.
107 ! Otherwise, we need check the tolerance
108 if (this%scf_count == this%max_scf_count) then
109 if (debug%info) then
110 message(1) = "Debug: -- Max SCF Iter reached for '" + trim(this%system%namespace%get()) + "'"
111 call messages_info(1, namespace=this%system%namespace)
112 end if
113 this%inside_scf = .false.
114 call this%next()
115 else
116 ! We reset the pointer to the beginning of the scf loop
117 if (this%system%is_tolerance_reached(this%scf_tol)) then
118 if (debug%info) then
119 message(1) = "Debug: -- SCF tolerance reached for '" + trim(this%system%namespace%get()) + "'"
120 call messages_info(1, namespace=this%system%namespace)
121 end if
122 this%inside_scf = .false.
123 call this%next()
124 else
125 ! We rewind the instruction stack
126 call this%rewind_scf_loop()
127
128 ! We reset the clocks
129 call this%system%reset_clocks(this%system%accumulated_loop_ticks)
130 this%system%accumulated_loop_ticks = 0
131 if (debug%info) then
132 write(message(1), '(a,i3,a,a)') "Debug: -- SCF iter ", this%scf_count, " for '" + trim(this%system%namespace%get()), "'"
133 call messages_info(1, namespace=this%system%namespace)
134 end if
135 end if
136 end if
138 case default
139 done = .false.
140 end select
141
143
144 ! ---------------------------------------------------------
147 logical function propagator_finished(this)
148 class(propagator_t), intent(in) :: this
149
150 type(clock_t) :: clock_
151
152 clock_ = this%system%clock + clock_tick
153 propagator_finished = clock_%time() > this%final_time
154
155 end function propagator_finished
156
159 subroutine propagator_save_scf_start(this)
160 class(propagator_t), intent(inout) :: this
161
163
164 this%scf_start = this%iter
165 call this%next()
166 this%scf_count = 0
167
169 end subroutine propagator_save_scf_start
170
171 ! ---------------------------------------------------------
174 subroutine propagator_rewind_scf_loop(this)
175 class(propagator_t), intent(inout) :: this
176
178
179 this%iter = this%scf_start
180 call this%next()
181 this%scf_count = this%scf_count + 1
182
184 end subroutine propagator_rewind_scf_loop
185
186end module propagator_oct_m
187
188
189!! Local Variables:
190!! mode: f90
191!! coding: utf-8
192!! End:
The basic elements defining algorithms.
Definition: algorithm.F90:107
integer, parameter, public clock_tick
Definition: clock.F90:120
type(debug_t), save, public debug
Definition: debug.F90:140
real(8), parameter, public m_zero
Definition: global.F90:170
subroutine, public push_sub(sub_name)
Definition: messages.F90:1046
subroutine, public messages_info(no_lines, iunit, verbose_limit, stress, all_nodes, namespace)
Definition: messages.F90:611
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:157
subroutine, public pop_sub(sub_name)
Definition: messages.F90:1101
This module implements the basic propagator framework.
Definition: propagator.F90:109
character(len=algo_label_len), parameter, public store_current_status
Definition: propagator.F90:153
type(algorithmic_operation_t), parameter, public op_store_current_status
Definition: propagator.F90:158
subroutine propagator_rewind_scf_loop(this)
Reset the iteration state to the beginning of the loop (START_SCF_LOOP) and move to next step.
Definition: propagator.F90:260
subroutine propagator_save_scf_start(this)
Save the current iteration state (START_SCF_LOOP) and move to next step.
Definition: propagator.F90:245
logical function propagator_do_operation(this, operation)
perform one operation of the state machine
Definition: propagator.F90:172
logical function propagator_finished(this)
indicate whether a propagation has reached the final time
Definition: propagator.F90:233
character(len=algo_label_len), parameter, public end_scf_loop
Definition: propagator.F90:153
type(algorithmic_operation_t), parameter, public op_end_scf_loop
Definition: propagator.F90:158
This module implements the abstract system type.
Definition: system.F90:110
An algorithm is a list of algorithmic operations executed sequentially. This is implemented as a link...
Definition: algorithm.F90:164
Descriptor of one algorithmic operation.
Definition: algorithm.F90:130
Abstract class implementing propagators.
Definition: propagator.F90:130
int true(void)