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))
298 message(1) =
"Using MGGA in Sternheimer calculation."
311 safe_deallocate_a(this%zphoton_coord_q)
317 safe_deallocate_a(this%fxc)
327 type(
grid_t),
intent(in) :: gr
329 type(
xc_t),
intent(in) :: xc
331 real(real64),
allocatable :: rho(:, :)
335 safe_allocate(this%fxc(1:gr%np, 1:st%d%nspin, 1:st%d%nspin))
336 safe_allocate(rho(1:gr%np_part, 1:st%d%nspin))
338 call xc_get_fxc(xc, gr, namespace, rho, st%d%ispin, this%fxc)
339 safe_deallocate_a(rho)
350 class(
mesh_t),
intent(in) :: mesh
352 type(
xc_t),
intent(in) :: xc
354 real(real64),
allocatable :: rho(:, :)
358 if (this%add_fxc)
then
359 safe_allocate(this%kxc(1:mesh%np, 1:st%d%nspin, 1:st%d%nspin, 1:st%d%nspin))
362 safe_allocate(rho(1:mesh%np, 1:st%d%nspin))
364 call xc_get_kxc(xc, mesh, namespace, rho, st%d%ispin, this%kxc)
365 safe_deallocate_a(rho)
378 safe_deallocate_a(this%kxc)
393 rr = this%add_hartree
406 have =
associated(this%drhs) .or.
associated(this%zrhs)
422 logical pure function sternheimer_have_inhomog(this) result(have)
424 have =
associated(this%dinhomog) .or.
associated(this%zinhomog)
433 nullify(this%dinhomog)
434 nullify(this%zinhomog)
441 integer,
intent(in) :: sigma
452 character(len=100) function wfs_tag_sigma(namespace, base_name, isigma)
result(str)
453 type(namespace_t),
intent(in) :: namespace
454 character(len=*),
intent(in) :: base_name
455 integer,
intent(in) :: isigma
457 character :: sigma_char
467 write(message(1),
'(a,i2)')
"Illegal integer isigma passed to wfs_tag_sigma: ", isigma
468 call messages_fatal(1, namespace=namespace)
471 str = trim(base_name) // sigma_char
480 type(namespace_t),
intent(in) :: namespace
481 character(len=*),
intent(in) :: old_prefix
482 character(len=*),
intent(in) :: new_prefix
486 call messages_obsolete_variable(namespace, trim(old_prefix)//
'Preorthogonalization', trim(new_prefix)//
'Preorthogonalization')
487 call messages_obsolete_variable(namespace, trim(old_prefix)//
'HamiltonianVariation', trim(new_prefix)//
'HamiltonianVariation')
489 call linear_solver_obsolete_variables(namespace, old_prefix, new_prefix)
490 call scf_tol_obsolete_variables(namespace, old_prefix, new_prefix)
498 class(mesh_t),
intent(in) :: mesh
499 integer,
intent(in) :: nspin
500 integer,
intent(in) :: nsigma
501 complex(real64),
intent(in) :: lr_rho(:,:)
502 complex(real64),
intent(inout) :: hvar(:,:,:)
503 integer,
optional,
intent(in) :: idir
505 real(real64),
allocatable :: lambda_dot_r(:)
506 complex(real64),
allocatable :: s_lr_rho(:), vp_dip_self_ener(:), vp_bilinear_el_pt(:)
507 integer :: nm, is, ii
508 complex(real64) :: first_moments
511 call profiling_in(
'CALC_HVAR_PHOTONS')
513 nm = this%pt_modes%nmodes
516 safe_allocate(s_lr_rho(1:mesh%np))
517 safe_allocate(lambda_dot_r(1:mesh%np))
518 safe_allocate(vp_dip_self_ener(1:mesh%np))
519 safe_allocate(vp_bilinear_el_pt(1:mesh%np))
524 s_lr_rho = s_lr_rho + lr_rho(:, is)
528 vp_dip_self_ener = m_zero
529 vp_bilinear_el_pt = m_zero
531 lambda_dot_r(1:mesh%np) = this%pt_modes%lambda(ii)*this%pt_modes%pol_dipole(1:mesh%np, ii)
532 first_moments = zmf_integrate(mesh, lambda_dot_r(1:mesh%np)*s_lr_rho(1:mesh%np))
535 this%zphoton_coord_q(ii, idir) = (m_one/(m_two*(this%pt_modes%omega(ii))**2)) * &
536 ((m_one/(this%zomega - cmplx(this%pt_modes%omega(ii),-this%pt_eta, real64))) - &
537 (m_one/(this%zomega + cmplx(this%pt_modes%omega(ii), this%pt_eta, real64)))) * &
538 (-(this%pt_modes%omega(ii))**2)*first_moments
541 vp_bilinear_el_pt = vp_bilinear_el_pt - &
542 this%pt_modes%omega(ii)*lambda_dot_r(1:mesh%np)*this%zphoton_coord_q(ii, idir)
545 vp_dip_self_ener = vp_dip_self_ener + first_moments*lambda_dot_r(1:mesh%np)
548 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)
550 safe_deallocate_a(s_lr_rho)
551 safe_deallocate_a(lambda_dot_r)
552 safe_deallocate_a(vp_dip_self_ener)
553 safe_deallocate_a(vp_bilinear_el_pt)
555 if (nsigma == 2) hvar(1:mesh%np, 1:nspin, 2) = conjg(hvar(1:mesh%np, 1:nspin, 1))
557 call profiling_out(
'CALC_HVAR_PHOTONS')
562#include "complex.F90"
563#include "sternheimer_inc.F90"
568#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 sternheimer_build_fxc(this, namespace, gr, st, xc)
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, 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_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.
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.