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_mf(this%mesh%np, hm%abs_boundaries%mf(1:this%mesh%np), psib, aux2psib)
251 call batch_mul_mf(this%mesh%np, this%vmagnus(1:this%mesh%np, ispin, 2), psib, aux2psib)
255 call batch_mul_mf(this%mesh%np, this%vmagnus(1:this%mesh%np, ispin, 1), auxpsib, aux2psib)
259 call batch_mul_mf(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.)
356 call batch_axpby(this%mesh%np, this%c2, auxpsib, this%c1, hpsib)
360 message(1) =
"Internal error: imcompatible batch_t in magnus3_linear_operator_apply for argument hpsib."
364 message(1) =
"Internal error: imcompatible batch_t in magnus3_linear_operator_apply for argument psib."
376 class(
mesh_t),
target,
intent(in) :: mesh
381 real(real64),
intent(in) :: dt
387 call this%init(namespace, mesh, hm1)
404 class(
batch_t),
intent(inout) :: psib
405 class(
batch_t),
intent(inout) :: hpsib
407 type(
wfs_elec_t) :: k1psib, k2psib, k3psib, k4psib
408 type(
wfs_elec_t) :: work1psib, work2psib, sum12psib, commpsib
412 select type (hm => this%hm)
420 assert(psib%nst == hpsib%nst)
422 call hpsib%copy_to(k1psib, copy_data=.false.)
423 call hpsib%copy_to(k2psib, copy_data=.false.)
424 call hpsib%copy_to(k3psib, copy_data=.false.)
425 call hpsib%copy_to(k4psib, copy_data=.false.)
426 call hpsib%copy_to(work1psib, copy_data=.false.)
427 call hpsib%copy_to(work2psib, copy_data=.false.)
428 call hpsib%copy_to(sum12psib, copy_data=.false.)
429 call hpsib%copy_to(commpsib, copy_data=.false.)
440 call k1psib%copy_data_to(this%mesh%np, hpsib)
453 call k1psib%copy_data_to(this%mesh%np, sum12psib)
464 call batch_axpy(this%mesh%np, (
m_zi*this%dt)/12.0_real64, work1psib, hpsib)
475 message(1) =
"Internal error: imcompatible batch_t in magnus3_operator_apply for argument hpsib."
479 message(1) =
"Internal error: imcompatible batch_t in magnus3_operator_apply for argument psib."
492 subroutine td_explicit_magnus3(ks, namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc)
493 type(
v_ks_t),
intent(inout) :: ks
497 type(
grid_t),
target,
intent(inout) :: gr
500 real(real64),
intent(in) :: time
501 real(real64),
intent(in) :: dt
503 type(
ions_t),
intent(inout) :: ions
528 if (
associated(gfield))
then
533 call v_ks_calc(ks, namespace, space, hm, st2, ions, ext_partners, &
534 calc_current = .false., calc_energy = .false., calc_eigenval = .false.)
544 safe_deallocate_p(op)
547 call v_ks_calc(ks, namespace, space, hm, st3, ions, ext_partners, &
548 calc_current = .false., calc_energy = .false., calc_eigenval = .false.)
559 ext_partners, mc, time,
m_half*dt)
560 if (
associated(gfield))
then
565 call v_ks_calc(ks, namespace, space, hm, st4, ions, ext_partners, &
566 calc_current = .false., calc_energy = .false., calc_eigenval = .false.)
576 safe_deallocate_p(op)
580 if (
associated(gfield))
then
614 subroutine td_cfmagnus4(ks, namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc, iter)
615 type(
v_ks_t),
target,
intent(inout) :: ks
619 type(
grid_t),
target,
intent(inout) :: gr
622 real(real64),
intent(in) :: time
623 real(real64),
intent(in) :: dt
625 type(
ions_t),
intent(inout) :: ions
628 integer,
intent(in) :: iter
630 real(real64) :: alpha1, alpha2, c1, c2, t1, t2, dt1, dt2
641 t1 = time - dt + c1*dt
642 t2 = time - dt + c2*dt
649 ext_partners, mc, t1, dt1, save_pos=.
true.)
650 if (
associated(gfield))
then
654 call hm%ks_pot%interpolate_potentials(tr%vks_old, 4, time, dt, t1)
659 ext_partners, mc, t2, dt2)
660 if (
associated(gfield))
then
664 call hm%ks_pot%interpolate_potentials(tr%vks_old, 4, time, dt, t2)
669 if (
associated(gfield))
then
675 safe_deallocate_p(op)
679 safe_deallocate_p(op)
689 subroutine td_cfmagnus4_sc(ks, namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc, &
690 iter, sctol, scsteps)
691 type(
v_ks_t),
intent(inout) :: ks
695 type(
grid_t),
intent(inout) :: gr
698 real(real64),
intent(in) :: time
699 real(real64),
intent(in) :: dt
701 type(
ions_t),
intent(inout) :: ions
704 integer,
intent(in) :: iter
705 real(real64),
intent(in) :: sctol
706 integer,
optional,
intent(out) :: scsteps
711 integer,
parameter :: niter = 10
725 do iter_sc = 1, niter
728 call hm%ks_pot%get_interpolated_potentials(tr%vks_old, 0, storage=vhxc_pred)
730 call td_cfmagnus4(ks, namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc, iter)
732 call v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners, &
733 time = time, calc_current = .false., calc_energy = .false., calc_eigenval = .false.)
736 diff = hm%ks_pot%check_convergence(vhxc_pred, gr, st%rho, st%qtot)
740 call hm%ks_pot%set_interpolated_potentials(tr%vks_old, 0)
748 if (diff <= sctol)
exit
749 if (iter_sc /= niter)
then
762 if (
present(scsteps)) scsteps = iter_sc
batchified version of the BLAS axpy routine:
batchified multiplication by mesh function with optional conjugation:
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