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
52
53 real(real64), public :: dt
54 real(real64), public :: final_time = m_zero
55
56 ! Options related to predictor-corrector propagators
57 logical, public :: inside_scf = .false.
58 logical, public :: predictor_corrector = .false.
59 integer, public :: scf_count
60 integer, public :: max_scf_count
61 integer, public :: accumulated_loop_ticks
62 real(real64), public :: scf_tol
63 contains
64 ! Below are the list of operations that needs to be implemented
65 procedure :: do_operation => propagator_do_operation
66 procedure :: finished => propagator_finished
67 procedure :: init_iteration_counters => propagator_init_iteration_counters
68 procedure :: save_scf_start => propagator_save_scf_start
69 procedure :: rewind_scf_loop => propagator_rewind_scf_loop
70 procedure :: write_output_header => propagator_write_output_header
71 procedure :: continues_after_finished => propagator_continues_after_finished
72 end type propagator_t
73
74 !# doc_start general_propagation_operations
75 ! Known propagation operations
76 character(len=ALGO_LABEL_LEN), public, parameter :: &
77 START_SCF_LOOP = 'START_SCF_LOOP', &
78 end_scf_loop = 'END_SCF_LOOP', &
79 store_current_status = 'STORE_CURRENT_STATUS'
80
81 type(algorithmic_operation_t), public, parameter :: &
82 OP_START_SCF_LOOP = algorithmic_operation_t(start_scf_loop, 'Starting SCF loop'), &
83 op_end_scf_loop = algorithmic_operation_t(end_scf_loop, 'End of SCF iteration'), &
85 !# doc_end
86
87
88contains
89
92 logical function propagator_do_operation(this, operation) result(done)
93 class(propagator_t), intent(inout) :: this
94 type(algorithmic_operation_t), intent(in) :: operation
95
96 done = .true.
97
98 select case (operation%id)
100 ! Update the accumulated loop ticks before executing this generic operation
101 this%accumulated_loop_ticks = this%accumulated_loop_ticks + 1
102 done = .false.
103
104 case (start_scf_loop)
105 assert(this%predictor_corrector)
106
107 call this%save_scf_start()
108 this%inside_scf = .true.
109 this%accumulated_loop_ticks = 0
110
111 if (debug%info) then
112 write(message(1), '(a,i3,a)') "Debug: -- SCF iter ", this%scf_count, " for '" + trim(this%system%namespace%get()) + "'"
113 call messages_info(1, namespace=this%system%namespace)
114 end if
115
116 case (end_scf_loop)
117 ! Here we first check if we did the maximum number of steps.
118 ! Otherwise, we need check the tolerance
119 if (this%scf_count == this%max_scf_count) then
120 if (debug%info) then
121 message(1) = "Debug: -- Max SCF Iter reached for '" + trim(this%system%namespace%get()) + "'"
122 call messages_info(1, namespace=this%system%namespace)
123 end if
124 this%inside_scf = .false.
125 call this%next()
126 else
127 ! We reset the pointer to the beginning of the scf loop
128 if (this%system%is_tolerance_reached(this%scf_tol)) then
129 if (debug%info) then
130 message(1) = "Debug: -- SCF tolerance reached for '" + trim(this%system%namespace%get()) + "'"
131 call messages_info(1, namespace=this%system%namespace)
132 end if
133 this%inside_scf = .false.
134 call this%next()
135 else
136 ! We rewind the instruction stack
137 call this%rewind_scf_loop()
139 ! We reset the clocks
140 call this%system%reset_iteration_counters(this%accumulated_loop_ticks)
141 this%accumulated_loop_ticks = 0
142 if (debug%info) then
143 write(message(1), '(a,i3,a,a)') "Debug: -- SCF iter ", this%scf_count, " for '" + trim(this%system%namespace%get()), "'"
144 call messages_info(1, namespace=this%system%namespace)
145 end if
146 end if
147 end if
148
149 case default
150 done = .false.
151 end select
155 ! ---------------------------------------------------------
158 logical function propagator_finished(this)
159 class(propagator_t), intent(in) :: this
161 type(iteration_counter_t) :: clock_
163 clock_ = this%system%iteration + 1
164 propagator_finished = clock_%value() > this%final_time
165
166 end function propagator_finished
167
168 ! ---------------------------------------------------------
174 class(propagator_t), intent(inout) :: this
175
176 this%iteration = clock_t(time_step=this%dt/this%algo_steps)
177 this%system%iteration = clock_t(time_step=this%dt)
178
180
182 !
183 subroutine propagator_save_scf_start(this)
184 class(propagator_t), intent(inout) :: this
187
188 this%scf_start = this%iter
189 call this%next()
190 this%scf_count = 0
191
193 end subroutine propagator_save_scf_start
194
195 ! ---------------------------------------------------------
197 !
198 subroutine propagator_rewind_scf_loop(this)
199 class(propagator_t), intent(inout) :: this
200
202
203 this%iter = this%scf_start
204 call this%next()
205 this%scf_count = this%scf_count + 1
206
208 end subroutine propagator_rewind_scf_loop
209
210 subroutine propagator_write_output_header(this)
211 class(propagator_t), intent(in) :: this
212
214
215 call messages_print_with_emphasis(msg="Multi-system propagation", namespace=this%system%namespace)
216 write(message(1), '(a6,1x,a14,1x,a13,1x,a10,1x,a15)') 'Iter', 'Time', 'Energy', 'SC Steps', 'Elapsed Time'
217 call messages_info(1, namespace=this%system%namespace)
218 call messages_print_with_emphasis(namespace=this%system%namespace)
219
221 end subroutine propagator_write_output_header
222
223
224 logical function propagator_continues_after_finished(this)
225 class(propagator_t), intent(in) :: this
226
228
230
233
234end module propagator_oct_m
235
236
237!! Local Variables:
238!! mode: f90
239!! coding: utf-8
240!! End:
This module implements the basic elements defining algorithms.
Definition: algorithm.F90:141
character(len=algo_label_len), parameter, public update_interactions
Definition: algorithm.F90:172
type(debug_t), save, public debug
Definition: debug.F90:154
real(real64), parameter, public m_zero
Definition: global.F90:187
subroutine, public messages_print_with_emphasis(msg, iunit, namespace)
Definition: messages.F90:930
character(len=512), private msg
Definition: messages.F90:165
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:160
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:624
This module implements the basic propagator framework.
Definition: propagator.F90:117
character(len=algo_label_len), parameter, public store_current_status
Definition: propagator.F90:169
type(algorithmic_operation_t), parameter, public op_store_current_status
Definition: propagator.F90:174
logical function propagator_continues_after_finished(this)
Definition: propagator.F90:318
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:292
subroutine propagator_write_output_header(this)
Definition: propagator.F90:304
subroutine propagator_save_scf_start(this)
Save the current iteration state (START_SCF_LOOP) and move to next step.
Definition: propagator.F90:277
logical function propagator_do_operation(this, operation)
Try to perform one operation of the algorithm. Return .true. if sucessful.
Definition: propagator.F90:186
logical function propagator_finished(this)
indicate whether a propagation has reached the final time
Definition: propagator.F90:252
character(len=algo_label_len), parameter, public end_scf_loop
Definition: propagator.F90:169
subroutine propagator_init_iteration_counters(this)
Initialize the propagator and system clocks.
Definition: propagator.F90:267
type(algorithmic_operation_t), parameter, public op_end_scf_loop
Definition: propagator.F90:174
This module implements the abstract system type.
Definition: system.F90:118
An algorithm is a list of algorithmic operations executed sequentially.
Definition: algorithm.F90:200
Descriptor of one algorithmic operation.
Definition: algorithm.F90:163
This class implements the iteration counter used by the multisystem algorithms. As any iteration coun...
Abstract class implementing propagators.
Definition: propagator.F90:138
int true(void)