Octopus
propagator_factory.F90
Go to the documentation of this file.
1!! Copyright (C) 2019 N. Tancogne-Dejean
2!! Copyright (C) 2020 M. Oliveira, Heiko Appel
3!! Copyright (C) 2021 S. Ohlmann
4!! Copyright (C) 2023 M. Oliveira
5!!
6!! This program is free software; you can redistribute it and/or modify
7!! it under the terms of the GNU General Public License as published by
8!! the Free Software Foundation; either version 2, or (at your option)
9!! any later version.
10!!
11!! This program is distributed in the hope that it will be useful,
12!! but WITHOUT ANY WARRANTY; without even the implied warranty of
13!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14!! GNU General Public License for more details.
15!!
16!! You should have received a copy of the GNU General Public License
17!! along with this program; if not, write to the Free Software
18!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19!! 02110-1301, USA.
20!!
21
22#include "global.h"
23
26
27
29 use, intrinsic :: iso_fortran_env
32 use clock_oct_m
33 use debug_oct_m
34 use global_oct_m
39 use parser_oct_m
52 use system_oct_m
53 implicit none
54
55 private
56 public :: propagator_factory_t
57
58 ! Known multisystem propagators
59 integer, public, parameter :: &
60 PROP_STATIC = 0, &
61 prop_verlet = 1, &
62 prop_beeman = 2, &
63 prop_beeman_scf = 3, &
66 prop_aetrs_ms = 6, &
67 prop_rk4 = 7, &
68 prop_expmid = 8, &
69 prop_leapfrog = 9, &
70 prop_bomd = 10
71
72
75 private
76 float :: final_time
77 contains
78 procedure :: create => propagator_factory_create
79 procedure :: create_static => propagator_factory_create_static
81
82 interface propagator_factory_t
83 module procedure propagator_factory_constructor
84 end interface propagator_factory_t
85
86
87contains
88 ! ---------------------------------------------------------------------------------------
92 !
93 function propagator_factory_constructor(namespace) result(factory)
94 type(namespace_t), intent(in) :: namespace
95 type(propagator_factory_t) :: factory
96
98
99 ! Get final propagation time from input
100 ! This variable is also defined (and properly documented) in td/td.F90.
101 ! This is temporary, until all the propagators are moved to the new framework.
102 call parse_variable(namespace, 'TDPropagationTime', -1.0_real64, factory%final_time, unit = units_inp%time)
103 if (factory%final_time <= m_zero) then
104 call messages_input_error(namespace, 'TDPropagationTime', 'must be greater than zero')
105 end if
106 call messages_print_var_value('TDPropagationTime', factory%final_time)
107
110
111 ! ---------------------------------------------------------------------------------------
122 !
123 function propagator_factory_create(this, system) result(algorithm)
124 class(propagator_factory_t), intent(in) :: this
125 class(interaction_partner_t), intent(in), target :: system
126 class(algorithm_t), pointer :: algorithm
127
128 integer :: prop_type
129 float :: dt
130 class(propagator_t), pointer :: propagator
131
133
134 !%Variable TDSystemPropagator
135 !%Type integer
136 !%Default static
137 !%Section Time-Dependent::Propagation
138 !%Description
139 !% A variable to set the propagator in the multisystem framework.
140 !% This is a temporary solution, and should be replaced by the
141 !% TDPropagator variable.
142 !%Option static 0
143 !% (Experimental) Do not propagate the system in time.
144 !%Option verlet 1
145 !% (Experimental) Verlet propagator.
146 !%Option beeman 2
147 !% (Experimental) Beeman propagator without predictor-corrector.
148 !%Option beeman_scf 3
149 !% (Experimental) Beeman propagator with predictor-corrector scheme.
150 !%Option exp_mid_2step 4
151 !% (Experimental) Exponential midpoint propagator without predictor-corrector.
152 !%Option exp_mid_2step_scf 5
153 !% (Experimental) Exponential midpoint propagator with predictor-corrector scheme.
154 !%Option prop_aetrs 6
155 !% (Experimental) Approximate ETRS propagator
156 !%Option prop_rk4 7
157 !% (Experimental) RK4 propagator
158 !%Option prop_expmid 8
159 !% (Experimental) Exponential midpoint propagator with extrapolation.
160 !%Option prop_leapfrog 9
161 !% (Experimental) Leap frog algorithm
162 !%Option prop_bomd 10
163 !% (Experimental) Born-Oppenheimer MD propagator for the matter system.
164 !%End
165 call parse_variable(system%namespace, 'TDSystemPropagator', prop_static, prop_type)
166 if (.not. varinfo_valid_option('TDSystemPropagator', prop_type)) then
167 call messages_input_error(system%namespace, 'TDSystemPropagator')
168 end if
169 call messages_print_with_emphasis(msg='System propagator', namespace=system%namespace)
170 call messages_print_var_option('TDSystemPropagator', prop_type, namespace=system%namespace)
171
172 dt = propagator_factory_read_dt(this, system%namespace)
173
174 select case (prop_type)
175 case (prop_static)
176 propagator => propagator_static_t(dt, 1)
178 propagator => propagator_verlet_t(dt)
179 case (prop_beeman)
180 propagator => propagator_beeman_t(dt, predictor_corrector=.false.)
181 case (prop_beeman_scf)
182 propagator => propagator_beeman_t(dt, predictor_corrector=.true.)
183 case (prop_expmid_2step)
184 propagator => propagator_exp_mid_2step_t(dt, predictor_corrector=.false.)
186 propagator => propagator_exp_mid_2step_t(dt, predictor_corrector=.true.)
187 case (prop_aetrs_ms)
188 propagator => propagator_aetrs_t(dt)
189 case (prop_rk4)
190 propagator => propagator_rk4_t(dt)
191 case (prop_expmid)
192 propagator => propagator_exp_mid_t(dt)
193 case (prop_leapfrog)
194 propagator => propagator_leapfrog_t(dt)
195 case (prop_bomd)
196 propagator => propagator_bomd_t(dt)
197 case default
198 call messages_input_error(system%namespace, 'TDSystemPropagator')
199 end select
200
201 call messages_print_with_emphasis(namespace=system%namespace)
202
203 propagator%final_time = this%final_time
204
205 select type (system)
206 class is (system_t)
207 propagator%system => system
208 class default
209 assert(.false.)
210 end select
211
212 algorithm => propagator
213
215 end function propagator_factory_create
216
217 ! ---------------------------------------------------------------------------------------
223 !
224 function propagator_factory_create_static(this, system) result(algorithm)
225 class(propagator_factory_t), intent(in) :: this
226 class(interaction_partner_t), intent(in), target :: system
227 class(algorithm_t), pointer :: algorithm
228
229 float :: largest_dt, smallest_dt
230 type(system_iterator_t) :: iter
231 class(system_t), pointer :: subsystem
232 class(propagator_t), pointer :: propagator
233
235
236 ! Note: We need to pass the system as an interaction_partner_t, but we can only create a propagator
237 ! for systems.
238 select type (system)
239 type is (multisystem_basic_t)
240 ! The multisystem container is an exception, as its time-step and the
241 ! number of algorithmic steps is determined by the subsystems.
242 largest_dt = m_zero
243 smallest_dt = m_huge
244 call iter%start(system%list)
245 do while (iter%has_next())
246 subsystem => iter%get_next()
247 select type (subalgorithm => subsystem%algo)
248 class is (propagator_t)
249 largest_dt = max(largest_dt, subalgorithm%dt)
250 smallest_dt = min(smallest_dt, subalgorithm%dt/subalgorithm%algo_steps)
251 end select
252 end do
253 propagator => propagator_static_t(largest_dt, nsteps=int(largest_dt/smallest_dt))
254
255 class default
256 propagator => propagator_static_t(propagator_factory_read_dt(this, system%namespace), 1)
257 end select
258
259 propagator%final_time = this%final_time
260
261 select type (system)
262 class is (system_t)
263 propagator%system => system
264 class default
265 assert(.false.)
266 end select
267
268 algorithm => propagator
269
272
273 ! ---------------------------------------------------------------------------------------
275 !
276 float function propagator_factory_read_dt(this, namespace) result(dt)
277 class(propagator_factory_t), intent(in) :: this
278 type(namespace_t), intent(in) :: namespace
279
280 float :: dt_adjusted
281
282 ! This variable is also defined (and properly documented) in td/td.F90.
283 ! This is temporary, until all the propagators are moved to the new framework.
284 call parse_variable(namespace, 'TDTimeStep', 10.0_real64, dt)
285 if (dt <= m_zero) then
286 call messages_input_error(namespace, 'TDTimeStep', "must be greater than zero")
287 end if
288 call messages_print_var_value('TDTimeStep', dt, namespace=namespace)
289
290 ! Time-step needs to be a multiple of the minimum clock time-step
291 dt_adjusted = int(dt/clock_minimum_dt, int64) * clock_minimum_dt
292 if (dt_adjusted /= dt) then
293 message(1) = "The time-step was adjusted to make it commensurable with the minimum time-step:"
294 write(message(2), '(a,es21.15)') " requested time-step = ", dt
295 write(message(3), '(a,es21.15)') " adjusted time-step = ", dt_adjusted
296 call messages_warning(3, namespace=namespace)
297 dt = dt_adjusted
298 end if
299
300 end function propagator_factory_read_dt
301
303
304!! Local Variables:
305!! mode: f90
306!! coding: utf-8
307!! End:
Prints out to iunit a message in the form: ["InputVariable" = value] where "InputVariable" is given b...
Definition: messages.F90:170
This module defines the abstract interfact for algorithm factories.
This module implements the basic elements defining algorithms.
Definition: algorithm.F90:132
real(8), parameter, public clock_minimum_dt
This CLOCK_MINIMUM_DT parameter defines what is the time-step in the common reference frame of all cl...
Definition: clock.F90:136
real(8), parameter, public m_huge
Definition: global.F90:185
real(8), parameter, public m_zero
Definition: global.F90:167
This module defines classes and functions for interaction partners.
subroutine, public messages_print_with_emphasis(msg, iunit, namespace)
Definition: messages.F90:910
character(len=512), private msg
Definition: messages.F90:156
subroutine, public messages_warning(no_lines, all_nodes, namespace)
Definition: messages.F90:522
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:151
subroutine, public messages_input_error(namespace, var, details, row, column)
Definition: messages.F90:702
This module implements the basic mulsisystem class, a container system for other systems.
This module implements the factory for propagators.
real(8) function propagator_factory_read_dt(this, namespace)
auxilliary function to read the time step from the input file
type(propagator_factory_t) function propagator_factory_constructor(namespace)
Constructor for the propagator factory.
integer, parameter, public prop_verlet
integer, parameter, public prop_aetrs_ms
integer, parameter, public prop_beeman_scf
integer, parameter, public prop_bomd
class(algorithm_t) function, pointer propagator_factory_create_static(this, system)
Create a static propagator.
integer, parameter, public prop_expmid
integer, parameter, public prop_expmid_2step
integer, parameter, public prop_expmid_2step_scf
integer, parameter, public prop_rk4
class(algorithm_t) function, pointer propagator_factory_create(this, system)
Create a general propagator.
integer, parameter, public prop_beeman
integer, parameter, public prop_leapfrog
This module implements the basic propagator framework.
Definition: propagator.F90:108
This module implements the abstract system type.
Definition: system.F90:109
This module defines the unit system, used for input and output.
type(unit_system_t), public units_inp
the units systems for reading and writing
Abstract class for the algorithm factories.
An algorithm is a list of algorithmic operations executed sequentially.
Definition: algorithm.F90:191
abstract class for general interaction partners
Container class for lists of system_oct_m::system_t.
Implements a propagator for Approximate ETRS.
Implements the Beeman propagator (with or without SCF)
Implements a propagator for Born-Oppenheimer molecular dynamics.
Implements the implicit exponential midpoint propagator with predictor-corrector.
Implements the explicit exponential midpoint propagator (without predictor-corrector)
This class defines the factory for propagators.
Implements a propagator for the leap frog algorithm.
Abstract class implementing propagators.
Definition: propagator.F90:129
Implements a the 4th order Runge Kutta propagator.
Implements a propagator that keeps the state of the system constant. Note that a time-step is still r...
Implements a propagator for the velocity Verlet algorithm.
Abstract class for systems.
Definition: system.F90:161
int true(void)