39 use,
intrinsic :: iso_fortran_env
74 real(real64),
allocatable :: vmagnus(:, :, :)
80 procedure magnus4_operator_constructor
86 type(hamiltonian_elec_t),
pointer :: hm1 => null()
87 type(hamiltonian_elec_t),
pointer :: hm2 => null()
88 real(real64) :: c1 =
m_zero
89 real(real64) :: c2 =
m_zero
95 procedure magnus3_linear_operator_constructor
101 type(hamiltonian_elec_t),
pointer :: hm1 => null()
102 type(hamiltonian_elec_t),
pointer :: hm2 => null()
103 type(hamiltonian_elec_t),
pointer :: hm3 => null()
104 type(hamiltonian_elec_t),
pointer :: hm4 => null()
105 real(real64) :: dt =
m_zero
111 procedure magnus3_operator_constructor
119 subroutine td_magnus(hm, ext_partners, gr, st, tr, namespace, time, dt)
120 type(hamiltonian_elec_t),
intent(inout) :: hm
121 type(partner_list_t),
intent(in) :: ext_partners
122 type(grid_t),
intent(in) :: gr
123 type(states_elec_t),
intent(inout) :: st
124 type(propagator_base_t),
intent(inout) :: tr
125 type(namespace_t),
intent(in) :: namespace
126 real(real64),
intent(in) :: time
127 real(real64),
intent(in) :: dt
130 real(real64) :: atime(2)
131 real(real64),
allocatable :: vaux(:, :, :), vmagnus(:, :, :), pot(:)
132 type(lasers_t),
pointer :: lasers
133 class(operator_t),
pointer :: op
139 safe_allocate(vaux(1:gr%np, 1:st%d%nspin, 1:2))
140 safe_allocate(vmagnus(1:gr%np, 1:st%d%nspin, 1:2))
156 if(
associated(lasers))
then
157 do i = 1, lasers%no_lasers
160 safe_allocate(pot(1:gr%np))
163 do is = 1, st%d%nspin
164 vaux(:, is, j) = vaux(:, is, j) + pot(:)
166 safe_deallocate_a(pot)
168 write(
message(1),
'(a)')
'The Magnus propagator cannot be used with magnetic fields, or'
169 write(
message(2),
'(a)')
'with an electric field described in the velocity gauge.'
176 vmagnus(:, :, 2) =
m_half*(vaux(:, :, 1) + vaux(:, :, 2))
177 vmagnus(:, :, 1) = (
sqrt(
m_three)/12.0_real64)*dt*(vaux(:, :, 2) - vaux(:, :, 1))
181 safe_deallocate_p(op)
183 safe_deallocate_a(vaux)
184 safe_deallocate_a(vmagnus)
190 class(
mesh_t),
target,
intent(in) :: mesh
192 real(real64),
intent(in) :: vmagnus(:, :, :)
198 call this%init(namespace, mesh, hm)
202 assert(
size(vmagnus, 1) >= mesh%np)
203 assert(
size(vmagnus, 2) == hm%d%nspin)
204 assert(
size(vmagnus, 3) == 2)
206 write(
message(1),
'(a)')
'Magnus operators only implemented for electrons at the moment'
209 safe_allocate_source(this%vmagnus, vmagnus)
216 class(
batch_t),
intent(inout) :: psib
217 class(
batch_t),
intent(inout) :: hpsib
224 select type(hm => this%hm)
233 assert(psib%nst == hpsib%nst)
235 ispin = hm%d%get_spin_index(psib%ik)
237 call hpsib%copy_to(auxpsib, copy_data=.false.)
238 call hpsib%copy_to(aux2psib, copy_data=.false.)
245 call auxpsib%copy_data_to(this%mesh%np, hpsib)
248 call batch_mul(this%mesh%np, hm%abs_boundaries%mf(1:this%mesh%np), psib, aux2psib)
251 call batch_mul(this%mesh%np, this%vmagnus(1:this%mesh%np, ispin, 2), psib, aux2psib)
255 call batch_mul(this%mesh%np, this%vmagnus(1:this%mesh%np, ispin, 1), auxpsib, aux2psib)
259 call batch_mul(this%mesh%np, this%vmagnus(1:this%mesh%np, ispin, 1), psib, auxpsib)
267 message(1) =
"Internal error: imcompatible batch_t in magnus4_operator_apply for argument hpsib."
271 message(1) =
"Internal error: imcompatible batch_t in magnus4_operator_apply for argument psib."
283 class(
mesh_t),
target,
intent(in) :: mesh
286 real(real64),
intent(in) :: c1
287 real(real64),
intent(in) :: c2
293 call this%init(namespace, mesh, hm1)
306 class(
mesh_t),
intent(in) :: mesh
314 if (hm_ref%phase%is_allocated())
call hm_ref%phase%unset_phase_corr(mesh, psib)
315 if (hm_stage%phase%is_allocated())
call hm_stage%phase%set_phase_corr(mesh, psib)
319 if (hm_stage%phase%is_allocated())
then
320 call hm_stage%phase%unset_phase_corr(mesh, hpsib)
321 call hm_stage%phase%unset_phase_corr(mesh, psib)
323 if (hm_ref%phase%is_allocated())
then
324 call hm_ref%phase%set_phase_corr(mesh, hpsib)
325 call hm_ref%phase%set_phase_corr(mesh, psib)
335 class(
batch_t),
intent(inout) :: psib
336 class(
batch_t),
intent(inout) :: hpsib
342 select type (hm => this%hm)
350 assert(psib%nst == hpsib%nst)
352 call hpsib%copy_to(auxpsib, copy_data=.false.)
358 call batch_axpy(this%mesh%np, this%c2, auxpsib, hpsib)
362 message(1) =
"Internal error: imcompatible batch_t in magnus3_linear_operator_apply for argument hpsib."
366 message(1) =
"Internal error: imcompatible batch_t in magnus3_linear_operator_apply for argument psib."
378 class(
mesh_t),
target,
intent(in) :: mesh
383 real(real64),
intent(in) :: dt
389 call this%init(namespace, mesh, hm1)
406 class(
batch_t),
intent(inout) :: psib
407 class(
batch_t),
intent(inout) :: hpsib
409 type(
wfs_elec_t) :: k1psib, k2psib, k3psib, k4psib
410 type(
wfs_elec_t) :: work1psib, work2psib, sum12psib, commpsib
414 select type (hm => this%hm)
422 assert(psib%nst == hpsib%nst)
424 call hpsib%copy_to(k1psib, copy_data=.false.)
425 call hpsib%copy_to(k2psib, copy_data=.false.)
426 call hpsib%copy_to(k3psib, copy_data=.false.)
427 call hpsib%copy_to(k4psib, copy_data=.false.)
428 call hpsib%copy_to(work1psib, copy_data=.false.)
429 call hpsib%copy_to(work2psib, copy_data=.false.)
430 call hpsib%copy_to(sum12psib, copy_data=.false.)
431 call hpsib%copy_to(commpsib, copy_data=.false.)
442 call k1psib%copy_data_to(this%mesh%np, hpsib)
456 call k1psib%copy_data_to(this%mesh%np, sum12psib)
467 call batch_axpy(this%mesh%np, (
m_zi*this%dt)/12.0_real64, work1psib, hpsib)
478 message(1) =
"Internal error: imcompatible batch_t in magnus3_operator_apply for argument hpsib."
482 message(1) =
"Internal error: imcompatible batch_t in magnus3_operator_apply for argument psib."
495 subroutine td_explicit_magnus3(ks, namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc)
496 type(
v_ks_t),
intent(inout) :: ks
500 type(
grid_t),
target,
intent(inout) :: gr
503 real(real64),
intent(in) :: time
504 real(real64),
intent(in) :: dt
506 type(
ions_t),
intent(inout) :: ions
531 if (
associated(gfield))
then
536 call v_ks_calc(ks, namespace, space, hm, st2, ions, ext_partners, &
537 calc_current = .false., calc_energy = .false., calc_eigenval = .false.)
547 safe_deallocate_p(op)
550 call v_ks_calc(ks, namespace, space, hm, st3, ions, ext_partners, &
551 calc_current = .false., calc_energy = .false., calc_eigenval = .false.)
562 ext_partners, mc, time,
m_half*dt)
563 if (
associated(gfield))
then
568 call v_ks_calc(ks, namespace, space, hm, st4, ions, ext_partners, &
569 calc_current = .false., calc_energy = .false., calc_eigenval = .false.)
579 safe_deallocate_p(op)
583 if (
associated(gfield))
then
617 subroutine td_cfmagnus4(ks, namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc, iter)
618 type(
v_ks_t),
target,
intent(inout) :: ks
622 type(
grid_t),
target,
intent(inout) :: gr
625 real(real64),
intent(in) :: time
626 real(real64),
intent(in) :: dt
628 type(
ions_t),
intent(inout) :: ions
631 integer,
intent(in) :: iter
633 real(real64) :: alpha1, alpha2, c1, c2, t1, t2, dt1, dt2
644 t1 = time - dt + c1*dt
645 t2 = time - dt + c2*dt
652 ext_partners, mc, t1, dt1, save_pos=.
true.)
653 if (
associated(gfield))
then
657 call hm%ks_pot%interpolate_potentials(tr%vks_old, 4, time, dt, t1)
662 ext_partners, mc, t2, dt2)
663 if (
associated(gfield))
then
667 call hm%ks_pot%interpolate_potentials(tr%vks_old, 4, time, dt, t2)
672 if (
associated(gfield))
then
678 safe_deallocate_p(op)
682 safe_deallocate_p(op)
692 subroutine td_cfmagnus4_sc(ks, namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc, &
693 iter, sctol, scsteps)
694 type(
v_ks_t),
intent(inout) :: ks
698 type(
grid_t),
intent(inout) :: gr
701 real(real64),
intent(in) :: time
702 real(real64),
intent(in) :: dt
704 type(
ions_t),
intent(inout) :: ions
707 integer,
intent(in) :: iter
708 real(real64),
intent(in) :: sctol
709 integer,
optional,
intent(out) :: scsteps
714 integer,
parameter :: niter = 10
728 do iter_sc = 1, niter
731 call hm%ks_pot%get_interpolated_potentials(tr%vks_old, 0, storage=vhxc_pred)
733 call td_cfmagnus4(ks, namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc, iter)
735 call v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners, &
736 time = time, calc_current = .false., calc_energy = .false., calc_eigenval = .false.)
739 diff = hm%ks_pot%check_convergence(vhxc_pred, gr, st%rho, st%qtot)
743 call hm%ks_pot%set_interpolated_potentials(tr%vks_old, 0)
751 if (diff <= sctol)
exit
752 if (iter_sc /= niter)
then
765 if (
present(scsteps)) scsteps = iter_sc
batchified version of the BLAS axpy routine:
scale a batch by a constant or vector
double sqrt(double __x) __attribute__((__nothrow__
integer, parameter, public imaginary_absorbing
This module implements batches of mesh functions.
This module implements common operations on batches of mesh functions.
This module implements a calculator for the density and defines related functions.
type(gauge_field_t) function, pointer, public list_get_gauge_field(partners)
type(lasers_t) function, pointer, public list_get_lasers(partners)
real(real64), parameter, public m_two
real(real64), parameter, public m_zero
real(real64), parameter, public m_four
integer, parameter, public independent_particles
Theory level.
complex(real64), parameter, public m_zi
real(real64), parameter, public m_half
real(real64), parameter, public m_one
real(real64), parameter, public m_three
This module implements the underlying real-space grid.
This module defines an abstract class for Hamiltonians.
integer, parameter, public term_non_local_potential
integer, parameter, public term_kinetic
subroutine, public zhamiltonian_elec_apply_batch(hm, namespace, mesh, psib, hpsib, terms, set_bc)
subroutine, public hamiltonian_elec_end(hm)
subroutine, public hamiltonian_elec_copy(hm_out, hm_in)
Deep-copy a hamiltonian_elec_t snapshot.
subroutine, public zhamiltonian_elec_external(this, mesh, psib, vpsib)
This module defines classes and functions for interaction partners.
A module to handle KS potential, without the external potential.
integer, parameter, public e_field_electric
integer, parameter, public e_field_vector_potential
subroutine, public laser_potential(laser, mesh, pot, time)
integer pure elemental function, public laser_kind(laser)
integer, parameter, public e_field_magnetic
subroutine, public lda_u_write_u(this, iunit, namespace)
subroutine, public lda_u_write_v(this, iunit, namespace)
integer, parameter, public dft_u_none
subroutine, public lda_u_update_occ_matrices(this, namespace, mesh, st, phase, energy)
This module defines the meshes, which are used in Octopus.
subroutine, public messages_not_implemented(feature, namespace)
subroutine, public messages_new_line()
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_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
This module handles the communicators for the various parallelization strategies.
subroutine, public potential_interpolation_interpolate(potential_interpolation, order, time, dt, t, vhxc, vtau)
subroutine, public propagation_ops_elec_restore_ions(wo, ions_dyn, ions)
subroutine, public propagation_ops_elec_propagate_gauge_field(wo, gfield, dt, time, save_gf)
subroutine, public propagation_ops_elec_update_hamiltonian(namespace, space, st, mesh, hm, ext_partners, time)
subroutine, public propagation_ops_elec_fuse_density_exp_apply(te, namespace, st, gr, hm, dt, dt2, op)
subroutine, public propagation_ops_elec_restore_gauge_field(wo, namespace, space, hm, mesh, ext_partners)
subroutine, public propagation_ops_elec_move_ions(wo, gr, hm, st, namespace, space, ions_dyn, ions, ext_partners, mc, time, dt, save_pos)
subroutine, public propagation_ops_elec_exp_apply(te, namespace, st, mesh, hm, dt, op)
type(magnus3_linear_operator_t) function, pointer magnus3_linear_operator_constructor(namespace, mesh, hm1, hm2, c1, c2)
Build a linear Hamiltonian operator c1*H1 + c2*H2.
subroutine magnus4_operator_apply(this, psib, hpsib)
subroutine magnus3_operator_apply(this, psib, hpsib)
Apply the explicit Magnus-3 operator (weighted stage sum plus commutator term). The equation refers t...
subroutine magnus3_linear_operator_apply(this, psib, hpsib)
Apply the linear Hamiltonian operator for the explicit Magnus-3 stages.
subroutine, public td_magnus(hm, ext_partners, gr, st, tr, namespace, time, dt)
Magnus propagator.
type(magnus4_operator_t) function, pointer magnus4_operator_constructor(namespace, mesh, hm, vmagnus)
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....
type(magnus3_operator_t) function, pointer magnus3_operator_constructor(namespace, mesh, hm1, hm2, hm3, hm4, dt)
Build the explicit Magnus-3 final-stage operator from stage Hamiltonians.
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 magnus3_apply_stage_in_ref_phase(namespace, mesh, hm_ref, hm_stage, psib, hpsib)
Apply a stage Hamiltonian in the reference Hamiltonian phase convention.
This module handles groups of electronic batches and their parallel distribution.
subroutine, public states_elec_group_copy(d, group_in, group_out, copy_data, special)
make a copy of a group
subroutine, public states_elec_end(st)
finalize the states_elec_t object
subroutine, public states_elec_copy(stout, stin, exclude_wfns, exclude_eigenval, special)
make a (selective) copy of a states_elec_t object
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, public family_is_mgga_with_exc(xcs)
Is the xc function part of the mGGA family with an energy functional.
Class defining batches of mesh functions.
Extension of space that contains the knowledge of the spin dimension.
Description of the grid, containing information on derivatives, stencil, and symmetries.
The abstract Hamiltonian class defines a skeleton for specific implementations.
Describes mesh distribution to nodes.
Stores all communicators and groups.
Class to encapsulate the operation for the explicit Magnus 3 propagator.
Class to encapsulate linear combinations of two Hamiltonians.
The states_elec_t class contains all electronic wave functions.
batches of electronic states