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
30 use loct_oct_m
33 use system_oct_m
34 use unit_oct_m
37
38 implicit none
39
40 private
41 public :: &
43
49 type, extends(algorithm_t), abstract :: propagator_t
50 private
51 class(system_t), pointer, public :: system
52
53 type(algorithm_iterator_t) :: scf_start
56
57 real(real64), public :: dt
58 real(real64), public :: final_time = m_zero
59
60 ! Options related to predictor-corrector propagators
61 logical, public :: inside_scf = .false.
62 logical, public :: predictor_corrector = .false.
63 integer, public :: scf_count
64 integer, public :: max_scf_count
65 integer, public :: accumulated_loop_ticks
66 real(real64), public :: scf_tol
67 contains
68 ! Below are the list of operations that needs to be implemented
69 procedure :: do_operation => propagator_do_operation
70 procedure :: finished => propagator_finished
71 procedure :: init_iteration_counters => propagator_init_iteration_counters
72 procedure :: save_scf_start => propagator_save_scf_start
73 procedure :: rewind_scf_loop => propagator_rewind_scf_loop
74 procedure :: write_output_header => propagator_write_output_header
75 procedure :: continues_after_finished => propagator_continues_after_finished
76 procedure :: print_speed => propagator_print_speed
77 end type propagator_t
78
79 !# doc_start general_propagation_operations
80 ! Known propagation operations
81 character(len=ALGO_LABEL_LEN), public, parameter :: &
82 START_SCF_LOOP = 'START_SCF_LOOP', &
83 end_scf_loop = 'END_SCF_LOOP', &
84 store_current_status = 'STORE_CURRENT_STATUS'
85
86 type(algorithmic_operation_t), public, parameter :: &
87 OP_START_SCF_LOOP = algorithmic_operation_t(start_scf_loop, 'Starting SCF loop'), &
88 op_end_scf_loop = algorithmic_operation_t(end_scf_loop, 'End of SCF iteration'), &
90 !# doc_end
91
92
93contains
94
97 logical function propagator_do_operation(this, operation) result(done)
98 class(propagator_t), intent(inout) :: this
99 type(algorithmic_operation_t), intent(in) :: operation
100
101 done = .true.
102
103 select case (operation%id)
105 ! Update the accumulated loop ticks before executing this generic operation
106 this%accumulated_loop_ticks = this%accumulated_loop_ticks + 1
107 done = .false.
108
109 case (start_scf_loop)
110 assert(this%predictor_corrector)
111
112 call this%save_scf_start()
113 this%inside_scf = .true.
114 this%accumulated_loop_ticks = 0
115
116 if (debug%info) then
117 write(message(1), '(a,i3,a)') "Debug: -- SCF iter ", this%scf_count, " for '" + trim(this%system%namespace%get()) + "'"
118 call messages_info(1, namespace=this%system%namespace)
119 end if
120
121 case (end_scf_loop)
122 ! Here we first check if we did the maximum number of steps.
123 ! Otherwise, we need check the tolerance
124 if (this%scf_count == this%max_scf_count) then
125 if (debug%info) then
126 message(1) = "Debug: -- Max SCF Iter reached for '" + trim(this%system%namespace%get()) + "'"
127 call messages_info(1, namespace=this%system%namespace)
128 end if
129 this%inside_scf = .false.
130 call this%next()
131 else
132 ! We reset the pointer to the beginning of the scf loop
133 if (this%system%is_tolerance_reached(this%scf_tol)) then
134 if (debug%info) then
135 message(1) = "Debug: -- SCF tolerance reached for '" + trim(this%system%namespace%get()) + "'"
136 call messages_info(1, namespace=this%system%namespace)
137 end if
138 this%inside_scf = .false.
139 call this%next()
140 else
141 ! We rewind the instruction stack
142 call this%rewind_scf_loop()
143
144 ! We reset the clocks
145 call this%system%reset_iteration_counters(this%accumulated_loop_ticks)
146 this%accumulated_loop_ticks = 0
147 if (debug%info) then
148 write(message(1), '(a,i3,a,a)') "Debug: -- SCF iter ", this%scf_count, " for '" + trim(this%system%namespace%get()), "'"
149 call messages_info(1, namespace=this%system%namespace)
150 end if
151 end if
152 end if
154 case default
155 done = .false.
156 end select
160 ! ---------------------------------------------------------
163 logical function propagator_finished(this)
164 class(propagator_t), intent(in) :: this
166 type(iteration_counter_t) :: clock_
168 clock_ = this%system%iteration + 1
169 propagator_finished = clock_%value() > this%final_time
172
173 ! ---------------------------------------------------------
179 class(propagator_t), intent(inout) :: this
180
181 this%iteration = clock_t(time_step=this%dt/this%algo_steps)
182 this%system%iteration = clock_t(time_step=this%dt)
183
185
187 !
188 subroutine propagator_save_scf_start(this)
189 class(propagator_t), intent(inout) :: this
190
193 this%scf_start = this%iter
194 call this%next()
195 this%scf_count = 0
196
198 end subroutine propagator_save_scf_start
199
200 ! ---------------------------------------------------------
202 !
203 subroutine propagator_rewind_scf_loop(this)
204 class(propagator_t), intent(inout) :: this
205
207
208 this%iter = this%scf_start
209 call this%next()
210 this%scf_count = this%scf_count + 1
211
213 end subroutine propagator_rewind_scf_loop
214
215 subroutine propagator_write_output_header(this)
216 class(propagator_t), intent(in) :: this
217
219
220 call messages_print_with_emphasis(msg="Multi-system propagation", namespace=this%system%namespace)
221 write(message(1), '(a6,1x,a14,1x,a13,1x,a10,1x,a15)') 'Iter', 'Time', 'Energy', 'SC Steps', 'Elapsed Time'
222 call messages_info(1, namespace=this%system%namespace)
223 call messages_print_with_emphasis(namespace=this%system%namespace)
224
226 end subroutine propagator_write_output_header
227
228
229 logical function propagator_continues_after_finished(this)
230 class(propagator_t), intent(in) :: this
231
233
235
238
239 ! ---------------------------------------------------------
241 !
242 subroutine propagator_print_speed(this)
243 class(propagator_t), intent(in) :: this
244
245 real(real64) :: wall_time, simulation_time, speed_fs_per_day
246
247 ! Output propagation speed in fs/day
248 wall_time = loct_clock() - walltimer_get_start_time()
249 simulation_time = this%iteration%value(elapsed=.true.)
250 speed_fs_per_day = units_from_atomic(unit_femtosecond, simulation_time)/ (wall_time / 86400.0_real64)
251 write(message(1), '(a,f10.3,a)') 'Propagation speed: ', speed_fs_per_day, ' fs/day'
252 write(message(2), '(a)') ''
253 call messages_info(2, namespace=this%system%namespace)
254
255 end subroutine propagator_print_speed
256
257end module propagator_oct_m
259
260!! Local Variables:
261!! mode: f90
262!! coding: utf-8
263!! End:
This module implements the basic elements defining algorithms.
Definition: algorithm.F90:143
character(len=algo_label_len), parameter, public update_interactions
Definition: algorithm.F90:174
type(debug_t), save, public debug
Definition: debug.F90:158
real(real64), parameter, public m_zero
Definition: global.F90:190
subroutine, public messages_print_with_emphasis(msg, iunit, namespace)
Definition: messages.F90:904
character(len=512), private msg
Definition: messages.F90:167
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:162
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:600
This module implements the basic propagator framework.
Definition: propagator.F90:119
character(len=algo_label_len), parameter, public store_current_status
Definition: propagator.F90:176
type(algorithmic_operation_t), parameter, public op_store_current_status
Definition: propagator.F90:181
logical function propagator_continues_after_finished(this)
Definition: propagator.F90:325
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:299
subroutine propagator_write_output_header(this)
Definition: propagator.F90:311
subroutine propagator_save_scf_start(this)
Save the current iteration state (START_SCF_LOOP) and move to next step.
Definition: propagator.F90:284
logical function propagator_do_operation(this, operation)
Try to perform one operation of the algorithm. Return .true. if sucessful.
Definition: propagator.F90:193
logical function propagator_finished(this)
indicate whether a propagation has reached the final time
Definition: propagator.F90:259
character(len=algo_label_len), parameter, public end_scf_loop
Definition: propagator.F90:176
subroutine propagator_init_iteration_counters(this)
Initialize the propagator and system clocks.
Definition: propagator.F90:274
subroutine propagator_print_speed(this)
print iteration speed, i.e., fs/day of wall clock time
Definition: propagator.F90:338
type(algorithmic_operation_t), parameter, public op_end_scf_loop
Definition: propagator.F90:181
This module implements the abstract system type.
Definition: system.F90:120
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
Definition: unit.F90:134
This module defines the unit system, used for input and output.
type(unit_t), public unit_femtosecond
Time in femtoseconds.
This module provices a simple timer class which can be used to trigger the writing of a restart file ...
Definition: walltimer.F90:123
real(real64) function, public walltimer_get_start_time()
Return the walltimer start time.
Definition: walltimer.F90:407
An algorithm is a list of algorithmic operations executed sequentially.
Definition: algorithm.F90:202
Descriptor of one algorithmic operation.
Definition: algorithm.F90:165
This class implements the iteration counter used by the multisystem algorithms. As any iteration coun...
Abstract class implementing propagators.
Definition: propagator.F90:144
int true(void)