32 use,
intrinsic :: iso_fortran_env
98 character(len=*),
public,
parameter :: EM_RESP_PHOTONS_DIR =
"em_resp_photons/"
102 type(linear_solver_t) :: solver
104 type(scf_tol_t) :: scf_tol
105 real(real64) :: lrc_alpha
106 real(real64),
allocatable :: fxc(:,:,:)
107 real(real64),
allocatable :: kxc(:,:,:,:)
108 real(real64),
pointer,
contiguous :: drhs(:, :, :, :) => null()
109 complex(real64),
pointer,
contiguous :: zrhs(:, :, :, :) => null()
110 real(real64),
pointer,
contiguous :: dinhomog(:, :, :, :, :) => null()
111 complex(real64),
pointer,
contiguous :: zinhomog(:, :, :, :, :) => null()
113 logical :: add_hartree
115 logical :: occ_response
116 logical :: last_occ_response
117 logical :: occ_response_by_sternheimer
118 logical :: preorthogonalization
119 logical,
public :: has_photons
120 real(real64) :: domega
121 complex(real64) :: zomega
122 real(real64),
allocatable,
public :: dphoton_coord_q(:, :)
123 complex(real64),
allocatable,
public :: zphoton_coord_q(:, :)
124 real(real64) :: pt_eta
125 type(photon_mode_t) :: pt_modes
132 subroutine sternheimer_init(this, namespace, space, gr, st, hm, xc, mc, wfs_are_cplx, set_ham_var, set_occ_response, &
133 set_last_occ_response, occ_response_by_sternheimer)
134 type(sternheimer_t),
intent(out) :: this
135 type(namespace_t),
intent(in) :: namespace
136 class(space_t),
intent(in) :: space
137 type(grid_t),
intent(inout) :: gr
138 type(states_elec_t),
intent(in) :: st
139 type(hamiltonian_elec_t),
intent(in) :: hm
140 type(xc_t),
intent(in) :: xc
141 type(multicomm_t),
intent(in) :: mc
142 logical,
intent(in) :: wfs_are_cplx
143 integer,
optional,
intent(in) :: set_ham_var
144 logical,
optional,
intent(in) :: set_occ_response
145 logical,
optional,
intent(in) :: set_last_occ_response
146 logical,
optional,
intent(in) :: occ_response_by_sternheimer
148 integer :: ham_var, iunit
149 logical :: default_preorthog
158 write(
message(1),
'(a,f12.6)')
'Partial occupation at the Fermi level: ', st%smear%ef_occ
159 message(2) =
'Semiconducting smearing cannot be used for Sternheimer in this situation.'
163 if (wfs_are_cplx)
then
164 call mix_init(this%mixer, namespace, space, gr%der, gr%np, st%d%nspin, func_type_=
type_cmplx)
166 call mix_init(this%mixer, namespace, space, gr%der, gr%np, st%d%nspin, func_type_=
type_float)
169 if (
present(set_occ_response))
then
170 this%occ_response = set_occ_response
172 this%occ_response = .false.
175 this%occ_response_by_sternheimer =
optional_default(occ_response_by_sternheimer, .false.)
189 .and. .not. this%occ_response
190 call parse_variable(namespace,
'Preorthogonalization', default_preorthog, this%preorthogonalization)
215 if (
present(set_ham_var))
then
216 ham_var = set_ham_var
224 this%add_fxc = ((ham_var / 2) == 1)
225 this%add_hartree = (mod(ham_var, 2) == 1)
227 this%add_fxc = .false.
228 this%add_hartree = .false.
231 if (
present(set_last_occ_response))
then
232 this%last_occ_response = set_last_occ_response
234 this%last_occ_response = .false.
237 message(1) =
"Variation of the Hamiltonian in Sternheimer equation: V_ext"
238 if (this%add_hartree)
write(
message(1),
'(2a)') trim(
message(1)),
' + hartree'
239 if (this%add_fxc)
write(
message(1),
'(2a)') trim(
message(1)),
' + fxc'
241 message(2) =
"Solving Sternheimer equation for"
242 if (this%occ_response)
then
243 write(
message(2),
'(2a)') trim(
message(2)),
' full linear response.'
245 write(
message(2),
'(2a)') trim(
message(2)),
' linear response in unoccupied subspace only.'
248 message(3) =
"Sternheimer preorthogonalization:"
249 if (this%preorthogonalization)
then
259 if (ham_var == 0)
then
260 call scf_tol_init(this%scf_tol, namespace, st%qtot, tol_scheme = 0)
265 this%lrc_alpha = xc%kernel_lrc_alpha
271 call parse_variable(namespace,
'EnablePhotons', .false., this%has_photons)
274 if (this%has_photons)
then
279 call io_mkdir(em_resp_photons_dir, namespace)
280 iunit =
io_open(em_resp_photons_dir //
'photon_modes', namespace, action=
'write')
282 safe_allocate(this%zphoton_coord_q(1:this%pt_modes%nmodes, 1:space%dim))
297 message(1) =
"Using MGGA in Sternheimer calculation."
310 safe_deallocate_a(this%zphoton_coord_q)
316 safe_deallocate_a(this%fxc)
326 class(
mesh_t),
intent(in) :: mesh
328 type(
xc_t),
intent(in) :: xc
330 real(real64),
allocatable :: rho(:, :)
334 safe_allocate(this%fxc(1:mesh%np, 1:st%d%nspin, 1:st%d%nspin))
337 safe_allocate(rho(1:mesh%np, 1:st%d%nspin))
339 call xc_get_fxc(xc, mesh, namespace, rho, st%d%ispin, this%fxc)
340 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)
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 - this%pt_modes%omega(ii) + m_zi*this%pt_eta)) - &
538 (m_one/(this%zomega + this%pt_modes%omega(ii) + m_zi*this%pt_eta))) * &
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.
integer, parameter, public independent_particles
subroutine, public io_mkdir(fname, namespace, parents)
integer function, public io_open(file, namespace, action, status, form, position, die, recl, grp)
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_info(no_lines, iunit, verbose_limit, stress, 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 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, 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)
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 sternheimer_build_fxc(this, namespace, mesh, st, xc)
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)
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_fxc(xcs, mesh, namespace, rho, ispin, fxc, zfxc)
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.
Describes mesh distribution to nodes.
The states_elec_t class contains all electronic wave functions.