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
27 use forces_oct_m
29 use grid_oct_m
30 use global_oct_m
34 use ions_oct_m
35 use, intrinsic :: iso_fortran_env
36 use lasers_oct_m
37 use lda_u_oct_m
39 use parser_oct_m
57 use scf_oct_m
59 use space_oct_m
61 use stress_oct_m
63 use v_ks_oct_m
65 use xc_oct_m
66
67 implicit none
68
69 private
70 public :: &
79
80contains
81
82 ! ---------------------------------------------------------
83 subroutine propagator_elec_copy(tro, tri)
84 type(propagator_base_t), intent(inout) :: tro
85 type(propagator_base_t), intent(in) :: tri
86
87 push_sub(propagator_elec_copy)
88
89 tro%method = tri%method
90
91 select case (tro%method)
93 tro%tdsk_size = tri%tdsk_size
94 call sparskit_solver_copy(tro%tdsk, tri%tdsk)
95
97 tro%tdsk_size = tri%tdsk_size
98 call sparskit_solver_copy(tro%tdsk, tri%tdsk)
99
100 case (prop_runge_kutta2)
101 tro%tdsk_size = tri%tdsk_size
102 call sparskit_solver_copy(tro%tdsk, tri%tdsk)
103
104 end select
105
106 call potential_interpolation_copy(tro%vks_old, tri%vks_old)
107
108 call exponential_copy(tro%te, tri%te)
109 tro%scf_propagation_steps = tri%scf_propagation_steps
110
111 tro%scf_threshold = tri%scf_threshold
112 pop_sub(propagator_elec_copy)
113 end subroutine propagator_elec_copy
114 ! ---------------------------------------------------------
115
117 ! ---------------------------------------------------------
118 subroutine propagator_elec_init(gr, namespace, st, tr, ks_pot, have_fields, family_is_mgga_with_exc, relax_cell)
119 type(grid_t), intent(in) :: gr
120 type(namespace_t), intent(in) :: namespace
121 type(states_elec_t), intent(in) :: st
122 type(propagator_base_t), intent(inout) :: tr
123 type(ks_potential_t), intent(in) :: ks_pot
127 logical, intent(in) :: have_fields
128 logical, intent(in) :: family_is_mgga_with_exc
129 logical, intent(in) :: relax_cell
130
131 push_sub(propagator_elec_init)
132
133 !%Variable TDPropagator
134 !%Type integer
135 !%Default etrs
136 !%Section Time-Dependent::Propagation
137 !%Description
138 !% This variable determines which algorithm will be used to approximate
139 !% the evolution operator <math>U(t+\delta t, t)</math>. That is, given
140 !% <math>\psi(\tau)</math> and <math>H(\tau)</math> for <math>\tau \le t</math>,
141 !% calculate <math>t+\delta t</math>. Note that in general the Hamiltonian
142 !% is not known at times in the interior of the interval <math>[t,t+\delta t]</math>.
143 !% This is due to the self-consistent nature of the time-dependent Kohn-Sham problem:
144 !% the Hamiltonian at a given time <math>\tau</math> is built from the
145 !% "solution" wavefunctions at that time.
146 !%
147 !% Some methods, however, do require the knowledge of the Hamiltonian at some
148 !% point of the interval <math>[t,t+\delta t]</math>. This problem is solved by making
149 !% use of extrapolation: given a number <math>l</math> of time steps previous to time
150 !% <math>t</math>, this information is used to build the Hamiltonian at arbitrary times
151 !% within <math>[t,t+\delta t]</math>. To be fully precise, one should then proceed
152 !% <i>self-consistently</i>: the obtained Hamiltonian at time <math>t+\delta t</math>
153 !% may then be used to interpolate the Hamiltonian, and repeat the evolution
154 !% algorithm with this new information. Whenever iterating the procedure does
155 !% not change the solution wavefunctions, the cycle is stopped. In practice,
156 !% in <tt>Octopus</tt> we perform a second-order extrapolation without a
157 !% self-consistency check, except for the first two iterations, where obviously
158 !% the extrapolation is not reliable.
159 !%
160 !% The proliferation of methods is certainly excessive. The reason for it is that
161 !% the propagation algorithm is currently a topic of active development. We
162 !% hope that in the future the optimal schemes are clearly identified. In the
163 !% mean time, if you do not feel like testing, use the default choices and
164 !% make sure the time step is small enough.
165 !%
166 !% More details about the propagation methods could be found in
167 !% A. Castro, M.A.L. Marques, and A. Rubio, J. Chem. Phys 121 3425-3433 (2004)
168 !% and
169 !% A. Pueyo et al., J. Chem. Theory Comput. 14, 6, 3040 (2018)
170 !%
171 !%Option etrs 2
172 !% The idea is to make use of time-reversal symmetry from the beginning:
173 !%
174 !% <math>
175 !% \exp \left(-i\delta t H_{n} / 2 \right)\psi_n = \exp \left(i\delta t H_{n+1} / 2 \right)\psi_{n+1},
176 !% </math>
177 !%
178 !% and then invert to obtain:
179 !%
180 !% <math>
181 !% \psi_{n+1} = \exp \left(-i\delta t H_{n+1} / 2 \right) \exp \left(-i\delta t H_{n} / 2 \right)\psi_{n}.
182 !% </math>
183 !%
184 !% But we need to know <math>H_{n+1}</math>, which can only be known exactly through the solution
185 !% <math>\psi_{n+1}</math>. What we do is to estimate it by performing a single exponential:
186 !% <math>\psi\^{\*}\_{n+1}=\exp \left( -i\delta t H_{n} \right) \psi_n</math>, and then
187 !% <math>H_{n+1} = H[\psi\^{\*}_{n+1}]</math>. Thus no extrapolation is performed in this case.
188 !%Option aetrs 3
189 !% Approximated Enforced Time-Reversal Symmetry (AETRS).
190 !% A modification of previous method to make it faster.
191 !% It is based on extrapolation of the time-dependent potentials. It is faster
192 !% by about 40%.
193 !% The only difference is the procedure to estimate <math>H_{n+1}</math>: in this case
194 !% it is extrapolated via a second-order polynomial by making use of the
195 !% Hamiltonian at time <math>t-2\delta t</math>, <math>t-\delta t</math> and <math>t</math>.
196 !%Option caetrs 12
197 !% (experimental) Corrected Approximated Enforced Time-Reversal
198 !% Symmetry (AETRS), this is the previous propagator but including
199 !% a correction step to the exponential.
200 !%Option exp_mid 4
201 !% Exponential Midpoint Rule (EM).
202 !% This is maybe the simplest method, but it is very well grounded theoretically:
203 !% it is unitary (if the exponential is performed correctly) and preserves
204 !% time-reversal symmetry (if the self-consistency problem is dealt with correctly).
205 !% It is defined as:
206 !% <math>
207 !% U_{\rm EM}(t+\delta t, t) = \exp \left( -i\delta t H_{t+\delta t/2}\right)\,.
208 !% </math>
209 !%Option crank_nicholson 5
210 !%Option crank_nicolson 5
211 !% Classical Crank-Nicolson propagator.
212 !% <math>
213 !% (1 + i\delta t H_{n+1/2} / 2) \psi_{n+1} = (1 - i\delta t H_{n+1/2} / 2) \psi_{n}
214 !% </math>
215 !%Option crank_nicholson_sparskit 6
216 !%Option crank_nicolson_sparskit 6
217 !% Classical Crank-Nicolson propagator. Requires the SPARSKIT library.
218 !% <math>
219 !% (1 + i\delta t H_{n+1/2} / 2) \psi_{n+1} = (1 - i\delta t H_{n+1/2} / 2) \psi_{n}
220 !% </math>
221 !%Option magnus 7
222 !% Magnus Expansion (M4).
223 !% This is the most sophisticated approach. It is a fourth-order scheme (a feature
224 !% which it shares with the ST scheme; the other schemes are in principle second-order).
225 !% It is tailored for making use of very large time steps, or equivalently,
226 !% dealing with problem with very high-frequency time-dependence.
227 !% It is still in a experimental state; we are not yet sure of when it is
228 !% advantageous.
229 !%Option qoct_tddft_propagator 10
230 !% WARNING: EXPERIMENTAL
231 !%Option runge_kutta4 13
232 !% WARNING: EXPERIMENTAL. Implicit Gauss-Legendre 4th order Runge-Kutta.
233 !%Option runge_kutta2 14
234 !% WARNING: EXPERIMENTAL. Implicit 2nd order Runge-Kutta (trapezoidal rule).
235 !% Similar, but not identical, to Crank-Nicolson method.
236 !%Option expl_runge_kutta4 15
237 !% WARNING: EXPERIMENTAL. Explicit RK4 method.
238 !%Option cfmagnus4 16
239 !% WARNING EXPERIMENTAL. Commutator-free magnus expansion.
240 !%Option exp_mid_predictor 17
241 !% Exponential Midpoint Rule (EM).
242 !% This is maybe the simplest method, but it is very well grounded theoretically:
243 !% it is unitary (if the exponential is performed correctly) and preserves
244 !% time-reversal symmetry (if the self-consistency problem is dealt with correctly).
245 !% It is defined as:
246 !% <math>
247 !% U_{\rm EM}(t+\delta t, t) = \exp \left( -i\delta t H_{t+\delta t/2}\right)\,.
248 !% </math>
249 !% As opposed to the exp_mid propagator, $H_{t+\delta t/2}$ is not obtained by
250 !% extrapolation from previous timesteps, but by predicting by applying the exponential with
251 !% $\delta t/2$ and computing the corresponding density and potential.
252 !% It is equivalent to an explicit Magnus integration of second order, see equation 20 in
253 !% Casas, F. & Iserles, A. Explicit Magnus expansions for nonlinear equations. J. Phys. A: Math. Gen. 39,
254 !% 5445 (2006) [https://dx.doi.org/10.1088/0305-4470/39/19/S07]
255 !%End
256 call messages_obsolete_variable(namespace, 'TDEvolutionMethod', 'TDPropagator')
257
258 call parse_variable(namespace, 'TDPropagator', prop_etrs, tr%method)
259 if (.not. varinfo_valid_option('TDPropagator', tr%method)) call messages_input_error(namespace, 'TDPropagator')
260
261 select case (tr%method)
262 case (prop_etrs)
263 case (prop_aetrs)
264 case (prop_caetrs)
265 call messages_experimental("CAETRS propagator", namespace=namespace)
269 ! set up pointer for zmf_dotu_aux, zmf_nrm2_aux
270 call mesh_init_mesh_aux(gr)
271 case (prop_runge_kutta4)
272 ! set up pointer for zmf_dotu_aux, zmf_nrm2_aux
273 call mesh_init_mesh_aux(gr)
275 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)
276 call sparskit_solver_init(namespace, tr%tdsk_size, tr%tdsk, .true.)
277
278#ifndef HAVE_SPARSKIT
279 message(1) = 'Octopus was not compiled with support for the SPARSKIT library. This'
280 message(2) = 'library is required if the "runge_kutta4" propagator is selected.'
281 message(3) = 'Try using a different propagation scheme or recompile with SPARSKIT support.'
282 call messages_fatal(3, namespace=namespace)
283#endif
284
285 call messages_experimental("Runge-Kutta 4 propagator", namespace=namespace)
286 case (prop_runge_kutta2)
287
288 ! set up pointer for zmf_dotu_aux, zmf_nrm2_aux
289 call mesh_init_mesh_aux(gr)
291 tr%tdsk_size = st%d%dim * gr%np * (st%st_end - st%st_start + 1) * (st%d%kpt%end - st%d%kpt%start + 1)
292 call sparskit_solver_init(namespace, tr%tdsk_size, tr%tdsk, .true.)
293
294#ifndef HAVE_SPARSKIT
295 message(1) = 'Octopus was not compiled with support for the SPARSKIT library. This'
296 message(2) = 'library is required if the "runge_kutta2" propagator is selected.'
297 message(3) = 'Try using a different propagation scheme or recompile with SPARSKIT support.'
298 call messages_fatal(3, namespace=namespace)
299#endif
300
301 call messages_experimental("Runge-Kutta 2 propagator", namespace=namespace)
303 ! set up pointer for zmf_dotu_aux
304 call mesh_init_mesh_aux(gr)
306 tr%tdsk_size = st%d%dim*gr%np
307 call sparskit_solver_init(namespace, st%d%dim*gr%np, tr%tdsk, .true.)
308
309#ifndef HAVE_SPARSKIT
310 message(1) = 'Octopus was not compiled with support for the SPARSKIT library. This'
311 message(2) = 'library is required if the "crank_nicolson_sparskit" propagator is selected.'
312 message(3) = 'Try using a different propagation scheme or recompile with SPARSKIT support.'
313 call messages_fatal(3, namespace=namespace)
314#endif
315 case (prop_magnus)
316 call messages_experimental("Magnus propagator", namespace=namespace)
317 if (family_is_mgga_with_exc) then
318 message(1) = "Magnus propagator with MGGA"
319 call messages_fatal(1, namespace=namespace)
320 end if
322 call messages_experimental("QOCT+TDDFT propagator", namespace=namespace)
324 call messages_experimental("explicit Runge-Kutta 4 propagator", namespace=namespace)
325 case (prop_cfmagnus4)
326 call messages_experimental("Commutator-Free Magnus propagator", namespace=namespace)
327 case default
328 call messages_input_error(namespace, 'TDPropagator')
329 end select
330 call messages_print_var_option('TDPropagator', tr%method, namespace=namespace)
331
332 if (have_fields) then
333 if (tr%method /= prop_etrs .and. &
334 tr%method /= prop_aetrs .and. &
335 tr%method /= prop_exponential_midpoint .and. &
336 tr%method /= prop_exponential_midpoint_predictor .and. &
337 tr%method /= prop_qoct_tddft_propagator .and. &
338 tr%method /= prop_crank_nicolson .and. &
339 tr%method /= prop_runge_kutta4 .and. &
340 tr%method /= prop_explicit_runge_kutta4 .and. &
341 tr%method /= prop_runge_kutta2 .and. &
342 tr%method /= prop_crank_nicolson_sparskit) then
343 message(1) = "To move the ions or put in a gauge field, use one of the following propagators:"
344 message(2) = "etrs, aetrs, crank-nicolson, rk2, rk4, or exp_mid."
345 call messages_fatal(2, namespace=namespace)
346 end if
347 end if
348
349 if (relax_cell) then
350 if (tr%method /= prop_etrs .and. &
351 tr%method /= prop_aetrs .and. &
352 tr%method /= prop_exponential_midpoint .and. &
353 tr%method /= prop_exponential_midpoint_predictor .and. &
354 tr%method /= prop_crank_nicolson .and. &
355 tr%method /= prop_crank_nicolson_sparskit) then
356 message(1) = "To relax the cell, use the one of the following propagators:"
357 message(2) = "etrs, aetrs, crank-nicolson, or exp_mid."
358 call messages_fatal(2, namespace=namespace)
359 end if
360 end if
361
362 select case (tr%method)
363 case (prop_cfmagnus4)
364 call ks_pot%init_interpolation(tr%vks_old, order = 4)
365 case default
366 call ks_pot%init_interpolation(tr%vks_old)
367 end select
368
369 call exponential_init(tr%te, namespace) ! initialize propagator
370
371 call messages_obsolete_variable(namespace, 'TDSelfConsistentSteps', 'TDStepsWithSelfConsistency')
372
373 !%Variable TDStepsWithSelfConsistency
374 !%Type integer
375 !%Default 0
376 !%Section Time-Dependent::Propagation
377 !%Description
378 !% Since the KS propagator is non-linear, each propagation step
379 !% should be performed self-consistently. In practice, for most
380 !% purposes this is not necessary, except perhaps in the first
381 !% iterations. This variable holds the number of propagation steps
382 !% for which the propagation is done self-consistently.
383 !%
384 !% The special value <tt>all_steps</tt> forces self-consistency to
385 !% be imposed on all propagation steps. A value of 0 means that
386 !% self-consistency will not be imposed. The default is 0.
387 !%Option all_steps -1
388 !% Self-consistency is imposed for all propagation steps.
389 !%End
390
391 call parse_variable(namespace, 'TDStepsWithSelfConsistency', 0, tr%scf_propagation_steps)
392
393 if (tr%scf_propagation_steps == -1) tr%scf_propagation_steps = huge(tr%scf_propagation_steps)
394 if (tr%scf_propagation_steps < 0) call messages_input_error(namespace, 'TDStepsWithSelfConsistency', 'Cannot be negative')
395
396 if (tr%scf_propagation_steps /= 0) then
397 call messages_experimental('TDStepsWithSelfConsistency', namespace=namespace)
398
399 if (tr%method /= prop_etrs) then
400 call messages_write('TDStepsWithSelfConsistency only works with the ETRS propagator')
401 call messages_fatal(namespace=namespace)
402 end if
403 end if
404
405 !%Variable TDSCFThreshold
406 !%Type float
407 !%Default 1.0e-6
408 !%Section Time-Dependent::Propagation
409 !%Description
410 !% Since the KS propagator is non-linear, each propagation step
411 !% should be performed self-consistently. In practice, for most
412 !% purposes this is not necessary, except perhaps in the first
413 !% iterations. This variable holds the number of propagation steps
414 !% for which the propagation is done self-consistently.
415 !%
416 !% The self consistency has to be measured against some accuracy
417 !% threshold. This variable controls the value of that threshold.
418 !%End
419 call parse_variable(namespace, 'TDSCFThreshold', 1.0e-6_real64, tr%scf_threshold)
420
421 pop_sub(propagator_elec_init)
422 end subroutine propagator_elec_init
423 ! ---------------------------------------------------------
424
425
426 ! ---------------------------------------------------------
427 subroutine propagator_elec_set_scf_prop(tr, threshold)
428 type(propagator_base_t), intent(inout) :: tr
429 real(real64), optional, intent(in) :: threshold
430
432
433 tr%scf_propagation_steps = huge(1)
434 if (present(threshold)) then
435 tr%scf_threshold = threshold
436 end if
437
439 end subroutine propagator_elec_set_scf_prop
440 ! ---------------------------------------------------------
441
442
443 ! ---------------------------------------------------------
445 type(propagator_base_t), intent(inout) :: tr
446
448
449 tr%scf_propagation_steps = -1
450
453 ! ---------------------------------------------------------
454
455
456 ! ---------------------------------------------------------
457 subroutine propagator_elec_end(tr)
458 type(propagator_base_t), intent(inout) :: tr
459
460 push_sub(propagator_elec_end)
461
462 call potential_interpolation_end(tr%vks_old)
463
464 select case (tr%method)
466 call propagator_rk_end()
467 call sparskit_solver_end(tr%tdsk)
468
470 call sparskit_solver_end(tr%tdsk)
471
472 end select
473
474 pop_sub(propagator_elec_end)
475 end subroutine propagator_elec_end
476 ! ---------------------------------------------------------
477
478
479 ! ---------------------------------------------------------
482 ! ---------------------------------------------------------
483 subroutine propagator_elec_dt(ks, namespace, space, hm, gr, st, tr, time, dt, nt, &
484 ions_dyn, ions, ext_partners, mc, outp, write_handler, scsteps, update_energy, qcchi)
485 type(v_ks_t), target, intent(inout) :: ks
486 type(namespace_t), intent(in) :: namespace
487 type(electron_space_t), intent(in) :: space
488 type(hamiltonian_elec_t), target, intent(inout) :: hm
489 type(grid_t), target, intent(inout) :: gr
490 type(states_elec_t), target, intent(inout) :: st
491 type(propagator_base_t), target, intent(inout) :: tr
492 real(real64), intent(in) :: time
493 real(real64), intent(in) :: dt
494 integer, intent(in) :: nt
495 type(ion_dynamics_t), intent(inout) :: ions_dyn
496 type(ions_t), intent(inout) :: ions
497 type(partner_list_t), intent(in) :: ext_partners
498 type(multicomm_t), intent(inout) :: mc
499 type(output_t), intent(in) :: outp
500 type(td_write_t), intent(in) :: write_handler
501 integer, optional, intent(out) :: scsteps
502 logical, optional, intent(in) :: update_energy
503 type(opt_control_state_t), optional, target, intent(inout) :: qcchi
504 type(gauge_field_t), pointer :: gfield
505 type(lasers_t), pointer :: lasers
506 logical :: generate, update_energy_
507 real(real64) :: am(space%dim)
508
509 call profiling_in("TD_PROPAGATOR")
510 push_sub(propagator_elec_dt)
511
512 update_energy_ = optional_default(update_energy, .true.)
513
514 call hm%ks_pot%interpolation_new(tr%vks_old, time, dt)
515
516 if (present(scsteps)) scsteps = 1
517
518 select case (tr%method)
519 case (prop_etrs)
520 if (self_consistent_step()) then
521 call td_etrs_sc(ks, namespace, space, hm, ext_partners, gr, st, tr, time, dt, &
522 ions_dyn, ions, mc, tr%scf_threshold, scsteps)
523 else
524 call td_etrs(ks, namespace, space, hm, ext_partners, gr, st, tr, time, dt, &
525 ions_dyn, ions, mc)
526 end if
527 case (prop_aetrs)
528 call td_aetrs(namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc)
529 case (prop_caetrs)
530 call td_caetrs(ks, namespace, space, hm, ext_partners, gr, st, tr, time, dt, ions_dyn, ions, mc)
532 call exponential_midpoint(hm, namespace, space, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc)
534 call exponential_midpoint_predictor(hm, ks, namespace, space, gr, st, tr, time, dt, ions_dyn, ions, &
535 ext_partners, mc)
537 call td_crank_nicolson(hm, namespace, space, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc, .false.)
538 case (prop_runge_kutta4)
539 call td_runge_kutta4(ks, namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners)
540 case (prop_runge_kutta2)
541 call td_runge_kutta2(ks, namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners)
543 call td_crank_nicolson(hm, namespace, space, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc, .true.)
544 case (prop_magnus)
545 call td_magnus(hm, ext_partners, gr, st, tr, namespace, time, dt)
547 call td_qoct_tddft_propagator(hm, namespace, space, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc)
549 if (present(qcchi)) then
550 call td_explicit_runge_kutta4(ks, namespace, space, hm, gr, st, time, dt, ions_dyn, ions, ext_partners, qcchi)
551 else
552 call td_explicit_runge_kutta4(ks, namespace, space, hm, gr, st, time, dt, ions_dyn, ions, ext_partners)
553 end if
554 case (prop_cfmagnus4)
555 call td_cfmagnus4(ks, namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, nt)
556 end select
557
558 generate = .false.
559 if (ions_dyn%is_active()) then
560 if (.not. propagator_elec_ions_are_propagated(tr)) then
561 call propagation_ops_elec_propagate_ions_and_cell(gr, hm, st, namespace, space, &
562 ions_dyn, ions, mc, abs(nt*dt), ions_dyn%ionic_scale*dt)
563 generate = .true.
564 end if
565 end if
566
567 gfield => list_get_gauge_field(ext_partners)
568 if(associated(gfield)) then
569 if (gauge_field_is_propagated(gfield) .and. .not. propagator_elec_ions_are_propagated(tr)) then
571 call propagation_ops_elec_update_hamiltonian(namespace, space, st, gr, hm, ext_partners, time)
572 end if
573 end if
574
575 if (generate .or. ions%has_time_dependent_species()) then
576 call hamiltonian_elec_epot_generate(hm, namespace, space, gr, ions, ext_partners, st, time = abs(nt*dt))
577 end if
579 call v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners, &
580 calc_eigenval = update_energy_, time = abs(nt*dt), calc_energy = update_energy_)
581
582 ! compute time integral of the paramagnetic current
583 if (ks%xc_photon /= 0) then
584 call ks%xc_photons%add_mean_field(ks%gr, space, hm%kpoints, st, abs(nt*dt), dt)
585 endif
586
587 if (update_energy_) call energy_calc_total(namespace, space, hm, gr, st, ext_partners, iunit = -1)
588
589 ! Recalculate forces, update velocities...
590 if ((ions_dyn%ions_move() .and. tr%method .ne. prop_explicit_runge_kutta4) .or. &
591 outp%what(option__output__forces) .or. write_handler%out(out_separate_forces)%write) then
592 call forces_calculate(gr, namespace, ions, hm, ext_partners, st, ks, t = abs(nt*dt), dt = dt)
593 end if
594
595 if (ions_dyn%cell_relax() .or. outp%what(option__output__stress)) then
596 call stress_calculate(namespace, gr, hm, st, ions, ks, ext_partners)
597 if(ions_dyn%cell_relax()) then
598 call ions_dyn%update_stress(ions%space, st%stress_tensors%total, ions%latt%rlattice, ions%latt%rcell_volume)
599 end if
600 end if
601
602 if( ions_dyn%is_active()) then
603 call ion_dynamics_propagate_vel(ions_dyn, ions, atoms_moved = generate)
604 call ions%update_kinetic_energy()
605 end if
606
607 if(associated(gfield)) then
608 if(gauge_field_is_propagated(gfield)) then
609 call gauge_field_get_force(gfield, gr, st%d%spin_channels, st%current, ks%xc%lrc)
611 end if
612 end if
613
614 !We update the occupation matrices
615 call lda_u_update_occ_matrices(hm%lda_u, namespace, gr, st, hm%phase, hm%energy)
616
617 !Updates Nondipole Vector potential
618 lasers => list_get_lasers(ext_partners)
619 if(associated(lasers)) then
620 if (lasers_with_nondipole_field(lasers)) then
621 call lasers_nondipole_laser_field_step(lasers, am, time)
622 call lasers_set_nondipole_parameters(lasers,am,time)
623 end if
624 end if
625 pop_sub(propagator_elec_dt)
626 call profiling_out("TD_PROPAGATOR")
627
628 contains
629
630 ! ---------------------------------------------------------
631 logical pure function self_consistent_step() result(scs)
632 scs = (hm%theory_level /= independent_particles) .and. (time <= tr%scf_propagation_steps*abs(dt) + m_epsilon)
633 end function self_consistent_step
634 ! ---------------------------------------------------------
635
636 end subroutine propagator_elec_dt
637 ! ---------------------------------------------------------
638
639
640
641
642 ! ---------------------------------------------------------
643 logical pure function propagator_elec_ions_are_propagated(tr) result(propagated)
644 type(propagator_base_t), intent(in) :: tr
645
646 select case (tr%method)
647 case (prop_etrs, prop_aetrs, prop_caetrs, prop_explicit_runge_kutta4)
648 propagated = .true.
649 case default
650 propagated = .false.
651 end select
652
654 ! ---------------------------------------------------------
655
656
657 ! ---------------------------------------------------------
658
659 subroutine propagator_elec_dt_bo(scf, namespace, space, gr, ks, st, hm, ions, ext_partners, mc, iter, dt, ions_dyn, scsteps)
660 type(scf_t), intent(inout) :: scf
661 type(namespace_t), intent(in) :: namespace
662 type(electron_space_t), intent(in) :: space
663 type(grid_t), intent(inout) :: gr
664 type(v_ks_t), intent(inout) :: ks
665 type(states_elec_t), intent(inout) :: st
666 type(hamiltonian_elec_t), intent(inout) :: hm
667 type(ions_t), intent(inout) :: ions
668 type(partner_list_t), intent(in) :: ext_partners
669 type(multicomm_t), intent(inout) :: mc
670 integer, intent(in) :: iter
671 real(real64), intent(in) :: dt
672 type(ion_dynamics_t), intent(inout) :: ions_dyn
673 integer, intent(inout) :: scsteps
674
675 type(gauge_field_t), pointer :: gfield
676
677 push_sub(propagator_elec_dt_bo)
678
679 ! move the hamiltonian to time t
680 call propagation_ops_elec_propagate_ions_and_cell(gr, hm, st, namespace, space, &
681 ions_dyn, ions, mc, iter*dt, dt)
682
683 call hamiltonian_elec_epot_generate(hm, namespace, space, gr, ions, ext_partners, st, time = iter*dt)
684 ! now calculate the eigenfunctions
685 call scf_run(scf, namespace, space, mc, gr, ions, ext_partners, st, ks, hm, &
686 verbosity = verb_compact, iters_done = scsteps)
687
688 ! Stress tensor calculation and uptade
689 if (ions_dyn%cell_relax()) then
690 if (.not. scf%calc_stress) then
691 call stress_calculate(namespace, gr, hm, st, ions, ks, ext_partners)
692 end if
693 call ions_dyn%update_stress(ions%space, st%stress_tensors%total, ions%latt%rlattice, ions%latt%rcell_volume)
694 end if
695
696 gfield => list_get_gauge_field(ext_partners)
697 if(associated(gfield)) then
698 if (gauge_field_is_propagated(gfield)) then
699 call gauge_field_do_algorithmic_operation(gfield, op_verlet_compute_acc, dt, iter*dt)
700 end if
701 end if
702
703 !TODO: we should update the occupation matrices here
704 if (hm%lda_u_level /= dft_u_none) then
705 call messages_not_implemented("DFT+U with propagator_elec_dt_bo", namespace=namespace)
706 end if
707
708 call hamiltonian_elec_epot_generate(hm, namespace, space, gr, ions, ext_partners, st, time = iter*dt)
709
710 ! update Hamiltonian and eigenvalues (fermi is *not* called)
711 call v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners, &
712 calc_eigenval = .true., time = iter*dt, calc_energy = .true.)
713
714 ! Get the energies.
715 call energy_calc_total(namespace, space, hm, gr, st, ext_partners, iunit = -1)
716
717 call ion_dynamics_propagate_vel(ions_dyn, ions)
718 call hamiltonian_elec_epot_generate(hm, namespace, space, gr, ions, ext_partners, st, time = iter*dt)
719 call ions%update_kinetic_energy()
720
721 if(associated(gfield)) then
722 if (gauge_field_is_propagated(gfield)) then
723 call gauge_field_do_algorithmic_operation(gfield, op_verlet_compute_vel, dt, iter*dt)
724 end if
725 end if
727 pop_sub(propagator_elec_dt_bo)
728 end subroutine propagator_elec_dt_bo
729
730end module propagator_elec_oct_m
731
732
733!! Local Variables:
734!! mode: f90
735!! coding: utf-8
736!! End:
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:340
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:237
real(real64), parameter, public m_epsilon
Definition: global.F90:207
This module implements the underlying real-space grid.
Definition: grid.F90:119
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:1152
subroutine, public lasers_set_nondipole_parameters(this, ndfield, nd_integration_time)
Set parameters for nondipole SFA calculation.
Definition: lasers.F90:754
logical function, public lasers_with_nondipole_field(lasers)
Check if a nondipole SFA correction should be computed for the given laser.
Definition: lasers.F90:741
subroutine, public lda_u_update_occ_matrices(this, namespace, mesh, st, phase, energy)
Definition: lda_u.F90:798
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_obsolete_variable(namespace, name, rep)
Definition: messages.F90:1023
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:162
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
Definition: messages.F90:410
subroutine, public messages_input_error(namespace, var, details, row, column)
Definition: messages.F90:691
subroutine, public messages_experimental(name, namespace)
Definition: messages.F90:1063
This module handles the communicators for the various parallelization strategies.
Definition: multicomm.F90:147
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:117
subroutine, public potential_interpolation_copy(vkso, vksi)
subroutine, public potential_interpolation_end(potential_interpolation)
subroutine, public profiling_out(label)
Increment out counter and sum up difference between entry and exit time.
Definition: profiling.F90:631
subroutine, public profiling_in(label, exclude)
Increment in counter and save entry time.
Definition: profiling.F90:554
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_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_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_dt(ks, namespace, space, hm, gr, st, tr, time, dt, nt, ions_dyn, ions, ext_partners, mc, outp, write_handler, scsteps, update_energy, qcchi)
Propagates st from time - dt to t. If dt<0, it propagates backwards from t+|dt| to t.
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.
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 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_cfmagnus4(ks, namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, iter)
Commutator-free Magnus propagator of order 4.
subroutine, public td_magnus(hm, ext_partners, gr, st, tr, namespace, time, dt)
Magnus propagator.
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:240
subroutine, public sparskit_solver_end(sk)
Definition: sparskit.F90:437
subroutine, public sparskit_solver_copy(sko, ski)
Definition: sparskit.F90:450
This module implements the calculation of the stress tensor.
Definition: stress.F90:120
subroutine, public stress_calculate(namespace, gr, hm, st, ions, ks, ext_partners)
This computes the total stress on the lattice.
Definition: stress.F90:188
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:752
Definition: xc.F90:116
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:171
Stores all communicators and groups.
Definition: multicomm.F90:208
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:166
The states_elec_t class contains all electronic wave functions.
Time-dependent Write Properties.
Definition: td_write.F90:321
int true(void)