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