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))
299 message(1) =
"Using MGGA in Sternheimer calculation."
312 safe_deallocate_a(this%zphoton_coord_q)
318 safe_deallocate_a(this%fxc)
328 class(
mesh_t),
intent(in) :: mesh
330 type(
xc_t),
intent(in) :: xc
332 real(real64),
allocatable :: rho(:, :)
336 safe_allocate(this%fxc(1:mesh%np, 1:st%d%nspin, 1:st%d%nspin))
339 safe_allocate(rho(1:mesh%np, 1:st%d%nspin))
341 call xc_get_fxc(xc, mesh, namespace, rho, st%d%ispin, this%fxc)
342 safe_deallocate_a(rho)
353 class(
mesh_t),
intent(in) :: mesh
355 type(
xc_t),
intent(in) :: xc
357 real(real64),
allocatable :: rho(:, :)
361 if (this%add_fxc)
then
362 safe_allocate(this%kxc(1:mesh%np, 1:st%d%nspin, 1:st%d%nspin, 1:st%d%nspin))
365 safe_allocate(rho(1:mesh%np, 1:st%d%nspin))
367 call xc_get_kxc(xc, mesh, namespace, rho, st%d%ispin, this%kxc)
368 safe_deallocate_a(rho)
381 safe_deallocate_a(this%kxc)
396 rr = this%add_hartree
409 have =
associated(this%drhs) .or.
associated(this%zrhs)
425 logical pure function sternheimer_have_inhomog(this) result(have)
427 have =
associated(this%dinhomog) .or.
associated(this%zinhomog)
436 nullify(this%dinhomog)
437 nullify(this%zinhomog)
444 integer,
intent(in) :: sigma
455 character(len=100) function wfs_tag_sigma(namespace, base_name, isigma)
result(str)
456 type(namespace_t),
intent(in) :: namespace
457 character(len=*),
intent(in) :: base_name
458 integer,
intent(in) :: isigma
460 character :: sigma_char
470 write(message(1),
'(a,i2)')
"Illegal integer isigma passed to wfs_tag_sigma: ", isigma
471 call messages_fatal(1, namespace=namespace)
474 str = trim(base_name) // sigma_char
483 type(namespace_t),
intent(in) :: namespace
484 character(len=*),
intent(in) :: old_prefix
485 character(len=*),
intent(in) :: new_prefix
489 call messages_obsolete_variable(namespace, trim(old_prefix)//
'Preorthogonalization', trim(new_prefix)//
'Preorthogonalization')
490 call messages_obsolete_variable(namespace, trim(old_prefix)//
'HamiltonianVariation', trim(new_prefix)//
'HamiltonianVariation')
492 call linear_solver_obsolete_variables(namespace, old_prefix, new_prefix)
493 call scf_tol_obsolete_variables(namespace, old_prefix, new_prefix)
501 class(mesh_t),
intent(in) :: mesh
502 integer,
intent(in) :: nspin
503 integer,
intent(in) :: nsigma
504 complex(real64),
intent(in) :: lr_rho(:,:)
505 complex(real64),
intent(inout) :: hvar(:,:,:)
506 integer,
intent(in) :: idir
508 real(real64),
allocatable :: lambda_dot_r(:)
509 complex(real64),
allocatable :: s_lr_rho(:), vp_dip_self_ener(:), vp_bilinear_el_pt(:)
510 integer :: nm, is, ii
511 complex(real64) :: first_moments
514 call profiling_in(
'CALC_HVAR_PHOTONS')
516 nm = this%pt_modes%nmodes
519 safe_allocate(s_lr_rho(1:mesh%np))
520 safe_allocate(lambda_dot_r(1:mesh%np))
521 safe_allocate(vp_dip_self_ener(1:mesh%np))
522 safe_allocate(vp_bilinear_el_pt(1:mesh%np))
527 s_lr_rho = s_lr_rho + lr_rho(:, is)
531 vp_dip_self_ener = m_zero
532 vp_bilinear_el_pt = m_zero
534 lambda_dot_r(1:mesh%np) = this%pt_modes%lambda(ii)*this%pt_modes%pol_dipole(1:mesh%np, ii)
535 first_moments = zmf_integrate(mesh, lambda_dot_r(1:mesh%np)*s_lr_rho(1:mesh%np))
538 this%zphoton_coord_q(ii, idir) = -m_half * &
539 ((m_one/(this%zomega - cmplx(this%pt_modes%omega(ii),-this%pt_eta, real64))) - &
540 (m_one/(this%zomega + cmplx(this%pt_modes%omega(ii), this%pt_eta, real64)))) *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 hvar(1:mesh%np, ii, 1) = hvar(1:mesh%np, 1, 1)
555 safe_deallocate_a(s_lr_rho)
556 safe_deallocate_a(lambda_dot_r)
557 safe_deallocate_a(vp_dip_self_ener)
558 safe_deallocate_a(vp_bilinear_el_pt)
560 if (nsigma == 2) hvar(1:mesh%np, 1:nspin, 2) = conjg(hvar(1:mesh%np, 1:nspin, 1))
562 call profiling_out(
'CALC_HVAR_PHOTONS')
567#include "complex.F90"
568#include "sternheimer_inc.F90"
573#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_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 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), 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
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.