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
115
116 type(algorithmic_operation_t), public :: final_operation
119
120 integer, public :: algo_steps
127
128 logical :: iteration_done
129
130 type(iteration_counter_t), public :: iteration
131 real(real64) :: start_time = m_zero
132 real(real64), public :: elapsed_time = m_zero
133
134 contains
135 procedure :: add_operation => algorithm_add_operation
136 procedure :: do_operation => algorithm_do_operation
137 procedure :: update_elapsed_time => algorithm_update_elapsed_time
138 procedure :: rewind => algorithm_rewind
139 procedure :: next => algorithm_next
140 procedure :: get_current_operation => algorithm_get_current_operation
141 procedure(algorithm_finished), deferred :: finished
142 procedure(algorithm_init_iteration_counters), deferred :: init_iteration_counters
143 procedure(algorithm_write_output_header), deferred :: write_output_header
144 procedure(algorithm_continues_after_finished), deferred :: continues_after_finished
145 end type algorithm_t
146
147 abstract interface
148
149 !
150 logical function algorithm_finished(this)
151 import :: algorithm_t
152 class(algorithm_t), intent(in) :: this
153 end function algorithm_finished
154
156 !
158 import :: algorithm_t
159 class(algorithm_t), intent(inout) :: this
161
165 import :: algorithm_t
166 class(algorithm_t), intent(in) :: this
167 end subroutine algorithm_write_output_header
168
170 !
171 logical function algorithm_continues_after_finished(this)
172 import :: algorithm_t
173 class(algorithm_t), intent(in) :: this
175 end interface
176contains
177
178 ! ---------------------------------------------------------
180 !
181 subroutine algorithm_add_operation(this, operation)
182 class(algorithm_t), intent(inout) :: this
183 type(algorithmic_operation_t), intent(in) :: operation
184
186
187 call this%add_copy(operation)
188
190 end subroutine algorithm_add_operation
191
192 ! ---------------------------------------------------------
194 !
195 logical function algorithm_do_operation(this, operation) result(done)
196 class(algorithm_t), intent(inout) :: this
197 type(algorithmic_operation_t), intent(in) :: operation
198
199 ! By default no algorithm specific operation is implemented in the algorithm
200 ! class. Child classes that wish to change this behaviour should override
201 ! this method.
202 done = .false.
204 end function algorithm_do_operation
206 ! ---------------------------------------------------------
208 !
210 class(algorithm_t), intent(inout) :: this
211
214 this%elapsed_time = loct_clock() - this%start_time
215
217 end subroutine algorithm_update_elapsed_time
218
219 ! ---------------------------------------------------------
222 subroutine algorithm_rewind(this)
223 class(algorithm_t), intent(inout) :: this
226
227 ! Note that both lines are necessary to get the first element of the list.
228 ! For more information, see the linked_list_t implementation.
229 call this%iter%start(this)
230 call this%next()
231 this%start_time = loct_clock()
234 end subroutine algorithm_rewind
236 ! ---------------------------------------------------------
238 !
239 subroutine algorithm_next(this)
240 class(algorithm_t), intent(inout) :: this
241
242 push_sub(algorithm_next)
244 this%current_ops = this%iter%get_next()
245
246 pop_sub(algorithm_next)
247 end subroutine algorithm_next
248
249 ! ---------------------------------------------------------
251 !
252 type(algorithmic_operation_t) function algorithm_get_current_operation(this) result(operation)
253 class(algorithm_t), intent(in) :: this
254
256
257 operation = this%current_ops
258
261
262 ! ---------------------------------------------------------
266 !
267 function algorithm_iterator_get_next(this) result(operation)
268 class(algorithm_iterator_t), intent(inout) :: this
269 type(algorithmic_operation_t) :: operation
270
272
273 assert(this%has_next())
275 select type (ptr => this%get_next_ptr())
276 class is (algorithmic_operation_t)
277 operation = ptr
278 class default
279 assert(.false.)
280 end select
281
283 end function algorithm_iterator_get_next
284
285end module algorithm_oct_m
286
287!! Local Variables:
288!! mode: f90
289!! coding: utf-8
290!! End:
indicate whether the algorithm should continue executing after finishing, or should set a barrier
Definition: algorithm.F90:264
indicate whether the algorithm has finished one time step
Definition: algorithm.F90:243
initializes the algorithm and system iteration counters
Definition: algorithm.F90:250
Write the header for the execution log.
Definition: algorithm.F90:257
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:346
subroutine algorithm_rewind(this)
Reset the algorithm to the first operation.
Definition: algorithm.F90:316
type(algorithmic_operation_t) function algorithm_iterator_get_next(this)
Get the next algorithmic operation from the iterator.
Definition: algorithm.F90:361
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:275
subroutine algorithm_update_elapsed_time(this)
The elapsed time is used for the output of run time information.
Definition: algorithm.F90:303
subroutine algorithm_next(this)
move to the next algorithmic operation
Definition: algorithm.F90:333
logical function algorithm_do_operation(this, operation)
try to perform one operation of the algorithm. If successfull return .true.
Definition: algorithm.F90:289
type(algorithmic_operation_t), parameter, public op_update_interactions
Definition: algorithm.F90:179
real(real64), parameter, public m_zero
Definition: global.F90:187
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.