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
36 use math_oct_m
40 use parser_oct_m
55 use system_oct_m
56 implicit none
57
58 private
59 public :: propagator_factory_t
60
61 ! Known multisystem propagators
62 integer, public, parameter :: &
63 PROP_STATIC = 0, &
64 prop_verlet = 1, &
65 prop_beeman = 2, &
66 prop_beeman_scf = 3, &
69 prop_aetrs_ms = 6, &
70 prop_rk4 = 7, &
71 prop_expmid = 8, &
72 prop_leapfrog = 9, &
73 prop_bomd = 10, &
74 prop_expgauss1 = 11, &
76
77
80 private
81 real(real64) :: final_time
82 contains
83 procedure :: create => propagator_factory_create
84 procedure :: create_static => propagator_factory_create_static
86
87 interface propagator_factory_t
88 module procedure propagator_factory_constructor
89 end interface propagator_factory_t
90
91
92contains
93 ! ---------------------------------------------------------------------------------------
97 !
98 function propagator_factory_constructor(namespace) result(factory)
99 type(namespace_t), intent(in) :: namespace
100 type(propagator_factory_t) :: factory
101
103
104 ! Get final propagation time from input
105 ! This variable is also defined (and properly documented) in td/td.F90.
106 ! This is temporary, until all the propagators are moved to the new framework.
107 call parse_variable(namespace, 'TDPropagationTime', -1.0_real64, factory%final_time, unit = units_inp%time)
108 if (factory%final_time <= m_zero) then
109 call messages_input_error(namespace, 'TDPropagationTime', 'must be greater than zero')
110 end if
111 call messages_print_var_value('TDPropagationTime', factory%final_time)
112
115
116 ! ---------------------------------------------------------------------------------------
127 !
128 function propagator_factory_create(this, system) result(algorithm)
129 class(propagator_factory_t), intent(in) :: this
130 class(interaction_partner_t), intent(in), target :: system
131 class(algorithm_t), pointer :: algorithm
132
133 integer :: prop_type
134 real(real64) :: dt
135 class(propagator_t), pointer :: propagator
136
138
139 !%Variable TDSystemPropagator
140 !%Type integer
141 !%Default static
142 !%Section Time-Dependent::Propagation
143 !%Description
144 !% A variable to set the propagator in the multisystem framework.
145 !% This is a temporary solution, and should be replaced by the
146 !% TDPropagator variable.
147 !%Option static 0
148 !% (Experimental) Do not propagate the system in time.
149 !%Option verlet 1
150 !% (Experimental) Verlet propagator.
151 !%Option beeman 2
152 !% (Experimental) Beeman propagator without predictor-corrector.
153 !%Option beeman_scf 3
154 !% (Experimental) Beeman propagator with predictor-corrector scheme.
155 !%Option exp_mid_2step 4
156 !% (Experimental) Exponential midpoint propagator without predictor-corrector.
157 !%Option exp_mid_2step_scf 5
158 !% (Experimental) Exponential midpoint propagator with predictor-corrector scheme.
159 !%Option prop_aetrs 6
160 !% (Experimental) Approximate ETRS propagator
161 !%Option prop_rk4 7
162 !% (Experimental) RK4 propagator
163 !%Option prop_expmid 8
164 !% (Experimental) Exponential midpoint propagator with extrapolation.
165 !%Option prop_leapfrog 9
166 !% (Experimental) Leap frog algorithm
167 !%Option prop_bomd 10
168 !% (Experimental) Born-Oppenheimer MD propagator for the matter system.
169 !%Option prop_exp_gauss1 11
170 !% (Experimental) Exponential RK method with a Gauss quadrature rule with one point (second order)
171 !% see also Hochbruck, M. & Ostermann, A.: Exponential Runge–Kutta methods for parabolic
172 !% problems. Applied Numerical Mathematics 53, 323–339 (2005).
173 !%Option prop_exp_gauss2 12
174 !% (Experimental) Exponential RK method with a Gauss quadrature rule with two points (fourth order)
175 !% see also Hochbruck, M. & Ostermann, A.: Exponential Runge–Kutta methods for parabolic
176 !% problems. Applied Numerical Mathematics 53, 323–339 (2005).
177 !%End
178 call parse_variable(system%namespace, 'TDSystemPropagator', prop_static, prop_type)
179 if (.not. varinfo_valid_option('TDSystemPropagator', prop_type)) then
180 call messages_input_error(system%namespace, 'TDSystemPropagator')
181 end if
182 call messages_print_with_emphasis(msg='System propagator', namespace=system%namespace)
183 call messages_print_var_option('TDSystemPropagator', prop_type, namespace=system%namespace)
184
185 dt = propagator_factory_read_dt(this, system%namespace)
186
187 select case (prop_type)
188 case (prop_static)
189 propagator => propagator_static_t(dt, 1)
190 case (prop_verlet)
191 propagator => propagator_verlet_t(dt)
192 case (prop_beeman)
193 propagator => propagator_beeman_t(dt, predictor_corrector=.false.)
194 case (prop_beeman_scf)
195 propagator => propagator_beeman_t(dt, predictor_corrector=.true.)
196 case (prop_expmid_2step)
197 propagator => propagator_exp_mid_2step_t(dt, predictor_corrector=.false.)
199 propagator => propagator_exp_mid_2step_t(dt, predictor_corrector=.true.)
200 case (prop_aetrs_ms)
201 propagator => propagator_aetrs_t(dt)
202 case (prop_rk4)
203 propagator => propagator_rk4_t(dt)
204 case (prop_expmid)
205 propagator => propagator_exp_mid_t(dt)
206 case (prop_leapfrog)
207 propagator => propagator_leapfrog_t(dt)
208 case (prop_bomd)
209 propagator => propagator_bomd_t(dt)
210 case (prop_expgauss1)
211 propagator => propagator_exp_gauss1_t(dt)
212 case (prop_expgauss2)
213 propagator => propagator_exp_gauss2_t(dt)
214 case default
215 call messages_input_error(system%namespace, 'TDSystemPropagator')
216 end select
217
218 call messages_print_with_emphasis(namespace=system%namespace)
219
220 propagator%final_time = this%final_time
222 select type (system)
223 class is (system_t)
224 propagator%system => system
225 class default
226 assert(.false.)
227 end select
228
229 algorithm => propagator
230
232 end function propagator_factory_create
233
234 ! ---------------------------------------------------------------------------------------
240 !
241 function propagator_factory_create_static(this, system) result(algorithm)
242 class(propagator_factory_t), intent(in) :: this
243 class(interaction_partner_t), intent(in), target :: system
244 class(algorithm_t), pointer :: algorithm
245
246 real(real64) :: largest_dt, smallest_dt
247 type(system_iterator_t) :: iter
248 class(system_t), pointer :: subsystem
249 class(propagator_t), pointer :: propagator
250
252
253 ! Note: We need to pass the system as an interaction_partner_t, but we can only create a propagator
254 ! for systems.
255 select type (system)
256 type is (multisystem_basic_t)
257 ! The multisystem container is an exception, as its time-step and the
258 ! number of algorithmic steps is determined by the subsystems.
259 largest_dt = m_zero
260 smallest_dt = m_huge
261 call iter%start(system%list)
262 do while (iter%has_next())
263 subsystem => iter%get_next()
264 select type (subalgorithm => subsystem%algo)
265 class is (propagator_t)
266 largest_dt = max(largest_dt, subalgorithm%dt)
267 smallest_dt = min(smallest_dt, subalgorithm%dt/subalgorithm%algo_steps)
268 end select
269 end do
270 propagator => propagator_static_t(largest_dt, nsteps=int(largest_dt/smallest_dt))
271
272 class default
273 propagator => propagator_static_t(propagator_factory_read_dt(this, system%namespace), 1)
274 end select
275
276 propagator%final_time = this%final_time
277
278 select type (system)
279 class is (system_t)
280 propagator%system => system
281 class default
282 assert(.false.)
283 end select
284
285 algorithm => propagator
286
289
290 ! ---------------------------------------------------------------------------------------
292 !
293 real(real64) function propagator_factory_read_dt(this, namespace) result(dt)
294 class(propagator_factory_t), intent(in) :: this
295 type(namespace_t), intent(in) :: namespace
296
297 real(real64) :: dt_adjusted
298
299 ! This variable is also defined (and properly documented) in td/td.F90.
300 ! This is temporary, until all the propagators are moved to the new framework.
301 call parse_variable(namespace, 'TDTimeStep', 10.0_real64, dt)
302 if (dt <= m_zero) then
303 call messages_input_error(namespace, 'TDTimeStep', "must be greater than zero")
304 end if
305 call messages_print_var_value('TDTimeStep', dt, namespace=namespace)
306
307 ! Time-step needs to be a multiple of the minimum clock time-step
308 dt_adjusted = int(dt/clock_minimum_dt, int64) * clock_minimum_dt
309 message(1) = "The time-step was adjusted to make it commensurable with the minimum time-step:"
310 write(message(2), '(a,es21.14)') " requested time-step = ", dt
311 write(message(3), '(a,es21.14)') " adjusted time-step = ", dt_adjusted
312 call messages_info(3, namespace=namespace)
313 dt = dt_adjusted
314
315 end function propagator_factory_read_dt
316
318
319!! Local Variables:
320!! mode: f90
321!! coding: utf-8
322!! End:
Prints out to iunit a message in the form: ["InputVariable" = value] where "InputVariable" is given b...
Definition: messages.F90:180
This module defines the abstract interfact for algorithm factories.
This module implements the basic elements defining algorithms.
Definition: algorithm.F90:141
real(real64), 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:145
real(real64), parameter, public m_huge
Definition: global.F90:206
real(real64), parameter, public m_zero
Definition: global.F90:188
This module defines classes and functions for interaction partners.
This module is intended to contain "only mathematical" functions and procedures.
Definition: math.F90:115
subroutine, public messages_print_with_emphasis(msg, iunit, namespace)
Definition: messages.F90:920
character(len=512), private msg
Definition: messages.F90:165
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:160
subroutine, public messages_input_error(namespace, var, details, row, column)
Definition: messages.F90:713
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:616
This module implements the basic mulsisystem class, a container system for other systems.
This module implements the factory for propagators.
integer, parameter, public prop_expgauss2
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
real(real64) function propagator_factory_read_dt(this, namespace)
auxilliary function to read the time step from the input file
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_expgauss1
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:117
This module implements the abstract system type.
Definition: system.F90:118
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:200
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 an exponential RK scheme with Gauss collocation points, s=1 see also Hochbruck,...
Implements the an exponential RK scheme with Gauss collocation points, s=2 see also Hochbruck,...
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:138
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:172
int true(void)