34 use,
intrinsic :: iso_fortran_env
101 character(len=*),
public,
parameter :: EM_RESP_PHOTONS_DIR =
"em_resp_photons/"
105 type(linear_solver_t) :: solver
107 type(mixfield_t),
pointer :: mixfield
108 type(scf_tol_t) :: scf_tol
109 real(real64) :: lrc_alpha
110 real(real64),
allocatable :: fxc(:,:,:)
111 real(real64),
allocatable :: kxc(:,:,:,:)
112 real(real64),
pointer,
contiguous :: drhs(:, :, :, :) => null()
113 complex(real64),
pointer,
contiguous :: zrhs(:, :, :, :) => null()
114 real(real64),
pointer,
contiguous :: dinhomog(:, :, :, :, :) => null()
115 complex(real64),
pointer,
contiguous :: zinhomog(:, :, :, :, :) => null()
117 logical :: add_hartree
119 logical :: occ_response
120 logical :: last_occ_response
121 logical :: occ_response_by_sternheimer
122 logical :: preorthogonalization
123 logical,
public :: has_photons
124 real(real64) :: domega
125 complex(real64) :: zomega
126 real(real64),
allocatable,
public :: dphoton_coord_q(:, :)
127 complex(real64),
allocatable,
public :: zphoton_coord_q(:, :)
128 real(real64) :: pt_eta
129 type(photon_mode_t) :: pt_modes
130 integer :: restart_write_interval
137 subroutine sternheimer_init(this, namespace, space, gr, st, hm, xc, mc, wfs_are_cplx, set_ham_var, set_occ_response, &
138 set_last_occ_response, occ_response_by_sternheimer)
139 type(sternheimer_t),
intent(out) :: this
140 type(namespace_t),
intent(in) :: namespace
141 class(space_t),
intent(in) :: space
142 type(grid_t),
intent(inout) :: gr
143 type(states_elec_t),
intent(in) :: st
144 type(hamiltonian_elec_t),
intent(in) :: hm
145 type(xc_t),
intent(in) :: xc
146 type(multicomm_t),
intent(in) :: mc
147 logical,
intent(in) :: wfs_are_cplx
148 integer,
optional,
intent(in) :: set_ham_var
149 logical,
optional,
intent(in) :: set_occ_response
150 logical,
optional,
intent(in) :: set_last_occ_response
151 logical,
optional,
intent(in) :: occ_response_by_sternheimer
153 integer :: ham_var, iunit
154 logical :: default_preorthog
170 write(
message(1),
'(a,f12.6)')
'Partial occupation at the Fermi level: ', st%smear%ef_occ
171 message(2) =
'Semiconducting smearing cannot be used for Sternheimer in this situation.'
175 if (wfs_are_cplx)
then
176 call mix_init(this%mixer, namespace, space, gr%der, gr%np, st%d%nspin, func_type_=
type_cmplx)
178 call mix_init(this%mixer, namespace, space, gr%der, gr%np, st%d%nspin, func_type_=
type_float)
183 this%occ_response_by_sternheimer =
optional_default(occ_response_by_sternheimer, .false.)
198 .and. .not. this%occ_response
199 call parse_variable(namespace,
'Preorthogonalization', default_preorthog, this%preorthogonalization)
223 if (
present(set_ham_var))
then
224 ham_var = set_ham_var
226 call parse_variable(namespace,
'HamiltonianVariation', 3, ham_var)
232 this%add_fxc = ((ham_var / 2) == 1)
233 this%add_hartree = (mod(ham_var, 2) == 1)
235 this%add_fxc = .false.
236 this%add_hartree = .false.
240 message(1) =
"Variation of the Hamiltonian in Sternheimer equation: V_ext"
241 if (this%add_hartree)
write(
message(1),
'(2a)') trim(
message(1)),
' + hartree'
242 if (this%add_fxc)
write(
message(1),
'(2a)') trim(
message(1)),
' + fxc'
244 message(2) =
"Solving Sternheimer equation for"
245 if (this%occ_response)
then
246 write(
message(2),
'(2a)') trim(
message(2)),
' full linear response.'
248 write(
message(2),
'(2a)') trim(
message(2)),
' linear response in unoccupied subspace only.'
251 message(3) =
"Sternheimer preorthogonalization:"
252 if (this%preorthogonalization)
then
262 if (ham_var == 0)
then
263 call scf_tol_init(this%scf_tol, namespace, st%qtot, tol_scheme = 0)
269 this%lrc_alpha = xc%kernel_lrc_alpha
274 call parse_variable(namespace,
'EnablePhotons', .false., this%has_photons)
277 if (this%has_photons)
then
282 call io_mkdir(em_resp_photons_dir, namespace)
283 iunit =
io_open(em_resp_photons_dir //
'photon_modes', namespace, action=
'write')
285 safe_allocate(this%zphoton_coord_q(1:this%pt_modes%nmodes, 1:space%dim))
299 call parse_variable(namespace,
'RestartWriteInterval', 50, this%restart_write_interval)
310 safe_deallocate_a(this%zphoton_coord_q)
316 nullify(this%mixfield)
318 safe_deallocate_a(this%fxc)
329 type(
grid_t),
intent(in) :: gr
331 type(
xc_t),
intent(in) :: xc
333 real(real64),
allocatable :: rho(:, :)
337 safe_allocate(this%fxc(1:gr%np, 1:st%d%nspin, 1:st%d%nspin))
338 safe_allocate(rho(1:gr%np_part, 1:st%d%nspin))
340 call xc_get_fxc(xc, gr, namespace, rho, st%d%ispin, this%fxc)
341 safe_deallocate_a(rho)
351 class(
mesh_t),
intent(in) :: mesh
353 type(
xc_t),
intent(in) :: xc
355 real(real64),
allocatable :: rho(:, :)
359 if (this%add_fxc)
then
360 safe_allocate(this%kxc(1:mesh%np, 1:st%d%nspin, 1:st%d%nspin, 1:st%d%nspin))
363 safe_allocate(rho(1:mesh%np, 1:st%d%nspin))
365 call xc_get_kxc(xc, mesh, namespace, rho, st%d%ispin, this%kxc)
366 safe_deallocate_a(rho)
379 safe_deallocate_a(this%kxc)
394 rr = this%add_hartree
407 have =
associated(this%drhs) .or.
associated(this%zrhs)
423 logical pure function sternheimer_have_inhomog(this) result(have)
425 have =
associated(this%dinhomog) .or.
associated(this%zinhomog)
434 nullify(this%dinhomog)
435 nullify(this%zinhomog)
441 integer pure function swap_sigma(sigma)
442 integer,
intent(in) :: sigma
453 character(len=100) function wfs_tag_sigma(namespace, base_name, isigma)
result(str)
454 type(namespace_t),
intent(in) :: namespace
455 character(len=*),
intent(in) :: base_name
456 integer,
intent(in) :: isigma
458 character :: sigma_char
468 write(message(1),
'(a,i2)')
"Illegal integer isigma passed to wfs_tag_sigma: ", isigma
469 call messages_fatal(1, namespace=namespace)
472 str = trim(base_name) // sigma_char
481 type(namespace_t),
intent(in) :: namespace
482 character(len=*),
intent(in) :: old_prefix
483 character(len=*),
intent(in) :: new_prefix
487 call messages_obsolete_variable(namespace, trim(old_prefix)//
'Preorthogonalization', trim(new_prefix)//
'Preorthogonalization')
488 call messages_obsolete_variable(namespace, trim(old_prefix)//
'HamiltonianVariation', trim(new_prefix)//
'HamiltonianVariation')
490 call linear_solver_obsolete_variables(namespace, old_prefix, new_prefix)
491 call scf_tol_obsolete_variables(namespace, old_prefix, new_prefix)
499 class(mesh_t),
intent(in) :: mesh
500 integer,
intent(in) :: nspin
501 integer,
intent(in) :: nsigma
502 complex(real64),
intent(in) :: lr_rho(:,:)
503 complex(real64),
intent(inout) :: hvar(:,:,:)
504 integer,
optional,
intent(in) :: idir
506 real(real64),
allocatable :: lambda_dot_r(:)
507 complex(real64),
allocatable :: s_lr_rho(:), vp_dip_self_ener(:), vp_bilinear_el_pt(:)
508 integer :: nm, is, ii
509 complex(real64) :: first_moments
512 call profiling_in(
'CALC_HVAR_PHOTONS')
514 nm = this%pt_modes%nmodes
517 safe_allocate(s_lr_rho(1:mesh%np))
518 safe_allocate(lambda_dot_r(1:mesh%np))
519 safe_allocate(vp_dip_self_ener(1:mesh%np))
520 safe_allocate(vp_bilinear_el_pt(1:mesh%np))
525 s_lr_rho = s_lr_rho + lr_rho(:, is)
529 vp_dip_self_ener = m_zero
530 vp_bilinear_el_pt = m_zero
532 lambda_dot_r(1:mesh%np) = this%pt_modes%lambda(ii)*this%pt_modes%pol_dipole(1:mesh%np, ii)
533 first_moments = zmf_integrate(mesh, lambda_dot_r(1:mesh%np)*s_lr_rho(1:mesh%np))
536 this%zphoton_coord_q(ii, idir) = (m_one/(m_two*(this%pt_modes%omega(ii))**2)) * &
537 ((m_one/(this%zomega - cmplx(this%pt_modes%omega(ii),-this%pt_eta, real64))) - &
538 (m_one/(this%zomega + cmplx(this%pt_modes%omega(ii), this%pt_eta, real64)))) * &
539 (-(this%pt_modes%omega(ii))**2)*first_moments
542 vp_bilinear_el_pt = vp_bilinear_el_pt - &
543 this%pt_modes%omega(ii)*lambda_dot_r(1:mesh%np)*this%zphoton_coord_q(ii, idir)
546 vp_dip_self_ener = vp_dip_self_ener + first_moments*lambda_dot_r(1:mesh%np)
549 hvar(1:mesh%np, 1, 1) = hvar(1:mesh%np, 1, 1) + vp_dip_self_ener(1:mesh%np) + vp_bilinear_el_pt(1:mesh%np)
551 safe_deallocate_a(s_lr_rho)
552 safe_deallocate_a(lambda_dot_r)
553 safe_deallocate_a(vp_dip_self_ener)
554 safe_deallocate_a(vp_bilinear_el_pt)
556 if (nsigma == 2) hvar(1:mesh%np, 1:nspin, 2) = conjg(hvar(1:mesh%np, 1:nspin, 1))
558 call profiling_out(
'CALC_HVAR_PHOTONS')
563#include "complex.F90"
564#include "sternheimer_inc.F90"
569#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.
real(real64), parameter, public m_zero
real(real64), parameter, public m_epsilon
real(real64), parameter, public m_one
This module implements the underlying real-space grid.
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 independent_particles
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_not_implemented(feature, 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, mesh, hm, lr, nsigma, hvar, idir)
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 dsternheimer_calc_hvar(this, namespace, mesh, hm, lr, nsigma, hvar, idir)
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)
logical function, public 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 zcalc_hvar(namespace, add_hartree, mesh, hm, lrc_alpha, lr_rho, nsigma, hvar, fxc)
Computes the first-order variation of the Kohn-Sham Hamiltonian.
subroutine, public sternheimer_unset_kxc(this)
subroutine, public sternheimer_init(this, namespace, space, gr, st, hm, xc, mc, wfs_are_cplx, set_ham_var, set_occ_response, set_last_occ_response, occ_response_by_sternheimer)
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.
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 dcalc_hvar(namespace, add_hartree, mesh, hm, lrc_alpha, lr_rho, nsigma, hvar, fxc)
Computes the first-order variation of the Kohn-Sham Hamiltonian.
subroutine, public dsternheimer_set_inhomog(this, inhomog)
logical function, public sternheimer_add_hartree(this)
subroutine, public sternheimer_unset_rhs(this)
type(type_t), public type_float
type(type_t), public type_cmplx
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
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.
subroutine, public xc_get_fxc(xcs, gr, namespace, rho, ispin, fxc, fxc_grad, fxc_grad_spin)
Returns the exchange-correlation kernel.
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.