32 use,
intrinsic :: iso_fortran_env
99 character(len=*),
public,
parameter :: EM_RESP_PHOTONS_DIR =
"em_resp_photons/"
103 type(linear_solver_t) :: solver
105 type(scf_tol_t) :: scf_tol
106 real(real64) :: lrc_alpha
107 real(real64),
allocatable :: fxc(:,:,:)
108 real(real64),
allocatable :: kxc(:,:,:,:)
109 real(real64),
pointer,
contiguous :: drhs(:, :, :, :) => null()
110 complex(real64),
pointer,
contiguous :: zrhs(:, :, :, :) => null()
111 real(real64),
pointer,
contiguous :: dinhomog(:, :, :, :, :) => null()
112 complex(real64),
pointer,
contiguous :: zinhomog(:, :, :, :, :) => null()
114 logical :: add_hartree
116 logical :: occ_response
117 logical :: last_occ_response
118 logical :: occ_response_by_sternheimer
119 logical :: preorthogonalization
120 logical,
public :: has_photons
121 real(real64) :: domega
122 complex(real64) :: zomega
123 real(real64),
allocatable,
public :: dphoton_coord_q(:, :)
124 complex(real64),
allocatable,
public :: zphoton_coord_q(:, :)
125 real(real64) :: pt_eta
126 type(photon_mode_t) :: pt_modes
133 subroutine sternheimer_init(this, namespace, space, gr, st, hm, xc, mc, wfs_are_cplx, set_ham_var, set_occ_response, &
134 set_last_occ_response, occ_response_by_sternheimer)
135 type(sternheimer_t),
intent(out) :: this
136 type(namespace_t),
intent(in) :: namespace
137 class(space_t),
intent(in) :: space
138 type(grid_t),
intent(inout) :: gr
139 type(states_elec_t),
intent(in) :: st
140 type(hamiltonian_elec_t),
intent(in) :: hm
141 type(xc_t),
intent(in) :: xc
142 type(multicomm_t),
intent(in) :: mc
143 logical,
intent(in) :: wfs_are_cplx
144 integer,
optional,
intent(in) :: set_ham_var
145 logical,
optional,
intent(in) :: set_occ_response
146 logical,
optional,
intent(in) :: set_last_occ_response
147 logical,
optional,
intent(in) :: occ_response_by_sternheimer
149 integer :: ham_var, iunit
150 logical :: default_preorthog
159 write(
message(1),
'(a,f12.6)')
'Partial occupation at the Fermi level: ', st%smear%ef_occ
160 message(2) =
'Semiconducting smearing cannot be used for Sternheimer in this situation.'
164 if (wfs_are_cplx)
then
165 call mix_init(this%mixer, namespace, space, gr%der, gr%np, st%d%nspin, func_type_=
type_cmplx)
167 call mix_init(this%mixer, namespace, space, gr%der, gr%np, st%d%nspin, func_type_=
type_float)
170 if (
present(set_occ_response))
then
171 this%occ_response = set_occ_response
173 this%occ_response = .false.
176 this%occ_response_by_sternheimer =
optional_default(occ_response_by_sternheimer, .false.)
190 .and. .not. this%occ_response
191 call parse_variable(namespace,
'Preorthogonalization', default_preorthog, this%preorthogonalization)
216 if (
present(set_ham_var))
then
217 ham_var = set_ham_var
225 this%add_fxc = ((ham_var / 2) == 1)
226 this%add_hartree = (mod(ham_var, 2) == 1)
228 this%add_fxc = .false.
229 this%add_hartree = .false.
232 if (
present(set_last_occ_response))
then
233 this%last_occ_response = set_last_occ_response
235 this%last_occ_response = .false.
238 message(1) =
"Variation of the Hamiltonian in Sternheimer equation: V_ext"
239 if (this%add_hartree)
write(
message(1),
'(2a)') trim(
message(1)),
' + hartree'
240 if (this%add_fxc)
write(
message(1),
'(2a)') trim(
message(1)),
' + fxc'
242 message(2) =
"Solving Sternheimer equation for"
243 if (this%occ_response)
then
244 write(
message(2),
'(2a)') trim(
message(2)),
' full linear response.'
246 write(
message(2),
'(2a)') trim(
message(2)),
' linear response in unoccupied subspace only.'
249 message(3) =
"Sternheimer preorthogonalization:"
250 if (this%preorthogonalization)
then
260 if (ham_var == 0)
then
261 call scf_tol_init(this%scf_tol, namespace, st%qtot, tol_scheme = 0)
266 this%lrc_alpha = xc%kernel_lrc_alpha
272 call parse_variable(namespace,
'EnablePhotons', .false., this%has_photons)
275 if (this%has_photons)
then
280 call io_mkdir(em_resp_photons_dir, namespace)
281 iunit =
io_open(em_resp_photons_dir //
'photon_modes', namespace, action=
'write')
283 safe_allocate(this%zphoton_coord_q(1:this%pt_modes%nmodes, 1:space%dim))
297 if (family_is_mgga(xc%family))
then
298 message(1) =
"Using MGGA in Sternheimer calculation."
311 safe_deallocate_a(this%zphoton_coord_q)
317 safe_deallocate_a(this%fxc)
327 class(
mesh_t),
intent(in) :: mesh
329 type(xc_t),
intent(in) :: xc
331 real(real64),
allocatable :: rho(:, :)
335 safe_allocate(this%fxc(1:mesh%np, 1:st%d%nspin, 1:st%d%nspin))
338 safe_allocate(rho(1:mesh%np, 1:st%d%nspin))
340 call xc_get_fxc(xc, mesh, namespace, rho, st%d%ispin, this%fxc)
341 safe_deallocate_a(rho)
352 class(
mesh_t),
intent(in) :: mesh
354 type(xc_t),
intent(in) :: xc
356 real(real64),
allocatable :: rho(:, :)
360 if (this%add_fxc)
then
361 safe_allocate(this%kxc(1:mesh%np, 1:st%d%nspin, 1:st%d%nspin, 1:st%d%nspin))
364 safe_allocate(rho(1:mesh%np, 1:st%d%nspin))
366 call xc_get_kxc(xc, mesh, namespace, rho, st%d%ispin, this%kxc)
367 safe_deallocate_a(rho)
380 safe_deallocate_a(this%kxc)
395 rr = this%add_hartree
408 have =
associated(this%drhs) .or.
associated(this%zrhs)
424 logical pure function sternheimer_have_inhomog(this) result(have)
426 have =
associated(this%dinhomog) .or.
associated(this%zinhomog)
435 nullify(this%dinhomog)
436 nullify(this%zinhomog)
443 integer,
intent(in) :: sigma
454 character(len=100) function wfs_tag_sigma(namespace, base_name, isigma)
result(str)
455 type(namespace_t),
intent(in) :: namespace
456 character(len=*),
intent(in) :: base_name
457 integer,
intent(in) :: isigma
459 character :: sigma_char
469 write(message(1),
'(a,i2)')
"Illegal integer isigma passed to wfs_tag_sigma: ", isigma
470 call messages_fatal(1, namespace=namespace)
473 str = trim(base_name) // sigma_char
482 type(namespace_t),
intent(in) :: namespace
483 character(len=*),
intent(in) :: old_prefix
484 character(len=*),
intent(in) :: new_prefix
488 call messages_obsolete_variable(namespace, trim(old_prefix)//
'Preorthogonalization', trim(new_prefix)//
'Preorthogonalization')
489 call messages_obsolete_variable(namespace, trim(old_prefix)//
'HamiltonianVariation', trim(new_prefix)//
'HamiltonianVariation')
491 call linear_solver_obsolete_variables(namespace, old_prefix, new_prefix)
492 call scf_tol_obsolete_variables(namespace, old_prefix, new_prefix)
500 class(mesh_t),
intent(in) :: mesh
501 integer,
intent(in) :: nspin
502 integer,
intent(in) :: nsigma
503 complex(real64),
intent(in) :: lr_rho(:,:)
504 complex(real64),
intent(inout) :: hvar(:,:,:)
505 integer,
optional,
intent(in) :: idir
507 real(real64),
allocatable :: lambda_dot_r(:)
508 complex(real64),
allocatable :: s_lr_rho(:), vp_dip_self_ener(:), vp_bilinear_el_pt(:)
509 integer :: nm, is, ii
510 complex(real64) :: first_moments
513 call profiling_in(
'CALC_HVAR_PHOTONS')
515 nm = this%pt_modes%nmodes
518 safe_allocate(s_lr_rho(1:mesh%np))
519 safe_allocate(lambda_dot_r(1:mesh%np))
520 safe_allocate(vp_dip_self_ener(1:mesh%np))
521 safe_allocate(vp_bilinear_el_pt(1:mesh%np))
526 s_lr_rho = s_lr_rho + lr_rho(:, is)
530 vp_dip_self_ener = m_zero
531 vp_bilinear_el_pt = m_zero
533 lambda_dot_r(1:mesh%np) = this%pt_modes%lambda(ii)*this%pt_modes%pol_dipole(1:mesh%np, ii)
534 first_moments = zmf_integrate(mesh, lambda_dot_r(1:mesh%np)*s_lr_rho(1:mesh%np))
537 this%zphoton_coord_q(ii, idir) = (m_one/(m_two*(this%pt_modes%omega(ii))**2)) * &
538 ((m_one/(this%zomega - cmplx(this%pt_modes%omega(ii),-this%pt_eta, real64))) - &
539 (m_one/(this%zomega + cmplx(this%pt_modes%omega(ii), this%pt_eta, real64)))) * &
540 (-(this%pt_modes%omega(ii))**2)*first_moments
543 vp_bilinear_el_pt = vp_bilinear_el_pt - &
544 this%pt_modes%omega(ii)*lambda_dot_r(1:mesh%np)*this%zphoton_coord_q(ii, idir)
547 vp_dip_self_ener = vp_dip_self_ener + first_moments*lambda_dot_r(1:mesh%np)
550 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)
552 safe_deallocate_a(s_lr_rho)
553 safe_deallocate_a(lambda_dot_r)
554 safe_deallocate_a(vp_dip_self_ener)
555 safe_deallocate_a(vp_bilinear_el_pt)
557 if (nsigma == 2) hvar(1:mesh%np, 1:nspin, 2) = conjg(hvar(1:mesh%np, 1:nspin, 1))
559 call profiling_out(
'CALC_HVAR_PHOTONS')
564#include "complex.F90"
565#include "sternheimer_inc.F90"
570#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.
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_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
Describes mesh distribution to nodes.
The states_elec_t class contains all electronic wave functions.