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
38 use parser_oct_m
55 use scf_oct_m
57 use space_oct_m
59 use stress_oct_m
61 use v_ks_oct_m
63 use xc_oct_m
64
65 implicit none
66
67 private
68 public :: &
78
79contains
80
81 ! ---------------------------------------------------------
82 subroutine propagator_elec_copy(tro, tri)
83 type(propagator_base_t), intent(inout) :: tro
84 type(propagator_base_t), intent(in) :: tri
85
86 push_sub(propagator_elec_copy)
87
88 tro%method = tri%method
89
90 select case (tro%method)
91 case (prop_magnus)
92 safe_allocate_source_a(tro%vmagnus, tri%vmagnus)
93
95 tro%tdsk_size = tri%tdsk_size
96 call sparskit_solver_copy(tro%tdsk, tri%tdsk)
97
99 tro%tdsk_size = tri%tdsk_size
100 call sparskit_solver_copy(tro%tdsk, tri%tdsk)
101
102 case (prop_runge_kutta2)
103 tro%tdsk_size = tri%tdsk_size
104 call sparskit_solver_copy(tro%tdsk, tri%tdsk)
105
106 end select
107
108 call potential_interpolation_copy(tro%vksold, tri%vksold)
109
110 call exponential_copy(tro%te, tri%te)
111 tro%scf_propagation_steps = tri%scf_propagation_steps
112
113 tro%scf_threshold = tri%scf_threshold
115 end subroutine propagator_elec_copy
116 ! ---------------------------------------------------------
117
118
119 ! ---------------------------------------------------------
120 subroutine propagator_elec_init(gr, namespace, st, tr, have_fields, family_is_mgga_with_exc)
121 type(grid_t), intent(in) :: gr
122 type(namespace_t), intent(in) :: namespace
123 type(states_elec_t), intent(in) :: st
124 type(propagator_base_t), intent(inout) :: tr
128 logical, intent(in) :: have_fields
129 logical, intent(in) :: family_is_mgga_with_exc
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 !%Option etrs 2
166 !% The idea is to make use of time-reversal symmetry from the beginning:
167 !%
168 !% <math>
169 !% \exp \left(-i\delta t H_{n} / 2 \right)\psi_n = \exp \left(i\delta t H_{n+1} / 2 \right)\psi_{n+1},
170 !% </math>
171 !%
172 !% and then invert to obtain:
173 !%
174 !% <math>
175 !% \psi_{n+1} = \exp \left(-i\delta t H_{n+1} / 2 \right) \exp \left(-i\delta t H_{n} / 2 \right)\psi_{n}.
176 !% </math>
177 !%
178 !% But we need to know <math>H_{n+1}</math>, which can only be known exactly through the solution
179 !% <math>\psi_{n+1}</math>. What we do is to estimate it by performing a single exponential:
180 !% <math>\psi^{*}_{n+1}=\exp \left( -i\delta t H_{n} \right) \psi_n</math>, and then
181 !% <math>H_{n+1} = H[\psi^{*}_{n+1}]</math>. Thus no extrapolation is performed in this case.
182 !%Option aetrs 3
183 !% Approximated Enforced Time-Reversal Symmetry (AETRS).
184 !% A modification of previous method to make it faster.
185 !% It is based on extrapolation of the time-dependent potentials. It is faster
186 !% by about 40%.
187 !% The only difference is the procedure to estimate <math>H_{n+1}</math>: in this case
188 !% it is extrapolated via a second-order polynomial by making use of the
189 !% Hamiltonian at time <math>t-2\delta t</math>, <math>t-\delta t</math> and <math>t</math>.
190 !%Option caetrs 12
191 !% (experimental) Corrected Approximated Enforced Time-Reversal
192 !% Symmetry (AETRS), this is the previous propagator but including
193 !% a correction step to the exponential.
194 !%Option exp_mid 4
195 !% Exponential Midpoint Rule (EM).
196 !% This is maybe the simplest method, but it is very well grounded theoretically:
197 !% it is unitary (if the exponential is performed correctly) and preserves
198 !% time-reversal symmetry (if the self-consistency problem is dealt with correctly).
199 !% It is defined as:
200 !% <math>
201 !% U_{\rm EM}(t+\delta t, t) = \exp \left( -i\delta t H_{t+\delta t/2}\right)\,.
202 !% </math>
203 !%Option crank_nicholson 5
204 !%Option crank_nicolson 5
205 !% Classical Crank-Nicolson propagator.
206 !% <math>
207 !% (1 + i\delta t H_{n+1/2} / 2) \psi_{n+1} = (1 - i\delta t H_{n+1/2} / 2) \psi_{n}
208 !% </math>
209 !%Option crank_nicholson_sparskit 6
210 !%Option crank_nicolson_sparskit 6
211 !% Classical Crank-Nicolson propagator. Requires the SPARSKIT library.
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 magnus 7
216 !% Magnus Expansion (M4).
217 !% This is the most sophisticated approach. It is a fourth-order scheme (a feature
218 !% which it shares with the ST scheme; the other schemes are in principle second-order).
219 !% It is tailored for making use of very large time steps, or equivalently,
220 !% dealing with problem with very high-frequency time-dependence.
221 !% It is still in a experimental state; we are not yet sure of when it is
222 !% advantageous.
223 !%Option qoct_tddft_propagator 10
224 !% WARNING: EXPERIMENTAL
225 !%Option runge_kutta4 13
226 !% WARNING: EXPERIMENTAL. Implicit Gauss-Legendre 4th order Runge-Kutta.
227 !%Option runge_kutta2 14
228 !% WARNING: EXPERIMENTAL. Implicit 2nd order Runge-Kutta (trapezoidal rule).
229 !% Similar, but not identical, to Crank-Nicolson method.
230 !%Option expl_runge_kutta4 15
231 !% WARNING: EXPERIMENTAL. Explicit RK4 method.
232 !%Option cfmagnus4 16
233 !% WARNING EXPERIMENTAL
234 !%End
235 call messages_obsolete_variable(namespace, 'TDEvolutionMethod', 'TDPropagator')
236
237 call parse_variable(namespace, 'TDPropagator', prop_etrs, tr%method)
238 if (.not. varinfo_valid_option('TDPropagator', tr%method)) call messages_input_error(namespace, 'TDPropagator')
239
240 select case (tr%method)
241 case (prop_etrs)
242 case (prop_aetrs)
243 case (prop_caetrs)
244 call messages_experimental("CAETRS propagator", namespace=namespace)
247 ! set up pointer for zmf_dotu_aux, zmf_nrm2_aux
248 call mesh_init_mesh_aux(gr)
249 case (prop_runge_kutta4)
250 ! set up pointer for zmf_dotu_aux, zmf_nrm2_aux
251 call mesh_init_mesh_aux(gr)
253 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)
254 call sparskit_solver_init(namespace, tr%tdsk_size, tr%tdsk, .true.)
255
256#ifndef HAVE_SPARSKIT
257 message(1) = 'Octopus was not compiled with support for the SPARSKIT library. This'
258 message(2) = 'library is required if the "runge_kutta4" propagator is selected.'
259 message(3) = 'Try using a different propagation scheme or recompile with SPARSKIT support.'
260 call messages_fatal(3, namespace=namespace)
261#endif
262
263 call messages_experimental("Runge-Kutta 4 propagator", namespace=namespace)
264 case (prop_runge_kutta2)
265
266 ! set up pointer for zmf_dotu_aux, zmf_nrm2_aux
267 call mesh_init_mesh_aux(gr)
269 tr%tdsk_size = st%d%dim * gr%np * (st%st_end - st%st_start + 1) * (st%d%kpt%end - st%d%kpt%start + 1)
270 call sparskit_solver_init(namespace, tr%tdsk_size, tr%tdsk, .true.)
271
272#ifndef HAVE_SPARSKIT
273 message(1) = 'Octopus was not compiled with support for the SPARSKIT library. This'
274 message(2) = 'library is required if the "runge_kutta2" propagator is selected.'
275 message(3) = 'Try using a different propagation scheme or recompile with SPARSKIT support.'
276 call messages_fatal(3, namespace=namespace)
277#endif
278
279 call messages_experimental("Runge-Kutta 2 propagator", namespace=namespace)
281 ! set up pointer for zmf_dotu_aux
282 call mesh_init_mesh_aux(gr)
284 tr%tdsk_size = st%d%dim*gr%np
285 call sparskit_solver_init(namespace, st%d%dim*gr%np, tr%tdsk, .true.)
286
287#ifndef HAVE_SPARSKIT
288 message(1) = 'Octopus was not compiled with support for the SPARSKIT library. This'
289 message(2) = 'library is required if the "crank_nicolson_sparskit" propagator is selected.'
290 message(3) = 'Try using a different propagation scheme or recompile with SPARSKIT support.'
291 call messages_fatal(3, namespace=namespace)
292#endif
293 case (prop_magnus)
294 call messages_experimental("Magnus propagator", namespace=namespace)
295 if (family_is_mgga_with_exc) then
296 message(1) = "Magnus propagator with MGGA"
297 call messages_fatal(1, namespace=namespace)
298 end if
299 safe_allocate(tr%vmagnus(1:gr%np, 1:st%d%nspin, 1:2))
301 call messages_experimental("QOCT+TDDFT propagator", namespace=namespace)
303 call messages_experimental("explicit Runge-Kutta 4 propagator", namespace=namespace)
304 case (prop_cfmagnus4)
305 call messages_experimental("Commutator-Free Magnus propagator", namespace=namespace)
306 case default
307 call messages_input_error(namespace, 'TDPropagator')
308 end select
309 call messages_print_var_option('TDPropagator', tr%method, namespace=namespace)
310
311 if (have_fields) then
312 if (tr%method /= prop_etrs .and. &
313 tr%method /= prop_aetrs .and. &
314 tr%method /= prop_exponential_midpoint .and. &
315 tr%method /= prop_qoct_tddft_propagator .and. &
316 tr%method /= prop_crank_nicolson .and. &
317 tr%method /= prop_runge_kutta4 .and. &
318 tr%method /= prop_explicit_runge_kutta4 .and. &
319 tr%method /= prop_runge_kutta2 .and. &
320 tr%method /= prop_crank_nicolson_sparskit) then
321 message(1) = "To move the ions or put in a gauge field, use the one of the following propagators:"
322 message(2) = "etrs, aetrs, crank-nicolson, rk2, rk4, or exp_mid."
323 call messages_fatal(2, namespace=namespace)
324 end if
325 end if
326
327 select case (tr%method)
328 case (prop_cfmagnus4)
329 call potential_interpolation_init(tr%vksold, gr%np, st%d%nspin, family_is_mgga_with_exc, order = 4)
330 case default
331 call potential_interpolation_init(tr%vksold, gr%np, st%d%nspin, family_is_mgga_with_exc)
332 end select
333
334 call exponential_init(tr%te, namespace) ! initialize propagator
335
336 call messages_obsolete_variable(namespace, 'TDSelfConsistentSteps', 'TDStepsWithSelfConsistency')
337
338 !%Variable TDStepsWithSelfConsistency
339 !%Type integer
340 !%Default 0
341 !%Section Time-Dependent::Propagation
342 !%Description
343 !% Since the KS propagator is non-linear, each propagation step
344 !% should be performed self-consistently. In practice, for most
345 !% purposes this is not necessary, except perhaps in the first
346 !% iterations. This variable holds the number of propagation steps
347 !% for which the propagation is done self-consistently.
348 !%
349 !% The special value <tt>all_steps</tt> forces self-consistency to
350 !% be imposed on all propagation steps. A value of 0 means that
351 !% self-consistency will not be imposed. The default is 0.
352 !%Option all_steps -1
353 !% Self-consistency is imposed for all propagation steps.
354 !%End
355
356 call parse_variable(namespace, 'TDStepsWithSelfConsistency', 0, tr%scf_propagation_steps)
357
358 if (tr%scf_propagation_steps == -1) tr%scf_propagation_steps = huge(tr%scf_propagation_steps)
359 if (tr%scf_propagation_steps < 0) call messages_input_error(namespace, 'TDStepsWithSelfConsistency', 'Cannot be negative')
360
361 if (tr%scf_propagation_steps /= 0) then
362 call messages_experimental('TDStepsWithSelfConsistency', namespace=namespace)
363
364 if (tr%method /= prop_etrs) then
365 call messages_write('TDStepsWithSelfConsistency only works with the ETRS propagator')
366 call messages_fatal(namespace=namespace)
367 end if
368 end if
369
370 !%Variable TDSCFThreshold
371 !%Type float
372 !%Default 1.0e-6
373 !%Section Time-Dependent::Propagation
374 !%Description
375 !% Since the KS propagator is non-linear, each propagation step
376 !% should be performed self-consistently. In practice, for most
377 !% purposes this is not necessary, except perhaps in the first
378 !% iterations. This variable holds the number of propagation steps
379 !% for which the propagation is done self-consistently.
380 !%
381 !% The self consistency has to be measured against some accuracy
382 !% threshold. This variable controls the value of that threshold.
383 !%End
384 call parse_variable(namespace, 'TDSCFThreshold', 1.0e-6_real64, tr%scf_threshold)
385
386 pop_sub(propagator_elec_init)
387 end subroutine propagator_elec_init
388 ! ---------------------------------------------------------
389
390
391 ! ---------------------------------------------------------
392 subroutine propagator_elec_set_scf_prop(tr, threshold)
393 type(propagator_base_t), intent(inout) :: tr
394 real(real64), optional, intent(in) :: threshold
395
397
398 tr%scf_propagation_steps = huge(1)
399 if (present(threshold)) then
400 tr%scf_threshold = threshold
401 end if
402
404 end subroutine propagator_elec_set_scf_prop
405 ! ---------------------------------------------------------
406
407
408 ! ---------------------------------------------------------
410 type(propagator_base_t), intent(inout) :: tr
411
413
414 tr%scf_propagation_steps = -1
415
418 ! ---------------------------------------------------------
419
420
421 ! ---------------------------------------------------------
422 subroutine propagator_elec_end(tr)
423 type(propagator_base_t), intent(inout) :: tr
424
425 push_sub(propagator_elec_end)
426
427 call potential_interpolation_end(tr%vksold)
428
429 select case (tr%method)
430 case (prop_magnus)
431 assert(allocated(tr%vmagnus))
432 safe_deallocate_a(tr%vmagnus)
433
435 call sparskit_solver_end(tr%tdsk)
436
437 end select
438
439 pop_sub(propagator_elec_end)
440 end subroutine propagator_elec_end
441 ! ---------------------------------------------------------
442
443
444 ! ---------------------------------------------------------
445 subroutine propagator_elec_run_zero_iter(hm, gr, tr)
446 type(hamiltonian_elec_t), intent(in) :: hm
447 type(grid_t), intent(in) :: gr
448 type(propagator_base_t), intent(inout) :: tr
449
451
452 call potential_interpolation_run_zero_iter(tr%vksold, gr%np, hm%d%nspin, hm%vhxc, vtau=hm%vtau)
453
455 end subroutine propagator_elec_run_zero_iter
456
457
458 ! ---------------------------------------------------------
461 ! ---------------------------------------------------------
462 subroutine propagator_elec_dt(ks, namespace, space, hm, gr, st, tr, time, dt, nt, &
463 ions_dyn, ions, ext_partners, outp, write_handler, scsteps, update_energy, qcchi)
464 type(v_ks_t), target, intent(inout) :: ks
465 type(namespace_t), intent(in) :: namespace
466 type(electron_space_t), intent(in) :: space
467 type(hamiltonian_elec_t), target, intent(inout) :: hm
468 type(grid_t), target, intent(inout) :: gr
469 type(states_elec_t), target, intent(inout) :: st
470 type(propagator_base_t), target, intent(inout) :: tr
471 real(real64), intent(in) :: time
472 real(real64), intent(in) :: dt
473 integer, intent(in) :: nt
474 type(ion_dynamics_t), intent(inout) :: ions_dyn
475 type(ions_t), intent(inout) :: ions
476 type(partner_list_t), intent(in) :: ext_partners
477 type(output_t), intent(in) :: outp
478 type(td_write_t), intent(in) :: write_handler
479 integer, optional, intent(out) :: scsteps
480 logical, optional, intent(in) :: update_energy
481 type(opt_control_state_t), optional, target, intent(inout) :: qcchi
482 type(gauge_field_t), pointer :: gfield
483 type(lasers_t), pointer :: lasers
484 logical :: generate, update_energy_
485 real(real64) :: am(space%dim)
486
487 call profiling_in("TD_PROPAGATOR")
489
490 update_energy_ = optional_default(update_energy, .true.)
491
492 call potential_interpolation_new(tr%vksold, gr%np, st%d%nspin, time, dt, hm%vhxc, vtau=hm%vtau)
493
494 if (present(scsteps)) scsteps = 1
495
496 select case (tr%method)
497 case (prop_etrs)
498 if (self_consistent_step()) then
499 call td_etrs_sc(ks, namespace, space, hm, ext_partners, gr, st, tr, time, dt, &
500 ions_dyn, ions, tr%scf_threshold, scsteps)
501 else
502 call td_etrs(ks, namespace, space, hm, ext_partners, gr, st, tr, time, dt, &
503 ions_dyn, ions)
504 end if
505 case (prop_aetrs)
506 call td_aetrs(namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners)
507 case (prop_caetrs)
508 call td_caetrs(ks, namespace, space, hm, ext_partners, gr, st, tr, time, dt, ions_dyn, ions)
510 call exponential_midpoint(hm, namespace, space, gr, st, tr, time, dt, ions_dyn, ions, ext_partners)
512 call td_crank_nicolson(hm, namespace, space, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, .false.)
513 case (prop_runge_kutta4)
514 call td_runge_kutta4(ks, namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners)
515 case (prop_runge_kutta2)
516 call td_runge_kutta2(ks, namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners)
518 call td_crank_nicolson(hm, namespace, space, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, .true.)
519 case (prop_magnus)
520 call td_magnus(hm, ext_partners, gr, st, tr, namespace, time, dt)
522 call td_qoct_tddft_propagator(hm, namespace, space, gr, st, tr, time, dt, ions_dyn, ions, ext_partners)
524 if (present(qcchi)) then
525 call td_explicit_runge_kutta4(ks, namespace, space, hm, gr, st, time, dt, ions_dyn, ions, ext_partners, qcchi)
526 else
527 call td_explicit_runge_kutta4(ks, namespace, space, hm, gr, st, time, dt, ions_dyn, ions, ext_partners)
528 end if
529 case (prop_cfmagnus4)
530 call td_cfmagnus4(ks, namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, nt)
531 end select
532
533 generate = .false.
534 if (ion_dynamics_ions_move(ions_dyn)) then
535 if (.not. propagator_elec_ions_are_propagated(tr)) then
536 call ion_dynamics_propagate(ions_dyn, ions, abs(nt*dt), ions_dyn%ionic_scale*dt, namespace)
537 generate = .true.
538 end if
539 end if
540
541 gfield => list_get_gauge_field(ext_partners)
542 if(associated(gfield)) then
543 if (gauge_field_is_propagated(gfield) .and. .not. propagator_elec_ions_are_propagated(tr)) then
545 end if
546 end if
547
548 if (generate .or. ions%has_time_dependent_species()) then
549 call hamiltonian_elec_epot_generate(hm, namespace, space, gr, ions, ext_partners, st, time = abs(nt*dt))
550 end if
551
552 call v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners, &
553 calc_eigenval = update_energy_, time = abs(nt*dt), calc_energy = update_energy_)
554
555 ! compute time integral of the paramagnetic current
556 if (ks%xc_photon /= 0) then
557 call ks%xc_photons%add_mean_field(ks%gr, space, hm%kpoints, st, abs(nt*dt), dt)
558 endif
559
560 if (update_energy_) call energy_calc_total(namespace, space, hm, gr, st, ext_partners, iunit = -1)
561
562 ! Recalculate forces, update velocities...
563 if (ion_dynamics_ions_move(ions_dyn) .and. tr%method .ne. prop_explicit_runge_kutta4) then
564 call forces_calculate(gr, namespace, ions, hm, ext_partners, st, ks, t = abs(nt*dt), dt = dt)
565 call ion_dynamics_propagate_vel(ions_dyn, ions, atoms_moved = generate)
566 call ions%update_kinetic_energy()
567 else
568 if (outp%what(option__output__forces) .or. write_handler%out(out_separate_forces)%write) then
569 call forces_calculate(gr, namespace, ions, hm, ext_partners, st, ks, t = abs(nt*dt), dt = dt)
570 end if
571 end if
572
573 if (outp%what(option__output__stress)) then
574 call stress_calculate(namespace, gr, hm, st, ions, ks, ext_partners)
575 end if
576
577 if(associated(gfield)) then
578 if(gauge_field_is_propagated(gfield)) then
579 if(ks%xc%kernel_lrc_alpha>m_epsilon) then
580 call gauge_field_get_force(gfield, gr, st%d%spin_channels, st%current, ks%xc%kernel_lrc_alpha)
581 else
582 call gauge_field_get_force(gfield, gr, st%d%spin_channels, st%current)
583 endif
585 end if
586 end if
587
588 !We update the occupation matrices
589 call lda_u_update_occ_matrices(hm%lda_u, namespace, gr, st, hm%hm_base, hm%phase, hm%energy)
590
591 !Updates Nondipole Vector potential
592 lasers => list_get_lasers(ext_partners)
593 if(associated(lasers)) then
594 if (lasers_with_nondipole_field(lasers)) then
595 call lasers_nondipole_laser_field_step(lasers, am, time)
596 call lasers_set_nondipole_parameters(lasers,am,time)
597 end if
598 end if
599 pop_sub(propagator_elec_dt)
600 call profiling_out("TD_PROPAGATOR")
601
602 contains
603
604 ! ---------------------------------------------------------
605 logical pure function self_consistent_step() result(scs)
606 scs = (hm%theory_level /= independent_particles) .and. (time <= tr%scf_propagation_steps*abs(dt) + m_epsilon)
607 end function self_consistent_step
608 ! ---------------------------------------------------------
609
610 end subroutine propagator_elec_dt
611 ! ---------------------------------------------------------
612
613
614
615
616 ! ---------------------------------------------------------
617 logical pure function propagator_elec_ions_are_propagated(tr) result(propagated)
618 type(propagator_base_t), intent(in) :: tr
619
620 select case (tr%method)
621 case (prop_etrs, prop_aetrs, prop_caetrs, prop_explicit_runge_kutta4)
622 propagated = .true.
623 case default
624 propagated = .false.
625 end select
626
628 ! ---------------------------------------------------------
629
630
631 ! ---------------------------------------------------------
632
633 subroutine propagator_elec_dt_bo(scf, namespace, space, gr, ks, st, hm, ions, ext_partners, mc, outp, iter, dt, ions_dyn, scsteps)
634 type(scf_t), intent(inout) :: scf
635 type(namespace_t), intent(in) :: namespace
636 type(electron_space_t), intent(in) :: space
637 type(grid_t), intent(inout) :: gr
638 type(v_ks_t), intent(inout) :: ks
639 type(states_elec_t), intent(inout) :: st
640 type(hamiltonian_elec_t), intent(inout) :: hm
641 type(ions_t), intent(inout) :: ions
642 type(partner_list_t), intent(in) :: ext_partners
643 type(multicomm_t), intent(inout) :: mc
644 type(output_t), intent(inout) :: outp
645 integer, intent(in) :: iter
646 real(real64), intent(in) :: dt
647 type(ion_dynamics_t), intent(inout) :: ions_dyn
648 integer, intent(inout) :: scsteps
649
650 type(gauge_field_t), pointer :: gfield
651
652 push_sub(propagator_elec_dt_bo)
653
654 ! move the hamiltonian to time t
655 call ion_dynamics_propagate(ions_dyn, ions, iter*dt, dt, namespace)
656 call hamiltonian_elec_epot_generate(hm, namespace, space, gr, ions, ext_partners, st, time = iter*dt)
657 ! now calculate the eigenfunctions
658 call scf_run(scf, namespace, space, mc, gr, ions, ext_partners, st, ks, hm, &
659 verbosity = verb_compact, iters_done = scsteps)
660
661 gfield => list_get_gauge_field(ext_partners)
662 if(associated(gfield)) then
663 if (gauge_field_is_propagated(gfield)) then
664 call gauge_field_do_algorithmic_operation(gfield, op_verlet_compute_acc, dt, iter*dt)
665 end if
666 end if
667
668 !TODO: we should update the occupation matrices here
669 if (hm%lda_u_level /= dft_u_none) then
670 call messages_not_implemented("DFT+U with propagator_elec_dt_bo", namespace=namespace)
671 end if
672
673 call hamiltonian_elec_epot_generate(hm, namespace, space, gr, ions, ext_partners, st, time = iter*dt)
674
675 ! update Hamiltonian and eigenvalues (fermi is *not* called)
676 call v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners, &
677 calc_eigenval = .true., time = iter*dt, calc_energy = .true.)
678
679 ! Get the energies.
680 call energy_calc_total(namespace, space, hm, gr, st, ext_partners, iunit = -1)
681
682 call ion_dynamics_propagate_vel(ions_dyn, ions)
683 call hamiltonian_elec_epot_generate(hm, namespace, space, gr, ions, ext_partners, st, time = iter*dt)
684 call ions%update_kinetic_energy()
685
686 if(associated(gfield)) then
687 if (gauge_field_is_propagated(gfield)) then
688 call gauge_field_do_algorithmic_operation(gfield, op_verlet_compute_vel, dt, iter*dt)
689 end if
690 end if
691
692 pop_sub(propagator_elec_dt_bo)
693 end subroutine propagator_elec_dt_bo
694
695end module propagator_elec_oct_m
697
698!! Local Variables:
699!! mode: f90
700!! coding: utf-8
701!! 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:336
subroutine, public gauge_field_do_algorithmic_operation(this, operation, dt, time)
subroutine, public gauge_field_get_force(this, gr, spin_channels, current, lrc_alpha)
logical pure function, public gauge_field_is_propagated(this)
real(real64), parameter, public m_epsilon
Definition: global.F90:203
This module implements the underlying real-space grid.
Definition: grid.F90:117
integer, parameter, public independent_particles
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(this, ions, time, dt, namespace)
logical pure function, public ion_dynamics_ions_move(this)
subroutine, public ion_dynamics_propagate_vel(this, ions, atoms_moved)
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:1146
subroutine, public lasers_set_nondipole_parameters(this, ndfield, nd_integration_time)
Set parameters for nondipole SFA calculation.
Definition: lasers.F90:748
logical function, public lasers_with_nondipole_field(lasers)
Check if a nondipole SFA correction should be computed for the given laser.
Definition: lasers.F90:735
subroutine, public lda_u_update_occ_matrices(this, namespace, mesh, st, hm_base, phase, energy)
Definition: lda_u.F90:796
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:1057
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:420
subroutine, public messages_input_error(namespace, var, details, row, column)
Definition: messages.F90:723
subroutine, public messages_experimental(name, namespace)
Definition: messages.F90:1097
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 output system
Definition: output_low.F90:115
subroutine, public potential_interpolation_copy(vkso, vksi)
subroutine, public potential_interpolation_end(potential_interpolation)
subroutine, public potential_interpolation_new(potential_interpolation, np, nspin, time, dt, vhxc, vtau)
subroutine, public potential_interpolation_run_zero_iter(potential_interpolation, np, nspin, vhxc, vtau)
subroutine, public potential_interpolation_init(potential_interpolation, np, nspin, mgga_with_exc, order)
subroutine, public profiling_out(label)
Increment out counter and sum up difference between entry and exit time.
Definition: profiling.F90:623
subroutine, public profiling_in(label, exclude)
Increment in counter and save entry time.
Definition: profiling.F90:552
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
subroutine, public td_crank_nicolson(hm, namespace, space, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, use_sparskit)
Crank-Nicolson propagator.
subroutine, public propagator_elec_dt_bo(scf, namespace, space, gr, ks, st, hm, ions, ext_partners, mc, outp, iter, dt, ions_dyn, scsteps)
subroutine, public propagator_elec_copy(tro, tri)
subroutine, public propagator_elec_run_zero_iter(hm, gr, tr)
subroutine, public propagator_elec_init(gr, namespace, st, tr, have_fields, family_is_mgga_with_exc)
subroutine, public propagator_elec_set_scf_prop(tr, threshold)
subroutine, public propagator_elec_dt(ks, namespace, space, hm, gr, st, tr, time, dt, nt, ions_dyn, ions, ext_partners, 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_remove_scf_prop(tr)
logical pure function, public propagator_elec_ions_are_propagated(tr)
subroutine, public propagator_elec_end(tr)
subroutine, public td_caetrs(ks, namespace, space, hm, ext_partners, gr, st, tr, time, dt, ions_dyn, ions)
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, 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)
Propagator with enforced time-reversal symmetry.
subroutine, public td_aetrs(namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners)
Propagator with approximate enforced time-reversal symmetry.
subroutine, public exponential_midpoint(hm, namespace, space, gr, st, tr, time, dt, ions_dyn, ions, ext_partners)
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)
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)
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:228
subroutine, public sparskit_solver_end(sk)
Definition: sparskit.F90:425
subroutine, public sparskit_solver_copy(sko, ski)
Definition: sparskit.F90:438
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:184
integer, parameter, public out_separate_forces
Definition: td_write.F90:201
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:732
Definition: xc.F90:114
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:168
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:163
The states_elec_t class contains all electronic wave functions.
Time-dependent Write Properties.
Definition: td_write.F90:315
int true(void)