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