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