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 end type algorithm_t
148
149 abstract interface
150
151 !
152 logical function algorithm_finished(this)
153 import :: algorithm_t
154 class(algorithm_t), intent(in) :: this
155 end function algorithm_finished
156
158 !
159 subroutine algorithm_init_iteration_counters(this)
160 import :: algorithm_t
161 class(algorithm_t), intent(inout) :: this
165 !
167 import :: algorithm_t
168 class(algorithm_t), intent(in) :: this
169 end subroutine algorithm_write_output_header
170
173 logical function algorithm_continues_after_finished(this)
174 import :: algorithm_t
175 class(algorithm_t), intent(in) :: this
177 end interface
178contains
180 ! ---------------------------------------------------------
182 !
183 subroutine algorithm_add_operation(this, operation)
184 class(algorithm_t), intent(inout) :: this
185 type(algorithmic_operation_t), intent(in) :: operation
186
188
189 call this%add_copy(operation)
190
193
194 ! ---------------------------------------------------------
196 !
197 logical function algorithm_do_operation(this, operation) result(done)
198 class(algorithm_t), intent(inout) :: this
199 type(algorithmic_operation_t), intent(in) :: operation
201 ! By default no algorithm specific operation is implemented in the algorithm
202 ! class. Child classes that wish to change this behaviour should override
203 ! this method.
204 done = .false.
206 end function algorithm_do_operation
207
208 ! ---------------------------------------------------------
211 subroutine algorithm_update_elapsed_time(this)
212 class(algorithm_t), intent(inout) :: this
213
216 this%elapsed_time = loct_clock() - this%start_time
217
219 end subroutine algorithm_update_elapsed_time
220
221 ! ---------------------------------------------------------
224 subroutine algorithm_rewind(this)
225 class(algorithm_t), intent(inout) :: this
228
229 ! Note that both lines are necessary to get the first element of the list.
230 ! For more information, see the linked_list_t implementation.
231 call this%iter%start(this)
232 call this%next()
233 this%start_time = loct_clock()
236 end subroutine algorithm_rewind
238 ! ---------------------------------------------------------
240 !
241 subroutine algorithm_next(this)
242 class(algorithm_t), intent(inout) :: this
243
244 push_sub(algorithm_next)
246 this%current_ops = this%iter%get_next()
247
248 pop_sub(algorithm_next)
249 end subroutine algorithm_next
250
251 ! ---------------------------------------------------------
253 !
254 type(algorithmic_operation_t) function algorithm_get_current_operation(this) result(operation)
255 class(algorithm_t), intent(in) :: this
256
258
259 operation = this%current_ops
260
263
264 ! ---------------------------------------------------------
268 !
269 function algorithm_iterator_get_next(this) result(operation)
270 class(algorithm_iterator_t), intent(inout) :: this
271 type(algorithmic_operation_t) :: operation
272
274
275 assert(this%has_next())
277 select type (ptr => this%get_next_ptr())
278 class is (algorithmic_operation_t)
279 operation = ptr
280 class default
281 assert(.false.)
282 end select
283
285 end function algorithm_iterator_get_next
286
287end module algorithm_oct_m
288
289!! Local Variables:
290!! mode: f90
291!! coding: utf-8
292!! End:
indicate whether the algorithm should continue executing after finishing, or should set a barrier
Definition: algorithm.F90:266
indicate whether the algorithm has finished one time step
Definition: algorithm.F90:245
initializes the algorithm and system iteration counters
Definition: algorithm.F90:252
Write the header for the execution log.
Definition: algorithm.F90:259
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
character(len=algo_label_len), parameter, public rewind_algorithm
Definition: algorithm.F90:172
type(algorithmic_operation_t), parameter, public op_iteration_done
Definition: algorithm.F90:179
character(len=algo_label_len), parameter, public update_couplings
Definition: algorithm.F90:172
type(algorithmic_operation_t), parameter, public op_rewind_algorithm
Definition: algorithm.F90:179
type(algorithmic_operation_t) function algorithm_get_current_operation(this)
return the current algorithmic operation.
Definition: algorithm.F90:348
subroutine algorithm_rewind(this)
Reset the algorithm to the first operation.
Definition: algorithm.F90:318
type(algorithmic_operation_t) function algorithm_iterator_get_next(this)
Get the next algorithmic operation from the iterator.
Definition: algorithm.F90:363
type(algorithmic_operation_t), parameter, public op_update_couplings
Definition: algorithm.F90:179
character(len=algo_label_len), parameter, public iteration_done
Definition: algorithm.F90:172
subroutine algorithm_add_operation(this, operation)
add an algorithmic operation to the list
Definition: algorithm.F90:277
subroutine algorithm_update_elapsed_time(this)
The elapsed time is used for the output of run time information.
Definition: algorithm.F90:305
subroutine algorithm_next(this)
move to the next algorithmic operation
Definition: algorithm.F90:335
logical function algorithm_do_operation(this, operation)
try to perform one operation of the algorithm. If successfull return .true.
Definition: algorithm.F90:291
type(algorithmic_operation_t), parameter, public op_update_interactions
Definition: algorithm.F90:179
real(real64), parameter, public m_zero
Definition: global.F90:188
This module implements fully polymorphic linked lists, and some specializations thereof.
Iterator to loop over the algorithmic operations of an algorithm.
Definition: algorithm.F90:189
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 an iterator for the polymorphic linked list.
This class implements a linked list of unlimited polymorphic values.