Octopus
propagator_elec.F90
Go to the documentation of this file.
1!! Copyright (C) 2002-2006 M. Marques, A. Castro, A. Rubio, G. Bertsch
2!!
3!! This program is free software; you can redistribute it and/or modify
4!! it under the terms of the GNU General Public License as published by
5!! the Free Software Foundation; either version 2, or (at your option)
6!! any later version.
7!!
8!! This program is distributed in the hope that it will be useful,
9!! but WITHOUT ANY WARRANTY; without even the implied warranty of
10!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11!! GNU General Public License for more details.
12!!
13!! You should have received a copy of the GNU General Public License
14!! along with this program; if not, write to the Free Software
15!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16!! 02110-1301, USA.
17!!
18
19#include "global.h"
20
22 use debug_oct_m
28 use forces_oct_m
30 use grid_oct_m
31 use global_oct_m
35 use ions_oct_m
36 use, intrinsic :: iso_fortran_env
37 use lasers_oct_m
38 use lda_u_oct_m
40 use parser_oct_m
58 use scf_oct_m
60 use space_oct_m
62 use stress_oct_m
64 use v_ks_oct_m
66 use xc_oct_m
67
68 implicit none
69
70 private
71 public :: &
80
81contains
82
83 ! ---------------------------------------------------------
84 subroutine propagator_elec_copy(tro, tri)
85 type(propagator_base_t), intent(inout) :: tro
86 type(propagator_base_t), intent(in) :: tri
87
88 push_sub(propagator_elec_copy)
89
90 tro%method = tri%method
91
92 select case (tro%method)
94 tro%tdsk_size = tri%tdsk_size
95 call sparskit_solver_copy(tro%tdsk, tri%tdsk)
96
98 tro%tdsk_size = tri%tdsk_size
99 call sparskit_solver_copy(tro%tdsk, tri%tdsk)
100
101 case (prop_runge_kutta2)
102 tro%tdsk_size = tri%tdsk_size
103 call sparskit_solver_copy(tro%tdsk, tri%tdsk)
104
105 end select
106
107 call potential_interpolation_copy(tro%vks_old, tri%vks_old)
108
109 call exponential_copy(tro%te, tri%te)
110 tro%scf_propagation_steps = tri%scf_propagation_steps
111
112 tro%scf_threshold = tri%scf_threshold
113 pop_sub(propagator_elec_copy)
114 end subroutine propagator_elec_copy
115 ! ---------------------------------------------------------
116
117
118 ! ---------------------------------------------------------
119 subroutine propagator_elec_init(gr, namespace, st, tr, ks_pot, have_fields, family_is_mgga_with_exc, relax_cell)
120 type(grid_t), intent(in) :: gr
121 type(namespace_t), intent(in) :: namespace
122 type(states_elec_t), intent(in) :: st
123 type(propagator_base_t), intent(inout) :: tr
124 type(ks_potential_t), intent(in) :: ks_pot
128 logical, intent(in) :: have_fields
129 logical, intent(in) :: family_is_mgga_with_exc
130 logical, intent(in) :: relax_cell
131
132 push_sub(propagator_elec_init)
133
134 if (st%requires_generalized_overlap) then
135 call messages_not_implemented("TDDFT propagation with ultrasoft/PAW generalized overlap", namespace=namespace)
136 end if
137
138 !%Variable TDPropagator
139 !%Type integer
140 !%Default etrs
141 !%Section Time-Dependent::Propagation
142 !%Description
143 !% This variable determines which algorithm will be used to approximate
144 !% the evolution operator <math>U(t+\delta t, t)</math>. That is, given
145 !% <math>\psi(\tau)</math> and <math>H(\tau)</math> for <math>\tau \le t</math>,
146 !% calculate <math>t+\delta t</math>. Note that in general the Hamiltonian
147 !% is not known at times in the interior of the interval <math>[t,t+\delta t]</math>.
148 !% This is due to the self-consistent nature of the time-dependent Kohn-Sham problem:
149 !% the Hamiltonian at a given time <math>\tau</math> is built from the
150 !% "solution" wavefunctions at that time.
151 !%
152 !% Some methods, however, do require the knowledge of the Hamiltonian at some
153 !% point of the interval <math>[t,t+\delta t]</math>. This problem is solved by making
154 !% use of extrapolation: given a number <math>l</math> of time steps previous to time
155 !% <math>t</math>, this information is used to build the Hamiltonian at arbitrary times
156 !% within <math>[t,t+\delta t]</math>. To be fully precise, one should then proceed
157 !% <i>self-consistently</i>: the obtained Hamiltonian at time <math>t+\delta t</math>
158 !% may then be used to interpolate the Hamiltonian, and repeat the evolution
159 !% algorithm with this new information. Whenever iterating the procedure does
160 !% not change the solution wavefunctions, the cycle is stopped. In practice,
161 !% in <tt>Octopus</tt> we perform a second-order extrapolation without a
162 !% self-consistency check, except for the first two iterations, where obviously
163 !% the extrapolation is not reliable.
164 !%
165 !% The proliferation of methods is certainly excessive. The reason for it is that
166 !% the propagation algorithm is currently a topic of active development. We
167 !% hope that in the future the optimal schemes are clearly identified. In the
168 !% mean time, if you do not feel like testing, use the default choices and
169 !% make sure the time step is small enough.
170 !%
171 !% More details about the propagation methods could be found in
172 !% A. Castro, M.A.L. Marques, and A. Rubio, J. Chem. Phys 121 3425-3433 (2004)
173 !% and
174 !% A. Pueyo et al., J. Chem. Theory Comput. 14, 6, 3040 (2018)
175 !%
176 !%Option etrs 2
177 !% The idea is to make use of time-reversal symmetry from the beginning:
178 !%
179 !% <math>
180 !% \exp \left(-i\delta t H_{n} / 2 \right)\psi_n = \exp \left(i\delta t H_{n+1} / 2 \right)\psi_{n+1},
181 !% </math>
182 !%
183 !% and then invert to obtain:
184 !%
185 !% <math>
186 !% \psi_{n+1} = \exp \left(-i\delta t H_{n+1} / 2 \right) \exp \left(-i\delta t H_{n} / 2 \right)\psi_{n}.
187 !% </math>
188 !%
189 !% But we need to know <math>H_{n+1}</math>, which can only be known exactly through the solution
190 !% <math>\psi_{n+1}</math>. What we do is to estimate it by performing a single exponential:
191 !% <math>\psi\^{\*}\_{n+1}=\exp \left( -i\delta t H_{n} \right) \psi_n</math>, and then
192 !% <math>H_{n+1} = H[\psi\^{\*}_{n+1}]</math>. Thus no extrapolation is performed in this case.
193 !%Option aetrs 3
194 !% Approximated Enforced Time-Reversal Symmetry (AETRS).
195 !% A modification of previous method to make it faster.
196 !% It is based on extrapolation of the time-dependent potentials. It is faster
197 !% by about 40%.
198 !% The only difference is the procedure to estimate <math>H_{n+1}</math>: in this case
199 !% it is extrapolated via a second-order polynomial by making use of the
200 !% Hamiltonian at time <math>t-2\delta t</math>, <math>t-\delta t</math> and <math>t</math>.
201 !%Option caetrs 12
202 !% (experimental) Corrected Approximated Enforced Time-Reversal
203 !% Symmetry (AETRS), this is the previous propagator but including
204 !% a correction step to the exponential.
205 !%Option exp_mid 4
206 !% Exponential Midpoint Rule (EM).
207 !% This is maybe the simplest method, but it is very well grounded theoretically:
208 !% it is unitary (if the exponential is performed correctly) and preserves
209 !% time-reversal symmetry (if the self-consistency problem is dealt with correctly).
210 !% It is defined as:
211 !% <math>
212 !% U_{\rm EM}(t+\delta t, t) = \exp \left( -i\delta t H_{t+\delta t/2}\right)\,.
213 !% </math>
214 !%Option crank_nicholson 5
215 !%Option crank_nicolson 5
216 !% Classical Crank-Nicolson propagator.
217 !% <math>
218 !% (1 + i\delta t H_{n+1/2} / 2) \psi_{n+1} = (1 - i\delta t H_{n+1/2} / 2) \psi_{n}
219 !% </math>
220 !%Option crank_nicholson_sparskit 6
221 !%Option crank_nicolson_sparskit 6
222 !% Classical Crank-Nicolson propagator. Requires the SPARSKIT library.
223 !% <math>
224 !% (1 + i\delta t H_{n+1/2} / 2) \psi_{n+1} = (1 - i\delta t H_{n+1/2} / 2) \psi_{n}
225 !% </math>
226 !%Option magnus 7
227 !% Magnus Expansion (M4).
228 !% This is the most sophisticated approach. It is a fourth-order scheme (a feature
229 !% which it shares with the ST scheme; the other schemes are in principle second-order).
230 !% It is tailored for making use of very large time steps, or equivalently,
231 !% dealing with problem with very high-frequency time-dependence.
232 !% It is still in a experimental state; we are not yet sure of when it is
233 !% advantageous.
234 !%Option qoct_tddft_propagator 10
235 !% WARNING: EXPERIMENTAL
236 !%Option runge_kutta4 13
237 !% WARNING: EXPERIMENTAL. Implicit Gauss-Legendre 4th order Runge-Kutta.
238 !%Option runge_kutta2 14
239 !% WARNING: EXPERIMENTAL. Implicit 2nd order Runge-Kutta (trapezoidal rule).
240 !% Similar, but not identical, to Crank-Nicolson method.
241 !%Option expl_runge_kutta4 15
242 !% WARNING: EXPERIMENTAL. Explicit RK4 method.
243 !%Option cfmagnus4 16
244 !% Commutator-free magnus expansion. This method has been developed for linear
245 !% systems and involves products of exponentials to avoid commutators. To apply it
246 !% to our non-linear equations, we extrapolate the potential from previous timesteps
247 !% to the times needed.The fourth-ordermethod implemented here follows equation 54
248 !% in Gómez Pueyo, A., Marques, M. A. L., Rubio, A. & Castro, A. Propagators for the
249 !% Time-Dependent Kohn–Sham Equations: Multistep, Runge–Kutta, Exponential Runge–Kutta,
250 !% and Commutator Free Magnus Methods. J. Chem. Theory Comput. 14, 3040–3052 (2018)
251 !% which corresponds to equation 43 in Blanes, S. & Moan, P. C. Fourth- and sixth-order
252 !% commutator-free Magnus integrators for linear and non-linear dynamical systems.
253 !% Applied Numerical Mathematics 56, 1519–1537 (2006):
254 !% <math>
255 !% \psi(t+\Delta t) = \exp(-i \Delta t ( \alpha_1 H(t_1) + \alpha_2 H(t_2) ) )
256 !% \exp(-i \Delta t ( \alpha_2 H(t_1) + \alpha_1 H(t_2) ) ) \psi(t),
257 !% </math>
258 !% with $\alpha_{1,2} = \frac{3\mp 2\sqrt{3}}{12}$ and $t_i = t_0 + c_i \Delta t$,
259 !% $c_{1,2} = \frac{1}{2} \mp \frac{\sqrt{3}}{6}$.
260 !% Still in experimental state.
261 !%Option exp_mid_predictor 17
262 !% Exponential Midpoint Rule (EM).
263 !% This is maybe the simplest method, but it is very well grounded theoretically:
264 !% it is unitary (if the exponential is performed correctly) and preserves
265 !% time-reversal symmetry (if the self-consistency problem is dealt with correctly).
266 !% It is defined as:
267 !% <math>
268 !% U_{\rm EM}(t+\delta t, t) = \exp \left( -i\delta t H_{t+\delta t/2}\right)\,.
269 !% </math>
270 !% As opposed to the exp_mid propagator, $H_{t+\delta t/2}$ is not obtained by
271 !% extrapolation from previous timesteps, but by predicting by applying the exponential with
272 !% $\delta t/2$ and computing the corresponding density and potential.
273 !% It is equivalent to an explicit Magnus integration of second order, see equation 20 in
274 !% Casas, F. & Iserles, A. Explicit Magnus expansions for nonlinear equations. J. Phys. A: Math. Gen. 39,
275 !% 5445 (2006) [https://dx.doi.org/10.1088/0305-4470/39/19/S07]
276 !%Option explicit_magnus3 18
277 !% Third-order explicit Magnus expansion.
278 !% This method follows equations 22 in
279 !% Casas, F. & Iserles, A. Explicit Magnus expansions for nonlinear equations.
280 !% J. Phys. A: Math. Gen. 39, 5445 (2006) [https://dx.doi.org/10.1088/0305-4470/39/19/S07]
281 !% Applying eq. 22 to our notation for the Schrödinger equation yields:
282 !% <math>
283 !% \psi_0 = \psi(t) \\
284 !% H_1 = H(t, \psi_0) \\
285 !% \psi_2 = \exp(-i \frac{\Delta t}{2} H_1) \psi_0 \\
286 !% H_2 = H(t+\frac{\Delta t}{2}, \psi_2) \\
287 !% \psi_3 = \exp(-i \frac{\Delta t}{4} (H_1 + H_2)) \psi_0 \\
288 !% H_3 = H(t+\frac{\Delta t}{2}, \psi_3) \\
289 !% \psi_4 = \exp(-i \Delta t H_2) \psi_0 \\
290 !% H_4 = H(t+\Delta t, \psi_4) \\
291 !% \psi(t+\Delta t) = \exp(-i \Delta t ( \frac{1}{6}(H_1 + 4 H_3 + H_4)
292 !% + \frac{i \Delta t}{12} ( [H_1 + H_2, H_3] + [H_2, H_4]))) \psi_0
293 !% </math>
294 !% Still in experimental state.
295 !%End
296 call messages_obsolete_variable(namespace, 'TDEvolutionMethod', 'TDPropagator')
297
298 call parse_variable(namespace, 'TDPropagator', prop_etrs, tr%method)
299 if (.not. varinfo_valid_option('TDPropagator', tr%method)) call messages_input_error(namespace, 'TDPropagator')
300
301 select case (tr%method)
302 case (prop_etrs)
303 case (prop_aetrs)
304 case (prop_caetrs)
305 call messages_experimental("CAETRS propagator", namespace=namespace)
309 ! set up pointer for zmf_dotu_aux, zmf_nrm2_aux
310 call mesh_init_mesh_aux(gr)
311 case (prop_runge_kutta4)
312 ! set up pointer for zmf_dotu_aux, zmf_nrm2_aux
313 call mesh_init_mesh_aux(gr)
315 tr%tdsk_size = 2 * st%d%dim * gr%np * (st%st_end - st%st_start + 1) * (st%d%kpt%end - st%d%kpt%start + 1)
316 call sparskit_solver_init(namespace, tr%tdsk_size, tr%tdsk, .true.)
317
318#ifndef HAVE_SPARSKIT
319 message(1) = 'Octopus was not compiled with support for the SPARSKIT library. This'
320 message(2) = 'library is required if the "runge_kutta4" propagator is selected.'
321 message(3) = 'Try using a different propagation scheme or recompile with SPARSKIT support.'
322 call messages_fatal(3, namespace=namespace)
323#endif
324
325 call messages_experimental("Runge-Kutta 4 propagator", namespace=namespace)
326 case (prop_runge_kutta2)
327
328 ! set up pointer for zmf_dotu_aux, zmf_nrm2_aux
329 call mesh_init_mesh_aux(gr)
331 tr%tdsk_size = st%d%dim * gr%np * (st%st_end - st%st_start + 1) * (st%d%kpt%end - st%d%kpt%start + 1)
332 call sparskit_solver_init(namespace, tr%tdsk_size, tr%tdsk, .true.)
333
334#ifndef HAVE_SPARSKIT
335 message(1) = 'Octopus was not compiled with support for the SPARSKIT library. This'
336 message(2) = 'library is required if the "runge_kutta2" propagator is selected.'
337 message(3) = 'Try using a different propagation scheme or recompile with SPARSKIT support.'
338 call messages_fatal(3, namespace=namespace)
339#endif
340
341 call messages_experimental("Runge-Kutta 2 propagator", namespace=namespace)
343 ! set up pointer for zmf_dotu_aux
344 call mesh_init_mesh_aux(gr)
346 tr%tdsk_size = st%d%dim*gr%np
347 call sparskit_solver_init(namespace, st%d%dim*gr%np, tr%tdsk, .true.)
348
349#ifndef HAVE_SPARSKIT
350 message(1) = 'Octopus was not compiled with support for the SPARSKIT library. This'
351 message(2) = 'library is required if the "crank_nicolson_sparskit" propagator is selected.'
352 message(3) = 'Try using a different propagation scheme or recompile with SPARSKIT support.'
353 call messages_fatal(3, namespace=namespace)
354#endif
355 case (prop_magnus)
356 call messages_experimental("Magnus propagator", namespace=namespace)
357 if (family_is_mgga_with_exc) then
358 message(1) = "Magnus propagator with MGGA"
359 call messages_fatal(1, namespace=namespace)
360 end if
362 call messages_experimental("QOCT+TDDFT propagator", namespace=namespace)
364 call messages_experimental("explicit Runge-Kutta 4 propagator", namespace=namespace)
365 case (prop_cfmagnus4)
366 call messages_experimental("Commutator-Free Magnus propagator", namespace=namespace)
368 call messages_experimental("Explicit Magnus 3 propagator", namespace=namespace)
369 case default
370 call messages_input_error(namespace, 'TDPropagator')
371 end select
372 call messages_print_var_option('TDPropagator', tr%method, namespace=namespace)
373
374 if (have_fields) then
375 if (tr%method /= prop_etrs .and. &
376 tr%method /= prop_aetrs .and. &
377 tr%method /= prop_exponential_midpoint .and. &
378 tr%method /= prop_exponential_midpoint_predictor .and. &
379 tr%method /= prop_cfmagnus4 .and. &
380 tr%method /= prop_explicit_magnus3 .and. &
381 tr%method /= prop_qoct_tddft_propagator .and. &
382 tr%method /= prop_crank_nicolson .and. &
383 tr%method /= prop_runge_kutta4 .and. &
384 tr%method /= prop_explicit_runge_kutta4 .and. &
385 tr%method /= prop_runge_kutta2 .and. &
386 tr%method /= prop_crank_nicolson_sparskit) then
387 message(1) = "To move the ions or put in a gauge field, use one of the following propagators:"
388 message(2) = "etrs, aetrs, cfmagnus4, crank-nicolson, rk2, rk4, or exp_mid."
389 call messages_fatal(2, namespace=namespace)
390 end if
391 end if
392
393 if (relax_cell) then
394 if (tr%method /= prop_etrs .and. &
395 tr%method /= prop_aetrs .and. &
396 tr%method /= prop_exponential_midpoint .and. &
397 tr%method /= prop_exponential_midpoint_predictor .and. &
398 tr%method /= prop_cfmagnus4 .and. &
399 tr%method /= prop_explicit_magnus3 .and. &
400 tr%method /= prop_crank_nicolson .and. &
401 tr%method /= prop_crank_nicolson_sparskit) then
402 message(1) = "To relax the cell, use the one of the following propagators:"
403 message(2) = "etrs, aetrs, cfmagnus4, crank-nicolson, or exp_mid."
404 call messages_fatal(2, namespace=namespace)
405 end if
406 end if
407
408 select case (tr%method)
409 case (prop_cfmagnus4)
410 call ks_pot%init_interpolation(tr%vks_old, order = 4)
411 case default
412 call ks_pot%init_interpolation(tr%vks_old)
413 end select
414
415 call exponential_init(tr%te, namespace) ! initialize propagator
416
417 call messages_obsolete_variable(namespace, 'TDSelfConsistentSteps', 'TDStepsWithSelfConsistency')
418
419 !%Variable TDStepsWithSelfConsistency
420 !%Type integer
421 !%Default 0
422 !%Section Time-Dependent::Propagation
423 !%Description
424 !% Since the KS propagator is non-linear, each propagation step
425 !% should be performed self-consistently. In practice, for most
426 !% purposes this is not necessary, except perhaps in the first
427 !% iterations. This variable holds the number of propagation steps
428 !% for which the propagation is done self-consistently.
429 !%
430 !% The special value <tt>all_steps</tt> forces self-consistency to
431 !% be imposed on all propagation steps. A value of 0 means that
432 !% self-consistency will not be imposed. The default is 0.
433 !%Option all_steps -1
434 !% Self-consistency is imposed for all propagation steps.
435 !%End
436
437 call parse_variable(namespace, 'TDStepsWithSelfConsistency', 0, tr%scf_propagation_steps)
438
439 if (tr%scf_propagation_steps == -1) tr%scf_propagation_steps = huge(tr%scf_propagation_steps)
440 if (tr%scf_propagation_steps < 0) call messages_input_error(namespace, 'TDStepsWithSelfConsistency', 'Cannot be negative')
441
442 if (tr%scf_propagation_steps /= 0) then
443 call messages_experimental('TDStepsWithSelfConsistency', namespace=namespace)
444
445 if (tr%method /= prop_etrs .and. tr%method /= prop_aetrs .and. tr%method /= prop_cfmagnus4) then
446 call messages_write('TDStepsWithSelfConsistency only works with the ETRS/AETRS/CFM4 propagators')
447 call messages_fatal(namespace=namespace)
448 end if
449 end if
450
451 !%Variable TDSCFThreshold
452 !%Type float
453 !%Default 1.0e-6
454 !%Section Time-Dependent::Propagation
455 !%Description
456 !% Since the KS propagator is non-linear, each propagation step
457 !% should be performed self-consistently. In practice, for most
458 !% purposes this is not necessary, except perhaps in the first
459 !% iterations. This variable holds the number of propagation steps
460 !% for which the propagation is done self-consistently.
461 !%
462 !% The self consistency has to be measured against some accuracy
463 !% threshold. This variable controls the value of that threshold.
464 !%End
465 call parse_variable(namespace, 'TDSCFThreshold', 1.0e-6_real64, tr%scf_threshold)
466
467 pop_sub(propagator_elec_init)
468 end subroutine propagator_elec_init
469 ! ---------------------------------------------------------
470
471
472 ! ---------------------------------------------------------
473 subroutine propagator_elec_set_scf_prop(tr, threshold)
474 type(propagator_base_t), intent(inout) :: tr
475 real(real64), optional, intent(in) :: threshold
476
478
479 tr%scf_propagation_steps = huge(1)
480 if (present(threshold)) then
481 tr%scf_threshold = threshold
482 end if
483
485 end subroutine propagator_elec_set_scf_prop
486 ! ---------------------------------------------------------
487
488
489 ! ---------------------------------------------------------
491 type(propagator_base_t), intent(inout) :: tr
492
494
495 tr%scf_propagation_steps = -1
496
499 ! ---------------------------------------------------------
500
501
502 ! ---------------------------------------------------------
503 subroutine propagator_elec_end(tr)
504 type(propagator_base_t), intent(inout) :: tr
505
506 push_sub(propagator_elec_end)
507
508 call potential_interpolation_end(tr%vks_old)
509
510 select case (tr%method)
512 call propagator_rk_end()
513 call sparskit_solver_end(tr%tdsk)
514
516 call sparskit_solver_end(tr%tdsk)
517
518 end select
519
520 if (allocated(tr%st)) then
521 call states_elec_end(tr%st)
522 safe_deallocate_a(tr%st)
523 end if
524
525 pop_sub(propagator_elec_end)
526 end subroutine propagator_elec_end
527 ! ---------------------------------------------------------
528
529
530 ! ---------------------------------------------------------
533 ! ---------------------------------------------------------
534 subroutine propagator_elec_dt(ks, namespace, space, hm, gr, st, tr, time, dt, nt, &
535 ions_dyn, ions, ext_partners, mc, outp, write_handler, scsteps, update_energy, qcchi, dmp)
536 type(v_ks_t), target, intent(inout) :: ks
537 type(namespace_t), intent(in) :: namespace
538 type(electron_space_t), intent(in) :: space
539 type(hamiltonian_elec_t), target, intent(inout) :: hm
540 type(grid_t), target, intent(inout) :: gr
541 type(states_elec_t), target, intent(inout) :: st
542 type(propagator_base_t), target, intent(inout) :: tr
543 real(real64), intent(in) :: time
544 real(real64), intent(in) :: dt
545 integer, intent(in) :: nt
546 type(ion_dynamics_t), intent(inout) :: ions_dyn
547 type(ions_t), intent(inout) :: ions
548 type(partner_list_t), intent(in) :: ext_partners
549 type(multicomm_t), intent(inout) :: mc
550 type(output_t), intent(in) :: outp
551 type(td_write_t), intent(in) :: write_handler
552 integer, optional, intent(out) :: scsteps
553 logical, optional, intent(in) :: update_energy
554 type(opt_control_state_t), optional, target, intent(inout) :: qcchi
555 type(dmp_t), optional, intent(inout) :: dmp
556 type(gauge_field_t), pointer :: gfield
557 type(lasers_t), pointer :: lasers
558 logical :: generate, update_energy_
559 real(real64) :: am(space%dim)
560
561 call profiling_in("TD_PROPAGATOR")
562 push_sub(propagator_elec_dt)
563
564 update_energy_ = optional_default(update_energy, .true.)
565
566 call hm%ks_pot%interpolation_new(tr%vks_old, time, dt)
567
568 if (present(scsteps)) scsteps = 1
569
570 select case (tr%method)
571 case (prop_etrs)
572 if (self_consistent_step()) then
573 call td_etrs_sc(ks, namespace, space, hm, ext_partners, gr, st, tr, time, dt, &
574 ions_dyn, ions, mc, tr%scf_threshold, scsteps)
575 else
576 call td_etrs(ks, namespace, space, hm, ext_partners, gr, st, tr, time, dt, &
577 ions_dyn, ions, mc)
578 end if
579 case (prop_aetrs)
580 if (self_consistent_step()) then
581 call td_aetrs_sc(ks, namespace, space, hm, ext_partners, gr, st, tr, time, dt, &
582 ions_dyn, ions, mc, tr%scf_threshold, scsteps)
583 else
584 call td_aetrs(namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc)
585 end if
586 case (prop_caetrs)
587 call td_caetrs(ks, namespace, space, hm, ext_partners, gr, st, tr, time, dt, ions_dyn, ions, mc)
589 call exponential_midpoint(hm, namespace, space, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc)
591 call exponential_midpoint_predictor(hm, ks, namespace, space, gr, st, tr, time, dt, ions_dyn, ions, &
592 ext_partners, mc)
594 call td_crank_nicolson(hm, namespace, space, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc, .false.)
595 case (prop_runge_kutta4)
596 call td_runge_kutta4(ks, namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners)
597 case (prop_runge_kutta2)
598 call td_runge_kutta2(ks, namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners)
600 call td_crank_nicolson(hm, namespace, space, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc, .true.)
601 case (prop_magnus)
602 call td_magnus(hm, ext_partners, gr, st, tr, namespace, time, dt)
604 call td_qoct_tddft_propagator(hm, namespace, space, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc)
606 if (present(qcchi)) then
607 call td_explicit_runge_kutta4(ks, namespace, space, hm, gr, st, time, dt, ions_dyn, ions, ext_partners, qcchi)
608 else
609 call td_explicit_runge_kutta4(ks, namespace, space, hm, gr, st, time, dt, ions_dyn, ions, ext_partners)
610 end if
611 case (prop_cfmagnus4)
612 if (self_consistent_step()) then
613 call td_cfmagnus4_sc(ks, namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc, &
614 nt, tr%scf_threshold, scsteps)
615 else
616 call td_cfmagnus4(ks, namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc, nt)
617 end if
619 call td_explicit_magnus3(ks, namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc)
620 end select
621
622 generate = .false.
623 if (ions_dyn%is_active()) then
624 if (.not. propagator_elec_ions_are_propagated(tr)) then
625 call propagation_ops_elec_propagate_ions_and_cell(gr, hm, st, namespace, space, &
626 ions_dyn, ions, mc, abs(nt*dt), ions_dyn%ionic_scale*dt)
627 generate = .true.
628 end if
629 end if
630
631 gfield => list_get_gauge_field(ext_partners)
632 if(associated(gfield)) then
633 if (gauge_field_is_propagated(gfield) .and. .not. propagator_elec_ions_are_propagated(tr)) then
635 call propagation_ops_elec_update_hamiltonian(namespace, space, st, gr, hm, ext_partners, time)
636 end if
637 end if
638
639 if (generate .or. ions%has_time_dependent_species()) then
640 call hamiltonian_elec_epot_generate(hm, namespace, space, gr, ions, ext_partners, st, time = abs(nt*dt))
641 end if
642
643 call v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners, &
644 calc_eigenval = update_energy_, time = abs(nt*dt), calc_energy = update_energy_)
645
646 if (present(dmp)) then
647 if (dmp%calculation_mode /= option__tddmpropagation__no_propagation) then
648 call dm_propagation_run(dmp, namespace, space, gr, ions, st, mc, hm, ks, nt, dt, ext_partners, &
649 update_energy = update_energy_)
650 end if
651 end if
652
653 ! compute time integral of the paramagnetic current
654 call ks%v_ks_photons%add_mean_field(ks%gr, space, hm%kpoints, st, abs(nt*dt), dt)
655
656 if (update_energy_) call energy_calc_total(namespace, space, hm, gr, st, ext_partners, iunit = -1)
657
658 ! Recalculate forces, update velocities...
659 if ((ions_dyn%ions_move() .and. tr%method .ne. prop_explicit_runge_kutta4) .or. &
660 outp%what(option__output__forces) .or. write_handler%out(out_separate_forces)%write) then
661 call forces_calculate(gr, namespace, ions, hm, ext_partners, st, ks, t = abs(nt*dt), dt = dt)
662 end if
663
664 if (ions_dyn%cell_relax() .or. outp%what(option__output__stress)) then
665 call stress_calculate(namespace, gr, hm, st, ions, ks, ext_partners)
666 if(ions_dyn%cell_relax()) then
667 call ions_dyn%update_stress(ions%space, st%stress_tensors%total, ions%latt%rlattice, ions%latt%rcell_volume)
668 end if
669 end if
670
671 if( ions_dyn%is_active()) then
672 call ion_dynamics_propagate_vel(ions_dyn, ions, atoms_moved = generate)
673 call ions%update_kinetic_energy()
674 end if
675
676 if(associated(gfield)) then
677 if(gauge_field_is_propagated(gfield)) then
678 call gauge_field_get_force(gfield, gr, st%d%spin_channels, st%current, ks%xc%lrc)
680 end if
681 end if
682
683 !We update the occupation matrices
684 call lda_u_update_occ_matrices(hm%lda_u, namespace, gr, st, hm%phase, hm%energy)
685
686 !Updates Nondipole Vector potential
687 lasers => list_get_lasers(ext_partners)
688 if(associated(lasers)) then
689 if (lasers_with_nondipole_field(lasers)) then
690 call lasers_nondipole_laser_field_step(lasers, am, time)
691 call lasers_set_nondipole_parameters(lasers,am,time)
692 end if
693 end if
694 pop_sub(propagator_elec_dt)
695 call profiling_out("TD_PROPAGATOR")
696
697 contains
698
699 ! ---------------------------------------------------------
700 logical pure function self_consistent_step() result(scs)
701 scs = (hm%theory_level /= independent_particles) .and. (time <= tr%scf_propagation_steps*abs(dt) + m_epsilon)
702 end function self_consistent_step
703 ! ---------------------------------------------------------
704
705 end subroutine propagator_elec_dt
706 ! ---------------------------------------------------------
707
708
709
710
711 ! ---------------------------------------------------------
712 logical pure function propagator_elec_ions_are_propagated(tr) result(propagated)
713 type(propagator_base_t), intent(in) :: tr
714
715 select case (tr%method)
716 case (prop_etrs, prop_aetrs, prop_caetrs, prop_explicit_runge_kutta4)
717 propagated = .true.
718 case default
719 propagated = .false.
720 end select
721
723 ! ---------------------------------------------------------
724
725
726 ! ---------------------------------------------------------
727
728 subroutine propagator_elec_dt_bo(scf, namespace, space, gr, ks, st, hm, ions, ext_partners, mc, iter, dt, ions_dyn, scsteps)
729 type(scf_t), intent(inout) :: scf
730 type(namespace_t), intent(in) :: namespace
731 type(electron_space_t), intent(in) :: space
732 type(grid_t), intent(inout) :: gr
733 type(v_ks_t), intent(inout) :: ks
734 type(states_elec_t), intent(inout) :: st
735 type(hamiltonian_elec_t), intent(inout) :: hm
736 type(ions_t), intent(inout) :: ions
737 type(partner_list_t), intent(in) :: ext_partners
738 type(multicomm_t), intent(inout) :: mc
739 integer, intent(in) :: iter
740 real(real64), intent(in) :: dt
741 type(ion_dynamics_t), intent(inout) :: ions_dyn
742 integer, intent(inout) :: scsteps
743
744 type(gauge_field_t), pointer :: gfield
745
746 push_sub(propagator_elec_dt_bo)
747
748 ! move the hamiltonian to time t
749 call propagation_ops_elec_propagate_ions_and_cell(gr, hm, st, namespace, space, &
750 ions_dyn, ions, mc, iter*dt, dt)
751
752 call hamiltonian_elec_epot_generate(hm, namespace, space, gr, ions, ext_partners, st, time = iter*dt)
753 ! now calculate the eigenfunctions
754 call scf_run(scf, namespace, space, mc, gr, ions, ext_partners, st, ks, hm, &
755 verbosity = verb_compact, iters_done = scsteps)
756
757 ! Stress tensor calculation and uptade
758 if (ions_dyn%cell_relax()) then
759 if (.not. scf%calc_stress) then
760 call stress_calculate(namespace, gr, hm, st, ions, ks, ext_partners)
761 end if
762 call ions_dyn%update_stress(ions%space, st%stress_tensors%total, ions%latt%rlattice, ions%latt%rcell_volume)
763 end if
764
765 gfield => list_get_gauge_field(ext_partners)
766 if(associated(gfield)) then
767 if (gauge_field_is_propagated(gfield)) then
768 call gauge_field_do_algorithmic_operation(gfield, op_verlet_compute_acc, dt, iter*dt)
769 end if
770 end if
771
772 !TODO: we should update the occupation matrices here
773 if (hm%lda_u_level /= dft_u_none) then
774 call messages_not_implemented("DFT+U with propagator_elec_dt_bo", namespace=namespace)
775 end if
776
777 call hamiltonian_elec_epot_generate(hm, namespace, space, gr, ions, ext_partners, st, time = iter*dt)
778
779 ! update Hamiltonian and eigenvalues (fermi is *not* called)
780 call v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners, &
781 calc_eigenval = .true., time = iter*dt, calc_energy = .true.)
782
783 ! Get the energies.
784 call energy_calc_total(namespace, space, hm, gr, st, ext_partners, iunit = -1)
785
786 call ion_dynamics_propagate_vel(ions_dyn, ions)
787 call hamiltonian_elec_epot_generate(hm, namespace, space, gr, ions, ext_partners, st, time = iter*dt)
788 call ions%update_kinetic_energy()
789
790 if(associated(gfield)) then
791 if (gauge_field_is_propagated(gfield)) then
792 call gauge_field_do_algorithmic_operation(gfield, op_verlet_compute_vel, dt, iter*dt)
793 end if
794 end if
795
796 pop_sub(propagator_elec_dt_bo)
797 end subroutine propagator_elec_dt_bo
798
799end module propagator_elec_oct_m
800
801
802!! Local Variables:
803!! mode: f90
804!! coding: utf-8
805!! End:
subroutine, public dm_propagation_run(dmp, namespace, space, gr, ions, st, mc, hm, ks, iter, dt, ext_partners, update_energy)
Density matrix propagation.
subroutine, public energy_calc_total(namespace, space, hm, gr, st, ext_partners, iunit, full)
This subroutine calculates the total energy of the system. Basically, it adds up the KS eigenvalues,...
subroutine, public exponential_copy(teo, tei)
subroutine, public exponential_init(te, namespace, full_batch)
type(gauge_field_t) function, pointer, public list_get_gauge_field(partners)
type(lasers_t) function, pointer, public list_get_lasers(partners)
subroutine, public forces_calculate(gr, namespace, ions, hm, ext_partners, st, ks, vhxc_old, t, dt)
Definition: forces.F90:339
subroutine, public gauge_field_get_force(this, gr, spin_channels, current, lrc)
subroutine, public gauge_field_do_algorithmic_operation(this, operation, dt, time)
logical pure function, public gauge_field_is_propagated(this)
integer, parameter, public independent_particles
Theory level.
Definition: global.F90:248
real(real64), parameter, public m_epsilon
Definition: global.F90:214
This module implements the underlying real-space grid.
Definition: grid.F90:117
subroutine, public hamiltonian_elec_epot_generate(this, namespace, space, gr, ions, ext_partners, st, time)
This module defines classes and functions for interaction partners.
subroutine, public ion_dynamics_propagate_vel(this, ions, atoms_moved)
A module to handle KS potential, without the external potential.
subroutine, public lasers_nondipole_laser_field_step(this, field, time)
Retrieves the NDSFA vector_potential correction. The nondipole field is obtained for consecutive time...
Definition: lasers.F90:1155
subroutine, public lasers_set_nondipole_parameters(this, ndfield, nd_integration_time)
Set parameters for nondipole SFA calculation.
Definition: lasers.F90:755
logical function, public lasers_with_nondipole_field(lasers)
Check if a nondipole SFA correction should be computed for the given laser.
Definition: lasers.F90:742
subroutine, public lda_u_update_occ_matrices(this, namespace, mesh, st, phase, energy)
Definition: lda_u.F90:892
This module defines various routines, operating on mesh functions.
integer, public sp_distdot_mode
subroutine, public mesh_init_mesh_aux(mesh)
Initialise a pointer to the grid/mesh, that is globally exposed, such that low level mesh operations ...
subroutine, public messages_not_implemented(feature, namespace)
Definition: messages.F90:1066
subroutine, public messages_obsolete_variable(namespace, name, rep)
Definition: messages.F90:998
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:160
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
Definition: messages.F90:408
subroutine, public messages_input_error(namespace, var, details, row, column)
Definition: messages.F90:689
subroutine, public messages_experimental(name, namespace)
Definition: messages.F90:1038
This module handles the communicators for the various parallelization strategies.
Definition: multicomm.F90:145
This module holds the "opt_control_state_t" datatype, which contains a quantum-classical state.
this module contains the low-level part of the output system
Definition: output_low.F90:115
subroutine, public potential_interpolation_copy(vkso, vksi)
subroutine, public potential_interpolation_end(potential_interpolation)
/* To use the profiling module, call profiling_in and profiling_out with the label of the region as a...
Definition: profiling.F90:143
subroutine, public profiling_out(label)
Increment out counter and sum up difference between entry and exit time.
Definition: profiling.F90:693
subroutine, public profiling_in(label, exclude)
Increment in counter and save entry time.
Definition: profiling.F90:625
subroutine, public propagation_ops_elec_propagate_ions_and_cell(gr, hm, st, namespace, space, ions_dyn, ions, mc, time, dt_ions)
subroutine, public propagation_ops_elec_update_hamiltonian(namespace, space, st, mesh, hm, ext_partners, time)
integer, parameter, public prop_aetrs
integer, parameter, public prop_crank_nicolson_sparskit
integer, parameter, public prop_crank_nicolson
integer, parameter, public prop_runge_kutta2
integer, parameter, public prop_magnus
integer, parameter, public prop_cfmagnus4
integer, parameter, public prop_caetrs
integer, parameter, public prop_qoct_tddft_propagator
integer, parameter, public prop_exponential_midpoint
integer, parameter, public prop_explicit_magnus3
integer, parameter, public prop_runge_kutta4
integer, parameter, public prop_explicit_runge_kutta4
integer, parameter, public prop_etrs
integer, parameter, public prop_exponential_midpoint_predictor
subroutine, public td_crank_nicolson(hm, namespace, space, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc, use_sparskit)
Crank-Nicolson propagator.
subroutine, public propagator_elec_copy(tro, tri)
subroutine, public propagator_elec_dt(ks, namespace, space, hm, gr, st, tr, time, dt, nt, ions_dyn, ions, ext_partners, mc, outp, write_handler, scsteps, update_energy, qcchi, dmp)
Propagates st from time - dt to t. If dt<0, it propagates backwards from t+|dt| to t.
subroutine, public propagator_elec_dt_bo(scf, namespace, space, gr, ks, st, hm, ions, ext_partners, mc, iter, dt, ions_dyn, scsteps)
subroutine, public propagator_elec_set_scf_prop(tr, threshold)
subroutine, public propagator_elec_init(gr, namespace, st, tr, ks_pot, have_fields, family_is_mgga_with_exc, relax_cell)
subroutine, public propagator_elec_remove_scf_prop(tr)
logical pure function, public propagator_elec_ions_are_propagated(tr)
subroutine, public propagator_elec_end(tr)
subroutine, public td_aetrs(namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc)
Propagator with approximate enforced time-reversal symmetry.
subroutine, public td_etrs_sc(ks, namespace, space, hm, ext_partners, gr, st, tr, time, dt, ions_dyn, ions, mc, sctol, scsteps)
Propagator with enforced time-reversal symmetry and self-consistency.
subroutine, public td_etrs(ks, namespace, space, hm, ext_partners, gr, st, tr, time, dt, ions_dyn, ions, mc)
Propagator with enforced time-reversal symmetry, ETRS.
subroutine, public td_caetrs(ks, namespace, space, hm, ext_partners, gr, st, tr, time, dt, ions_dyn, ions, mc)
Propagator with approximate enforced time-reversal symmetry.
subroutine, public td_aetrs_sc(ks, namespace, space, hm, ext_partners, gr, st, tr, time, dt, ions_dyn, ions, mc, sctol, scsteps)
Propagator with approximate enforced time-reversal symmetry and self-consistency.
subroutine, public exponential_midpoint_predictor(hm, ks, namespace, space, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc)
Exponential midpoint with prediction of the half time step This is equivalent to an explicit Magnus i...
subroutine, public exponential_midpoint(hm, namespace, space, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc)
Exponential midpoint.
subroutine, public td_magnus(hm, ext_partners, gr, st, tr, namespace, time, dt)
Magnus propagator.
subroutine, public td_cfmagnus4(ks, namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc, iter)
Commutator-free Magnus propagator of order 4. This method has been developed for linear systems and i...
subroutine, public td_explicit_magnus3(ks, namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc)
Third-order explicit Magnus propagator. This implements equation (22) from Casas, F....
subroutine, public td_cfmagnus4_sc(ks, namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc, iter, sctol, scsteps)
Commutator-free Magnus propagator of order 4 with self-consistency.
subroutine, public td_qoct_tddft_propagator(hm, namespace, space, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc)
Propagator specifically designed for the QOCT+TDDFT problem.
subroutine, public td_runge_kutta2(ks, namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners)
subroutine, public td_runge_kutta4(ks, namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners)
subroutine, public td_explicit_runge_kutta4(ks, namespace, space, hm, gr, st, time, dt, ions_dyn, ions, ext_partners, qcchi)
subroutine, public propagator_rk_end()
type(algorithmic_operation_t), parameter, public op_verlet_compute_acc
type(algorithmic_operation_t), parameter, public op_verlet_compute_vel
subroutine, public sparskit_solver_init(namespace, n, sk, is_complex)
Definition: sparskit.F90:238
subroutine, public sparskit_solver_end(sk)
Definition: sparskit.F90:436
subroutine, public sparskit_solver_copy(sko, ski)
Definition: sparskit.F90:449
subroutine, public states_elec_end(st)
finalize the states_elec_t object
This module implements the calculation of the stress tensor.
Definition: stress.F90:118
subroutine, public stress_calculate(namespace, gr, hm, st, ions, ks, ext_partners)
This computes the total stress on the lattice.
Definition: stress.F90:186
integer, parameter, public out_separate_forces
Definition: td_write.F90:203
subroutine, public v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners, calc_eigenval, time, calc_energy, calc_current, force_semilocal)
Definition: v_ks.F90:786
Definition: xc.F90:118
logical pure function self_consistent_step()
Extension of space that contains the knowledge of the spin dimension.
Description of the grid, containing information on derivatives, stencil, and symmetries.
Definition: grid.F90:169
Stores all communicators and groups.
Definition: multicomm.F90:206
This is the datatype that contains the objects that are propagated: in principle this could be both t...
output handler class
Definition: output_low.F90:164
The states_elec_t class contains all electronic wave functions.
Time-dependent Write Properties.
Definition: td_write.F90:323
int true(void)