35 use,
intrinsic :: iso_fortran_env
105 character(len=*),
public,
parameter :: EM_RESP_PHOTONS_DIR =
"em_resp_photons/"
109 type(linear_solver_t) :: solver
111 type(mixfield_t),
pointer :: mixfield
112 type(scf_tol_t) :: scf_tol
113 real(real64),
allocatable :: fxc(:,:,:)
114 real(real64),
allocatable :: fxc_grad(:,:,:,:,:)
115 real(real64),
allocatable :: fxc_grad_spin(:,:,:,:)
116 logical :: gga = .false.
117 real(real64),
allocatable :: kxc(:,:,:,:)
118 real(real64),
pointer,
contiguous :: drhs(:, :, :, :) => null()
119 complex(real64),
pointer,
contiguous :: zrhs(:, :, :, :) => null()
120 real(real64),
pointer,
contiguous :: dinhomog(:, :, :, :, :) => null()
121 complex(real64),
pointer,
contiguous :: zinhomog(:, :, :, :, :) => null()
122 logical :: add_fxc_kernel
124 logical :: occ_response
125 logical :: last_occ_response
126 logical :: occ_response_by_sternheimer
127 logical :: preorthogonalization
128 logical,
public :: has_photons
129 real(real64) :: domega
130 complex(real64) :: zomega
131 real(real64),
allocatable,
public :: dphoton_coord_q(:, :)
132 complex(real64),
allocatable,
public :: zphoton_coord_q(:, :)
133 real(real64) :: pt_eta
134 type(photon_mode_t) :: pt_modes
136 real(real64) :: coeff_hartree
146 subroutine sternheimer_init(this, namespace, space, gr, st, hm, ks, mc, wfs_are_cplx, set_ham_var, set_occ_response, &
147 set_last_occ_response, occ_response_by_sternheimer)
148 type(sternheimer_t),
intent(out) :: this
149 type(namespace_t),
intent(in) :: namespace
150 class(space_t),
intent(in) :: space
151 type(grid_t),
intent(inout) :: gr
152 type(states_elec_t),
intent(in) :: st
153 type(hamiltonian_elec_t),
intent(in) :: hm
154 type(v_ks_t),
intent(in) :: ks
155 type(multicomm_t),
intent(in) :: mc
156 logical,
intent(in) :: wfs_are_cplx
157 integer,
optional,
intent(in) :: set_ham_var
158 logical,
optional,
intent(in) :: set_occ_response
159 logical,
optional,
intent(in) :: set_last_occ_response
160 logical,
optional,
intent(in) :: occ_response_by_sternheimer
162 logical :: add_hartree
163 integer :: ham_var, iunit
164 logical :: default_preorthog
188 write(
message(1),
'(a,f12.6)')
'Partial occupation at the Fermi level: ', st%smear%ef_occ
189 message(2) =
'Semiconducting smearing cannot be used for Sternheimer in this situation.'
193 if (wfs_are_cplx)
then
194 call mix_init(this%mixer, namespace, space, gr%der, gr%np, st%d%nspin, func_type_=
type_cmplx)
196 call mix_init(this%mixer, namespace, space, gr%der, gr%np, st%d%nspin, func_type_=
type_float)
201 this%occ_response_by_sternheimer =
optional_default(occ_response_by_sternheimer, .false.)
216 .and. .not. this%occ_response
217 call parse_variable(namespace,
'Preorthogonalization', default_preorthog, this%preorthogonalization)
241 if (
present(set_ham_var))
then
242 ham_var = set_ham_var
244 call parse_variable(namespace,
'HamiltonianVariation', 3, ham_var)
250 this%add_fxc_kernel = ((ham_var / 2) == 1)
251 add_hartree = (mod(ham_var, 2) == 1)
253 this%add_fxc_kernel = .false.
254 add_hartree = .false.
258 if (hm%kpoints%use_symmetries .and. (add_hartree .or. this%add_fxc_kernel))
then
259 message(1) =
"The first-order density is accumulated on the symmetry-reduced k-point grid"
260 message(2) =
"without symmetry unfolding, so the self-consistent (Hartree + fxc) response"
261 message(3) =
"may be incorrect unless the k-point grid was reduced with SymmetryBreakDir"
262 message(4) =
"set along the perturbation direction."
266 message(1) =
"Variation of the Hamiltonian in Sternheimer equation: V_ext"
267 if (add_hartree)
write(
message(1),
'(2a)') trim(
message(1)),
' + hartree'
268 if (this%add_fxc_kernel)
write(
message(1),
'(2a)') trim(
message(1)),
' + fxc'
270 message(2) =
"Solving Sternheimer equation for"
271 if (this%occ_response)
then
272 write(
message(2),
'(2a)') trim(
message(2)),
' full linear response.'
274 write(
message(2),
'(2a)') trim(
message(2)),
' linear response in unoccupied subspace only.'
277 message(3) =
"Sternheimer preorthogonalization:"
278 if (this%preorthogonalization)
then
288 if (ham_var == 0)
then
289 call scf_tol_init(this%scf_tol, namespace, st%qtot, tol_scheme = 0)
295 this%coeff_hartree =
m_zero
296 if (this%add_fxc_kernel)
then
297 this%coeff_hartree = this%coeff_hartree - ks%xc%lrc%alpha / (
m_four *
m_pi)
299 if (add_hartree) this%coeff_hartree = this%coeff_hartree +
m_one
300 if (this%add_fxc_kernel)
then
311 call parse_variable(namespace,
'EnablePhotons', .false., this%has_photons)
314 if (this%has_photons)
then
319 call io_mkdir(em_resp_photons_dir, namespace)
320 iunit =
io_open(em_resp_photons_dir //
'photon_modes', namespace, action=
'write')
322 safe_allocate(this%zphoton_coord_q(1:this%pt_modes%nmodes, 1:space%dim))
347 safe_deallocate_a(this%zphoton_coord_q)
353 nullify(this%mixfield)
355 safe_deallocate_a(this%fxc)
356 safe_deallocate_a(this%fxc_grad)
357 safe_deallocate_a(this%fxc_grad_spin)
368 type(
grid_t),
intent(in) :: gr
370 type(
xc_t),
intent(in) :: xc
372 real(real64),
allocatable :: rho(:, :)
376 safe_allocate(this%fxc(1:gr%np, 1:st%d%nspin, 1:st%d%nspin))
377 safe_allocate(rho(1:gr%np_part, 1:st%d%nspin))
380 this%gga =
in_family(xc%kernel_family, [xc_family_gga])
382 safe_allocate(this%fxc_grad(1:gr%np, 1:gr%der%dim, 1:gr%der%dim, 1:st%d%nspin, 1:st%d%nspin))
384 safe_allocate(this%fxc_grad_spin(1:gr%np, 1:gr%der%dim, 1:st%d%nspin, 1:st%d%nspin))
386 safe_allocate(this%fxc_grad_spin(0, 0, 0, 0))
388 call xc_get_fxc(xc, gr, namespace, rho, st%d%ispin, this%fxc, this%fxc_grad, this%fxc_grad_spin)
390 call xc_get_fxc(xc, gr, namespace, rho, st%d%ispin, this%fxc)
393 safe_deallocate_a(rho)
403 class(
mesh_t),
intent(in) :: mesh
405 type(
xc_t),
intent(in) :: xc
407 real(real64),
allocatable :: rho(:, :)
411 if (this%add_fxc())
then
412 safe_allocate(this%kxc(1:mesh%np, 1:st%d%nspin, 1:st%d%nspin, 1:st%d%nspin))
415 safe_allocate(rho(1:mesh%np, 1:st%d%nspin))
417 call xc_get_kxc(xc, mesh, namespace, rho, st%d%ispin, this%kxc)
418 safe_deallocate_a(rho)
431 safe_deallocate_a(this%kxc)
439 rr = this%add_fxc_kernel
459 have =
associated(this%drhs) .or.
associated(this%zrhs)
475 logical pure function sternheimer_have_inhomog(this) result(have)
477 have =
associated(this%dinhomog) .or.
associated(this%zinhomog)
486 nullify(this%dinhomog)
487 nullify(this%zinhomog)
493 integer pure function swap_sigma(sigma)
494 integer,
intent(in) :: sigma
505 character(len=100) function wfs_tag_sigma(namespace, base_name, isigma)
result(str)
506 type(namespace_t),
intent(in) :: namespace
507 character(len=*),
intent(in) :: base_name
508 integer,
intent(in) :: isigma
510 character :: sigma_char
520 write(message(1),
'(a,i2)')
"Illegal integer isigma passed to wfs_tag_sigma: ", isigma
521 call messages_fatal(1, namespace=namespace)
524 str = trim(base_name) // sigma_char
533 type(namespace_t),
intent(in) :: namespace
534 character(len=*),
intent(in) :: old_prefix
535 character(len=*),
intent(in) :: new_prefix
539 call messages_obsolete_variable(namespace, trim(old_prefix)//
'Preorthogonalization', trim(new_prefix)//
'Preorthogonalization')
540 call messages_obsolete_variable(namespace, trim(old_prefix)//
'HamiltonianVariation', trim(new_prefix)//
'HamiltonianVariation')
542 call linear_solver_obsolete_variables(namespace, old_prefix, new_prefix)
543 call scf_tol_obsolete_variables(namespace, old_prefix, new_prefix)
551 class(mesh_t),
intent(in) :: mesh
552 integer,
intent(in) :: nspin
553 integer,
intent(in) :: nsigma
554 complex(real64),
intent(in) :: lr_rho(:,:)
555 complex(real64),
intent(inout) :: hvar(:,:,:)
556 integer,
intent(in) :: idir
558 real(real64),
allocatable :: lambda_dot_r(:)
559 complex(real64),
allocatable :: s_lr_rho(:), vp_dip_self_ener(:), vp_bilinear_el_pt(:)
560 integer :: nm, is, ii, ip
561 complex(real64) :: first_moments
564 call profiling_in(
'CALC_HVAR_PHOTONS')
566 nm = this%pt_modes%nmodes
569 safe_allocate(s_lr_rho(1:mesh%np))
570 safe_allocate(lambda_dot_r(1:mesh%np))
571 safe_allocate(vp_dip_self_ener(1:mesh%np))
572 safe_allocate(vp_bilinear_el_pt(1:mesh%np))
577 s_lr_rho = s_lr_rho + lr_rho(:, is)
581 vp_dip_self_ener = m_zero
582 vp_bilinear_el_pt = m_zero
586 lambda_dot_r(ip) = this%pt_modes%lambda(ii)*this%pt_modes%pol_dipole(ip, ii)
589 first_moments = zmf_integrate(mesh, lambda_dot_r(1:mesh%np)*s_lr_rho(1:mesh%np))
592 this%zphoton_coord_q(ii, idir) = -m_half * &
593 ((m_one/(this%zomega - cmplx(this%pt_modes%omega(ii),-this%pt_eta, real64))) - &
594 (m_one/(this%zomega + cmplx(this%pt_modes%omega(ii), this%pt_eta, real64)))) *first_moments
597 vp_bilinear_el_pt = vp_bilinear_el_pt - &
598 this%pt_modes%omega(ii)*lambda_dot_r(1:mesh%np)*this%zphoton_coord_q(ii, idir)
601 vp_dip_self_ener = vp_dip_self_ener + first_moments*lambda_dot_r(1:mesh%np)
606 hvar(ip, 1, 1) = hvar(ip, 1, 1) + vp_dip_self_ener(ip) + vp_bilinear_el_pt(ip)
610 hvar(1:mesh%np, ii, 1) = hvar(1:mesh%np, 1, 1)
613 safe_deallocate_a(s_lr_rho)
614 safe_deallocate_a(lambda_dot_r)
615 safe_deallocate_a(vp_dip_self_ener)
616 safe_deallocate_a(vp_bilinear_el_pt)
618 if (nsigma == 2) hvar(1:mesh%np, 1:nspin, 2) = conjg(hvar(1:mesh%np, 1:nspin, 1))
620 call profiling_out(
'CALC_HVAR_PHOTONS')
625#include "complex.F90"
626#include "sternheimer_inc.F90"
631#include "sternheimer_inc.F90"
Prints out to iunit a message in the form: ["InputVariable" = value] where "InputVariable" is given b...
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.
subroutine, public states_elec_total_density(st, mesh, total_rho)
This routine calculates the total electronic density.
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
integer, parameter, public spin_polarized
real(real64), parameter, public m_zero
real(real64), parameter, public m_four
real(real64), parameter, public m_pi
some mathematical constants
integer, parameter, public independent_particles
Theory level.
real(real64), parameter, public m_epsilon
real(real64), parameter, public m_one
This module implements the underlying real-space grid.
subroutine, public io_close(iunit, grp)
subroutine, public io_mkdir(fname, namespace, parents)
integer function, public io_open(file, namespace, action, status, form, position, die, recl, grp)
A module to handle KS potential, without the external potential.
integer, parameter, public dft_u_none
subroutine, public linear_solver_end(this)
subroutine, public linear_solver_init(this, namespace, gr, states_are_real, mc, space)
This module is intended to contain "only mathematical" functions and procedures.
This module defines various routines, operating on mesh functions.
This module defines the meshes, which are used in Octopus.
subroutine, public messages_print_with_emphasis(msg, iunit, namespace)
subroutine, public messages_not_implemented(feature, namespace)
character(len=512), private msg
subroutine, public messages_warning(no_lines, all_nodes, namespace)
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_experimental(name, namespace)
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
subroutine, public mix_get_field(this, mixfield)
subroutine, public mix_init(smix, namespace, space, der, d1, d2, def_, func_type_, prefix_)
Initialise mix_t instance.
subroutine, public mix_end(smix)
This module handles the communicators for the various parallelization strategies.
subroutine, public photon_mode_compute_dipoles(this, mesh)
Computes the polarization dipole.
subroutine, public photon_mode_write_info(this, iunit, namespace)
subroutine, public photon_mode_set_n_electrons(this, qtot)
subroutine, public photon_mode_init(this, namespace, dim, photon_free)
subroutine, public scf_tol_init(this, namespace, qtot, def_maximumiter, tol_scheme)
subroutine, public scf_tol_end(this)
integer, parameter, public smear_semiconductor
integer, parameter, public smear_fixed_occ
pure logical function, public states_are_real(st)
This module handles reading and writing restart information for the states_elec_t.
subroutine, public zsternheimer_set_inhomog(this, inhomog)
subroutine, public zsternheimer_calc_hvar(this, namespace, gr, hm, lr, nsigma, hvar, idir, lr_rho, exclude_hartree)
Computes the first-order variation of the Kohn-Sham potential from the stored xc kernel,...
subroutine, public dsternheimer_solve(this, namespace, space, gr, kpoints, st, hm, mc, lr, nsigma, omega, perturbation, restart, rho_tag, wfs_tag, idir, have_restart_rho, have_exact_freq)
This routine calculates the first-order variations of the wavefunctions for an applied perturbation.
subroutine, public zcalc_hvar(namespace, coeff_hartree, gr, hm, lr_rho, nsigma, hvar, fxc, fxc_grad, fxc_grad_spin)
Computes the first-order variation of the Kohn-Sham Hamiltonian.
subroutine, public dsternheimer_calc_hvar(this, namespace, gr, hm, lr, nsigma, hvar, idir, lr_rho, exclude_hartree)
Computes the first-order variation of the Kohn-Sham potential from the stored xc kernel,...
integer pure function, public swap_sigma(sigma)
subroutine sternheimer_build_fxc(this, namespace, gr, st, xc)
Builds the exchange-correlation kernel for computing the density response.
subroutine, public dcalc_kvar(this, mesh, st, lr_rho1, lr_rho2, nsigma, kvar)
logical function, public sternheimer_has_converged(this)
subroutine, public zsternheimer_set_rhs(this, rhs)
character(len=100) function, public wfs_tag_sigma(namespace, base_name, isigma)
subroutine calc_hvar_photons(this, mesh, nspin, lr_rho, nsigma, hvar, idir)
logical pure function, public sternheimer_have_rhs(this)
subroutine, public dsternheimer_solve_order2(sh1, sh2, sh_2ndorder, namespace, space, gr, kpoints, st, hm, mc, lr1, lr2, nsigma, omega1, omega2, pert1, pert2, lr_2ndorder, pert_2ndorder, restart, rho_tag, wfs_tag, have_restart_rho, have_exact_freq, give_pert1psi2, give_dl_eig1)
subroutine, public dsternheimer_set_rhs(this, rhs)
subroutine, public dcalc_hvar(namespace, coeff_hartree, gr, hm, lr_rho, nsigma, hvar, fxc, fxc_grad, fxc_grad_spin)
Computes the first-order variation of the Kohn-Sham Hamiltonian.
pure logical function sternheimer_add_fxc(this)
subroutine, public zsternheimer_solve_order2(sh1, sh2, sh_2ndorder, namespace, space, gr, kpoints, st, hm, mc, lr1, lr2, nsigma, omega1, omega2, pert1, pert2, lr_2ndorder, pert_2ndorder, restart, rho_tag, wfs_tag, have_restart_rho, have_exact_freq, give_pert1psi2, give_dl_eig1)
subroutine, public sternheimer_unset_kxc(this)
subroutine, public zsternheimer_solve(this, namespace, space, gr, kpoints, st, hm, mc, lr, nsigma, omega, perturbation, restart, rho_tag, wfs_tag, idir, have_restart_rho, have_exact_freq)
This routine calculates the first-order variations of the wavefunctions for an applied perturbation.
pure logical function sternheimer_add_hartree(this)
subroutine, public sternheimer_unset_inhomog(this)
logical pure function, public sternheimer_have_inhomog(this)
subroutine, public zcalc_kvar(this, mesh, st, lr_rho1, lr_rho2, nsigma, kvar)
subroutine, public sternheimer_end(this)
subroutine, public sternheimer_obsolete_variables(namespace, old_prefix, new_prefix)
subroutine, public sternheimer_build_kxc(this, namespace, mesh, st, xc)
subroutine, public dsternheimer_set_inhomog(this, inhomog)
subroutine, public sternheimer_init(this, namespace, space, gr, st, hm, ks, mc, wfs_are_cplx, set_ham_var, set_occ_response, set_last_occ_response, occ_response_by_sternheimer)
subroutine, public sternheimer_unset_rhs(this)
type(type_t), parameter, public type_cmplx
type(type_t), parameter, public type_float
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
This module defines the unit system, used for input and output.
type(unit_system_t), public units_inp
the units systems for reading and writing
This module provices a simple timer class which can be used to trigger the writing of a restart file ...
subroutine, public xc_get_fxc(xcs, gr, namespace, rho, ispin, fxc, fxc_grad, fxc_grad_spin)
Returns the exchange-correlation kernel.
subroutine, public xc_get_kxc(xcs, mesh, namespace, rho, ispin, kxc)
pure logical function, public family_is_mgga(family, only_collinear)
Is the xc function part of the mGGA family.
logical pure function, public family_is_hybrid(xcs)
Returns true if the functional is an hybrid functional.
pure logical function, public in_family(family, xc_families)
subroutine, public xc_write_fxc_info(xcs, iunit, namespace)
integer, parameter, public sic_none
no self-interaction correction
subroutine, public xc_sic_write_info(sic, iunit, namespace)
Description of the grid, containing information on derivatives, stencil, and symmetries.
Describes mesh distribution to nodes.
The states_elec_t class contains all electronic wave functions.