Octopus
algorithm.F90
Go to the documentation of this file.
1!! Copyright (C) 2020 M. Oliveira
2!!
3!! This Source Code Form is subject to the terms of the Mozilla Public
4!! License, v. 2.0. If a copy of the MPL was not distributed with this
5!! file, You can obtain one at https://mozilla.org/MPL/2.0/.
6!!
7
8#include "global.h"
9
23! The following pseudocode shows how multiple algorithms, one per system, are executed:
24! @code
25! repeat
26! for all systems do
27! algo_op ← next algorithmic operation
28! break ← f alse
29! while not break do
30! if algo_op != update interactions then
31! execute algorithmic operation
32! algo_op ← next algorithmic operation
33! else
34! try updating interactions
35! if interactions updated then
36! algo_op ← next algorithmic operation
37! end if
38! break ← true
39! end if
40! end while
41! end for
42! until all algorithms finished
43! @endcode
44!
45! Note: The above codeblock is not enabled for doxygen, as the formatting is broken in doxygen.
46!
47!TODO: the concept of granularity also needs to be explained more in detail.
48module algorithm_oct_m
49 use debug_oct_m
50 use global_oct_m
53 use loct_oct_m
55
56 implicit none
57
58 private
59 public :: &
63
64 integer, parameter, public :: ALGO_LABEL_LEN = 50
65
71 character(len=ALGO_LABEL_LEN) :: id
73 character(len=ALGO_LABEL_LEN) :: label
75
76 !# doc_start generic_algorithmic_operations
79 character(len=ALGO_LABEL_LEN), public, parameter :: &
80 SKIP = 'SKIP', &
81 update_couplings = 'UPDATE_COUPLINGS', &
82 update_interactions = 'UPDATE_INTERACTIONS', &
83 iteration_done = 'ITERATION_DONE', &
84 rewind_algorithm = 'REWIND_ALGORITHM'
85
86 type(algorithmic_operation_t), public, parameter :: &
87 OP_SKIP = algorithmic_operation_t(skip, 'Skipping algorithmic operation'), &
88 op_update_couplings = algorithmic_operation_t(update_couplings, 'Algorithmic operation - Updating couplings'), &
89 op_update_interactions = algorithmic_operation_t(update_interactions, 'Algorithmic operation - Updating interactions'), &
92 !# doc_end
93
94
97 private
98 contains
99 procedure :: get_next => algorithm_iterator_get_next
100 end type algorithm_iterator_t
101
102
106 !
107 type, extends(linked_list_t), abstract :: algorithm_t
108 private
109 type(algorithm_iterator_t), public :: iter
110 type(algorithmic_operation_t) :: current_ops
111
112 type(algorithmic_operation_t), public :: start_operation
116
117 type(algorithmic_operation_t), public :: final_operation
121
122 integer, public :: algo_steps
129
130 logical :: iteration_done
131
132 type(iteration_counter_t), public :: iteration
133 real(real64) :: start_time = m_zero
134 real(real64), public :: elapsed_time = m_zero
135
136 contains
137 procedure :: add_operation => algorithm_add_operation
138 procedure :: do_operation => algorithm_do_operation
139 procedure :: update_elapsed_time => algorithm_update_elapsed_time
140 procedure :: rewind => algorithm_rewind
141 procedure :: next => algorithm_next
142 procedure :: get_current_operation => algorithm_get_current_operation
143 procedure(algorithm_finished), deferred :: finished
144 procedure(algorithm_init_iteration_counters), deferred :: init_iteration_counters
145 procedure(algorithm_write_output_header), deferred :: write_output_header
146 procedure(algorithm_continues_after_finished), deferred :: continues_after_finished
147 procedure(algorithm_print_speed), deferred :: print_speed
148 end type algorithm_t
149
150 abstract interface
151
152 !
153 logical function algorithm_finished(this)
154 import :: algorithm_t
155 class(algorithm_t), intent(in) :: this
156 end function algorithm_finished
157
160 subroutine algorithm_init_iteration_counters(this)
161 import :: algorithm_t
162 class(algorithm_t), intent(inout) :: this
164
167 subroutine algorithm_write_output_header(this)
168 import :: algorithm_t
169 class(algorithm_t), intent(in) :: this
170 end subroutine algorithm_write_output_header
171
173 !
175 import :: algorithm_t
176 class(algorithm_t), intent(in) :: this
178
180 !
181 subroutine algorithm_print_speed(this)
182 import :: algorithm_t
183 class(algorithm_t), intent(in) :: this
184 end subroutine algorithm_print_speed
185 end interface
186contains
187
188 ! ---------------------------------------------------------
190 !
191 subroutine algorithm_add_operation(this, operation)
192 class(algorithm_t), intent(inout) :: this
193 type(algorithmic_operation_t), intent(in) :: operation
196
197 call this%add_copy(operation)
198
200 end subroutine algorithm_add_operation
201
202 ! ---------------------------------------------------------
205 logical function algorithm_do_operation(this, operation) result(done)
206 class(algorithm_t), intent(inout) :: this
207 type(algorithmic_operation_t), intent(in) :: operation
208
209 ! By default no algorithm specific operation is implemented in the algorithm
210 ! class. Child classes that wish to change this behaviour should override
211 ! this method.
212 done = .false.
213
214 end function algorithm_do_operation
215
216 ! ---------------------------------------------------------
218 !
219 subroutine algorithm_update_elapsed_time(this)
220 class(algorithm_t), intent(inout) :: this
221
223
224 this%elapsed_time = loct_clock() - this%start_time
229 ! ---------------------------------------------------------
231 !
232 subroutine algorithm_rewind(this)
233 class(algorithm_t), intent(inout) :: this
237 ! Note that both lines are necessary to get the first element of the list.
238 ! For more information, see the linked_list_t implementation.
239 call this%iter%start(this)
240 call this%next()
241 this%start_time = loct_clock()
243 pop_sub(algorithm_rewind)
244 end subroutine algorithm_rewind
245
246 ! ---------------------------------------------------------
249 subroutine algorithm_next(this)
250 class(algorithm_t), intent(inout) :: this
251
252 push_sub(algorithm_next)
253
254 this%current_ops = this%iter%get_next()
256 pop_sub(algorithm_next)
257 end subroutine algorithm_next
258
259 ! ---------------------------------------------------------
261 !
262 type(algorithmic_operation_t) function algorithm_get_current_operation(this) result(operation)
263 class(algorithm_t), intent(in) :: this
264
265 push_sub(algorithm_get_current_operation)
266
267 operation = this%current_ops
268
269 pop_sub(algorithm_get_current_operation)
271
272 ! ---------------------------------------------------------
277 function algorithm_iterator_get_next(this) result(operation)
278 class(algorithm_iterator_t), intent(inout) :: this
279 type(algorithmic_operation_t) :: operation
280
282
283 assert(this%has_next())
284
285 select type (ptr => this%get_next_ptr())
287 operation = ptr
288 class default
289 assert(.false.)
290 end select
291
293 end function algorithm_iterator_get_next
294
295end module algorithm_oct_m
296
297!! Local Variables:
298!! mode: f90
299!! coding: utf-8
300!! End:
indicate whether the algorithm should continue executing after finishing, or should set a barrier
Definition: algorithm.F90:269
indicate whether the algorithm has finished one time step
Definition: algorithm.F90:248
initializes the algorithm and system iteration counters
Definition: algorithm.F90:255
Write the header for the execution log.
Definition: algorithm.F90:262
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
character(len=algo_label_len), parameter, public rewind_algorithm
Definition: algorithm.F90:174
type(algorithmic_operation_t), parameter, public op_iteration_done
Definition: algorithm.F90:181
character(len=algo_label_len), parameter, public update_couplings
Definition: algorithm.F90:174
type(algorithmic_operation_t), parameter, public op_rewind_algorithm
Definition: algorithm.F90:181
type(algorithmic_operation_t) function algorithm_get_current_operation(this)
return the current algorithmic operation.
Definition: algorithm.F90:358
subroutine algorithm_rewind(this)
Reset the algorithm to the first operation.
Definition: algorithm.F90:328
type(algorithmic_operation_t) function algorithm_iterator_get_next(this)
Get the next algorithmic operation from the iterator.
Definition: algorithm.F90:373
type(algorithmic_operation_t), parameter, public op_update_couplings
Definition: algorithm.F90:181
character(len=algo_label_len), parameter, public iteration_done
Definition: algorithm.F90:174
subroutine algorithm_add_operation(this, operation)
add an algorithmic operation to the list
Definition: algorithm.F90:287
subroutine algorithm_update_elapsed_time(this)
The elapsed time is used for the output of run time information.
Definition: algorithm.F90:315
subroutine algorithm_next(this)
move to the next algorithmic operation
Definition: algorithm.F90:345
logical function algorithm_do_operation(this, operation)
try to perform one operation of the algorithm. If successfull return .true.
Definition: algorithm.F90:301
type(algorithmic_operation_t), parameter, public op_update_interactions
Definition: algorithm.F90:181
real(real64), parameter, public m_zero
Definition: global.F90:190
This module implements fully polymorphic linked lists, and some specializations thereof.
Iterator to loop over the algorithmic operations of an algorithm.
Definition: algorithm.F90:191
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 an iterator for the polymorphic linked list.
This class implements a linked list of unlimited polymorphic values.