35 use,
intrinsic :: iso_fortran_env
84 type(propagator_base_t),
intent(inout) :: tro
85 type(propagator_base_t),
intent(in) :: tri
89 tro%method = tri%method
91 select case (tro%method)
93 tro%tdsk_size = tri%tdsk_size
97 tro%tdsk_size = tri%tdsk_size
101 tro%tdsk_size = tri%tdsk_size
109 tro%scf_propagation_steps = tri%scf_propagation_steps
111 tro%scf_threshold = tri%scf_threshold
118 subroutine propagator_elec_init(gr, namespace, st, tr, ks_pot, have_fields, family_is_mgga_with_exc, relax_cell)
119 type(grid_t),
intent(in) :: gr
120 type(namespace_t),
intent(in) :: namespace
121 type(states_elec_t),
intent(in) :: st
122 type(propagator_base_t),
intent(inout) :: tr
123 type(ks_potential_t),
intent(in) :: ks_pot
127 logical,
intent(in) :: have_fields
128 logical,
intent(in) :: family_is_mgga_with_exc
129 logical,
intent(in) :: relax_cell
296 select case (tr%method)
310 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)
314 message(1) =
'Octopus was not compiled with support for the SPARSKIT library. This'
315 message(2) =
'library is required if the "runge_kutta4" propagator is selected.'
316 message(3) =
'Try using a different propagation scheme or recompile with SPARSKIT support.'
326 tr%tdsk_size = st%d%dim * gr%np * (st%st_end - st%st_start + 1) * (st%d%kpt%end - st%d%kpt%start + 1)
330 message(1) =
'Octopus was not compiled with support for the SPARSKIT library. This'
331 message(2) =
'library is required if the "runge_kutta2" propagator is selected.'
332 message(3) =
'Try using a different propagation scheme or recompile with SPARSKIT support.'
341 tr%tdsk_size = st%d%dim*gr%np
345 message(1) =
'Octopus was not compiled with support for the SPARSKIT library. This'
346 message(2) =
'library is required if the "crank_nicolson_sparskit" propagator is selected.'
347 message(3) =
'Try using a different propagation scheme or recompile with SPARSKIT support.'
352 if (family_is_mgga_with_exc)
then
353 message(1) =
"Magnus propagator with MGGA"
369 if (have_fields)
then
382 message(1) =
"To move the ions or put in a gauge field, use one of the following propagators:"
383 message(2) =
"etrs, aetrs, cfmagnus4, crank-nicolson, rk2, rk4, or exp_mid."
397 message(1) =
"To relax the cell, use the one of the following propagators:"
398 message(2) =
"etrs, aetrs, cfmagnus4, crank-nicolson, or exp_mid."
403 select case (tr%method)
405 call ks_pot%init_interpolation(tr%vks_old, order = 4)
407 call ks_pot%init_interpolation(tr%vks_old)
432 call parse_variable(namespace,
'TDStepsWithSelfConsistency', 0, tr%scf_propagation_steps)
434 if (tr%scf_propagation_steps == -1) tr%scf_propagation_steps = huge(tr%scf_propagation_steps)
435 if (tr%scf_propagation_steps < 0)
call messages_input_error(namespace,
'TDStepsWithSelfConsistency',
'Cannot be negative')
437 if (tr%scf_propagation_steps /= 0)
then
441 call messages_write(
'TDStepsWithSelfConsistency only works with the ETRS/AETRS/CFM4 propagators')
460 call parse_variable(namespace,
'TDSCFThreshold', 1.0e-6_real64, tr%scf_threshold)
470 real(real64),
optional,
intent(in) :: threshold
474 tr%scf_propagation_steps = huge(1)
475 if (
present(threshold))
then
476 tr%scf_threshold = threshold
490 tr%scf_propagation_steps = -1
505 select case (tr%method)
524 subroutine propagator_elec_dt(ks, namespace, space, hm, gr, st, tr, time, dt, nt, &
525 ions_dyn, ions, ext_partners, mc, outp, write_handler, scsteps, update_energy, qcchi)
526 type(
v_ks_t),
target,
intent(inout) :: ks
530 type(
grid_t),
target,
intent(inout) :: gr
533 real(real64),
intent(in) :: time
534 real(real64),
intent(in) :: dt
535 integer,
intent(in) :: nt
537 type(
ions_t),
intent(inout) :: ions
542 integer,
optional,
intent(out) :: scsteps
543 logical,
optional,
intent(in) :: update_energy
547 logical :: generate, update_energy_
548 real(real64) :: am(space%dim)
555 call hm%ks_pot%interpolation_new(tr%vks_old, time, dt)
557 if (
present(scsteps)) scsteps = 1
559 select case (tr%method)
562 call td_etrs_sc(ks, namespace, space, hm, ext_partners, gr, st, tr, time, dt, &
563 ions_dyn, ions, mc, tr%scf_threshold, scsteps)
565 call td_etrs(ks, namespace, space, hm, ext_partners, gr, st, tr, time, dt, &
570 call td_aetrs_sc(ks, namespace, space, hm, ext_partners, gr, st, tr, time, dt, &
571 ions_dyn, ions, mc, tr%scf_threshold, scsteps)
573 call td_aetrs(namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc)
576 call td_caetrs(ks, namespace, space, hm, ext_partners, gr, st, tr, time, dt, ions_dyn, ions, mc)
578 call exponential_midpoint(hm, namespace, space, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc)
580 call exponential_midpoint_predictor(hm, ks, namespace, space, gr, st, tr, time, dt, ions_dyn, ions, &
583 call td_crank_nicolson(hm, namespace, space, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc, .false.)
585 call td_runge_kutta4(ks, namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners)
587 call td_runge_kutta2(ks, namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners)
589 call td_crank_nicolson(hm, namespace, space, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc, .
true.)
591 call td_magnus(hm, ext_partners, gr, st, tr, namespace, time, dt)
593 call td_qoct_tddft_propagator(hm, namespace, space, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc)
595 if (
present(qcchi))
then
596 call td_explicit_runge_kutta4(ks, namespace, space, hm, gr, st, time, dt, ions_dyn, ions, ext_partners, qcchi)
598 call td_explicit_runge_kutta4(ks, namespace, space, hm, gr, st, time, dt, ions_dyn, ions, ext_partners)
602 call td_cfmagnus4_sc(ks, namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc, &
603 nt, tr%scf_threshold, scsteps)
605 call td_cfmagnus4(ks, namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc, nt)
608 call td_explicit_magnus3(ks, namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc)
612 if (ions_dyn%is_active())
then
615 ions_dyn, ions, mc, abs(nt*dt), ions_dyn%ionic_scale*dt)
621 if(
associated(gfield))
then
628 if (generate .or. ions%has_time_dependent_species())
then
632 call v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners, &
633 calc_eigenval = update_energy_, time = abs(nt*dt), calc_energy = update_energy_)
636 if (ks%xc_photon /= 0)
then
637 call ks%xc_photons%add_mean_field(ks%gr, space, hm%kpoints, st, abs(nt*dt), dt)
640 if (update_energy_)
call energy_calc_total(namespace, space, hm, gr, st, ext_partners, iunit = -1)
645 call forces_calculate(gr, namespace, ions, hm, ext_partners, st, ks, t = abs(nt*dt), dt = dt)
648 if (ions_dyn%cell_relax() .or. outp%what(option__output__stress))
then
650 if(ions_dyn%cell_relax())
then
651 call ions_dyn%update_stress(ions%space, st%stress_tensors%total, ions%latt%rlattice, ions%latt%rcell_volume)
655 if( ions_dyn%is_active())
then
657 call ions%update_kinetic_energy()
660 if(
associated(gfield))
then
672 if(
associated(lasers))
then
697 type(propagator_base_t),
intent(in) :: tr
699 select case (tr%method)
700 case (prop_etrs, prop_aetrs, prop_caetrs, prop_explicit_runge_kutta4)
712 subroutine propagator_elec_dt_bo(scf, namespace, space, gr, ks, st, hm, ions, ext_partners, mc, iter, dt, ions_dyn, scsteps)
713 type(scf_t),
intent(inout) :: scf
714 type(namespace_t),
intent(in) :: namespace
715 type(electron_space_t),
intent(in) :: space
716 type(grid_t),
intent(inout) :: gr
717 type(v_ks_t),
intent(inout) :: ks
718 type(states_elec_t),
intent(inout) :: st
719 type(hamiltonian_elec_t),
intent(inout) :: hm
720 type(ions_t),
intent(inout) :: ions
721 type(partner_list_t),
intent(in) :: ext_partners
722 type(multicomm_t),
intent(inout) :: mc
723 integer,
intent(in) :: iter
724 real(real64),
intent(in) :: dt
725 type(ion_dynamics_t),
intent(inout) :: ions_dyn
726 integer,
intent(inout) :: scsteps
728 type(gauge_field_t),
pointer :: gfield
733 call propagation_ops_elec_propagate_ions_and_cell(gr, hm, st, namespace, space, &
734 ions_dyn, ions, mc, iter*dt, dt)
736 call hamiltonian_elec_epot_generate(hm, namespace, space, gr, ions, ext_partners, st, time = iter*dt)
738 call scf_run(scf, namespace, space, mc, gr, ions, ext_partners, st, ks, hm, &
739 verbosity = verb_compact, iters_done = scsteps)
742 if (ions_dyn%cell_relax())
then
743 if (.not. scf%calc_stress)
then
744 call stress_calculate(namespace, gr, hm, st, ions, ks, ext_partners)
746 call ions_dyn%update_stress(ions%space, st%stress_tensors%total, ions%latt%rlattice, ions%latt%rcell_volume)
749 gfield => list_get_gauge_field(ext_partners)
750 if(
associated(gfield))
then
751 if (gauge_field_is_propagated(gfield))
then
752 call gauge_field_do_algorithmic_operation(gfield, op_verlet_compute_acc, dt, iter*dt)
757 if (hm%lda_u_level /= dft_u_none)
then
758 call messages_not_implemented(
"DFT+U with propagator_elec_dt_bo", namespace=namespace)
761 call hamiltonian_elec_epot_generate(hm, namespace, space, gr, ions, ext_partners, st, time = iter*dt)
764 call v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners, &
765 calc_eigenval = .
true., time = iter*dt, calc_energy = .
true.)
768 call energy_calc_total(namespace, space, hm, gr, st, ext_partners, iunit = -1)
770 call ion_dynamics_propagate_vel(ions_dyn, ions)
771 call hamiltonian_elec_epot_generate(hm, namespace, space, gr, ions, ext_partners, st, time = iter*dt)
772 call ions%update_kinetic_energy()
774 if(
associated(gfield))
then
775 if (gauge_field_is_propagated(gfield))
then
776 call gauge_field_do_algorithmic_operation(gfield, op_verlet_compute_vel, dt, iter*dt)
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)
subroutine, public gauge_field_get_force(this, gr, spin_channels, current, lrc)
subroutine, public gauge_field_do_algorithmic_operation(this, operation, dt, time)
logical pure function, public gauge_field_is_propagated(this)
integer, parameter, public independent_particles
Theory level.
real(real64), parameter, public m_epsilon
This module implements the underlying real-space grid.
subroutine, public hamiltonian_elec_epot_generate(this, namespace, space, gr, ions, ext_partners, st, time)
This module defines classes and functions for interaction partners.
subroutine, public ion_dynamics_propagate_vel(this, ions, atoms_moved)
A module to handle KS potential, without the external potential.
subroutine, public lasers_nondipole_laser_field_step(this, field, time)
Retrieves the NDSFA vector_potential correction. The nondipole field is obtained for consecutive time...
subroutine, public lasers_set_nondipole_parameters(this, ndfield, nd_integration_time)
Set parameters for nondipole SFA calculation.
logical function, public lasers_with_nondipole_field(lasers)
Check if a nondipole SFA correction should be computed for the given laser.
subroutine, public lda_u_update_occ_matrices(this, namespace, mesh, st, phase, energy)
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)
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
subroutine, public messages_input_error(namespace, var, details, row, column)
subroutine, public messages_experimental(name, namespace)
This module handles the communicators for the various parallelization strategies.
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
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.
subroutine, public profiling_in(label, exclude)
Increment in counter and save entry time.
subroutine, public propagation_ops_elec_propagate_ions_and_cell(gr, hm, st, namespace, space, ions_dyn, ions, mc, time, dt_ions)
subroutine, public propagation_ops_elec_update_hamiltonian(namespace, space, st, mesh, hm, ext_partners, time)
integer, parameter, public prop_aetrs
integer, parameter, public prop_crank_nicolson_sparskit
integer, parameter, public prop_crank_nicolson
integer, parameter, public prop_runge_kutta2
integer, parameter, public prop_magnus
integer, parameter, public prop_cfmagnus4
integer, parameter, public prop_caetrs
integer, parameter, public prop_qoct_tddft_propagator
integer, parameter, public prop_exponential_midpoint
integer, parameter, public prop_explicit_magnus3
integer, parameter, public prop_runge_kutta4
integer, parameter, public prop_explicit_runge_kutta4
integer, parameter, public prop_etrs
integer, parameter, public prop_exponential_midpoint_predictor
subroutine, public td_crank_nicolson(hm, namespace, space, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc, use_sparskit)
Crank-Nicolson propagator.
subroutine, public propagator_elec_copy(tro, tri)
subroutine, public propagator_elec_dt_bo(scf, namespace, space, gr, ks, st, hm, ions, ext_partners, mc, iter, dt, ions_dyn, scsteps)
subroutine, public propagator_elec_set_scf_prop(tr, threshold)
subroutine, public propagator_elec_init(gr, namespace, st, tr, ks_pot, have_fields, family_is_mgga_with_exc, relax_cell)
subroutine, public propagator_elec_remove_scf_prop(tr)
logical pure function, public propagator_elec_ions_are_propagated(tr)
subroutine, public propagator_elec_dt(ks, namespace, space, hm, gr, st, tr, time, dt, nt, ions_dyn, ions, ext_partners, mc, outp, write_handler, scsteps, update_energy, qcchi)
Propagates st from time - dt to t. If dt<0, it propagates backwards from t+|dt| to t.
subroutine, public propagator_elec_end(tr)
subroutine, public td_aetrs(namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc)
Propagator with approximate enforced time-reversal symmetry.
subroutine, public td_etrs_sc(ks, namespace, space, hm, ext_partners, gr, st, tr, time, dt, ions_dyn, ions, mc, sctol, scsteps)
Propagator with enforced time-reversal symmetry and self-consistency.
subroutine, public td_etrs(ks, namespace, space, hm, ext_partners, gr, st, tr, time, dt, ions_dyn, ions, mc)
Propagator with enforced time-reversal symmetry.
subroutine, public td_caetrs(ks, namespace, space, hm, ext_partners, gr, st, tr, time, dt, ions_dyn, ions, mc)
Propagator with approximate enforced time-reversal symmetry.
subroutine, public td_aetrs_sc(ks, namespace, space, hm, ext_partners, gr, st, tr, time, dt, ions_dyn, ions, mc, sctol, scsteps)
Propagator with approximate enforced time-reversal symmetry and self-consistency.
subroutine, public exponential_midpoint_predictor(hm, ks, namespace, space, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc)
Exponential midpoint with prediction of the half time step This is equivalent to an explicit Magnus i...
subroutine, public exponential_midpoint(hm, namespace, space, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc)
Exponential midpoint.
subroutine, public td_magnus(hm, ext_partners, gr, st, tr, namespace, time, dt)
Magnus propagator.
subroutine, public td_cfmagnus4(ks, namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc, iter)
Commutator-free Magnus propagator of order 4. This method has been developed for linear systems and i...
subroutine, public td_explicit_magnus3(ks, namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc)
Third-order explicit Magnus propagator. This implements equation (22) from Casas, F....
subroutine, public td_cfmagnus4_sc(ks, namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc, iter, sctol, scsteps)
Commutator-free Magnus propagator of order 4 with self-consistency.
subroutine, public td_qoct_tddft_propagator(hm, namespace, space, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc)
Propagator specifically designed for the QOCT+TDDFT problem.
subroutine, public td_runge_kutta2(ks, namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners)
subroutine, public td_runge_kutta4(ks, namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners)
subroutine, public td_explicit_runge_kutta4(ks, namespace, space, hm, gr, st, time, dt, ions_dyn, ions, ext_partners, qcchi)
subroutine, public propagator_rk_end()
type(algorithmic_operation_t), parameter, public op_verlet_compute_acc
type(algorithmic_operation_t), parameter, public op_verlet_compute_vel
subroutine, public sparskit_solver_init(namespace, n, sk, is_complex)
subroutine, public sparskit_solver_end(sk)
subroutine, public sparskit_solver_copy(sko, ski)
This module implements the calculation of the stress tensor.
subroutine, public stress_calculate(namespace, gr, hm, st, ions, ks, ext_partners)
This computes the total stress on the lattice.
integer, parameter, public out_separate_forces
subroutine, public v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners, calc_eigenval, time, calc_energy, calc_current, force_semilocal)
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.
Stores all communicators and groups.
This is the datatype that contains the objects that are propagated: in principle this could be both t...
The states_elec_t class contains all electronic wave functions.
Time-dependent Write Properties.