29 use,
intrinsic :: iso_fortran_env
58 subroutine vdw_run(system, from_scratch)
59 class(*),
intent(inout) :: system
60 logical,
intent(in) :: from_scratch
66 message(1) =
"CalculationMode = vdw not implemented for multi-system calculations"
77 type(electrons_t),
intent(inout) :: sys
78 logical,
intent(in) :: fromScratch
80 type(lr_t) :: lr(sys%space%dim, 1)
81 type(sternheimer_t) :: sh
83 integer :: dir, i, iunit, gauss_start, ndir
84 complex(real64) :: omega
85 real(real64) :: domega, pol, c3, c6, cat
88 real(real64),
allocatable :: gaus_leg_points(:), gaus_leg_weights(:)
89 real(real64),
parameter :: omega0 = 0.3_real64
91 type(restart_t) :: restart_dump
95 if (sys%hm%pcm%run_pcm)
then
99 if (sys%space%is_periodic())
then
103 if (sys%kpoints%use_symmetries)
call messages_experimental(
"KPoints symmetries with CalculationMode = vdw", &
104 namespace=sys%namespace)
108 call sternheimer_init(sh, sys%namespace, sys%space, sys%gr, sys%st, sys%hm, sys%ks%xc, sys%mc, wfs_are_cplx = .
true.)
112 write(iunit,
'(a,i3)')
'# npoints = ', gaus_leg_n
113 write(iunit,
'(a1,a12,2a20)')
'#',
'omega',
'domega',
'pol'
117 do i = gauss_start, gaus_leg_n
118 omega =
m_zi*omega0*(
m_one - gaus_leg_points(i))/(
m_one + gaus_leg_points(i))
119 domega = gaus_leg_weights(i) * omega0 * (
m_two)/(
m_one + gaus_leg_points(i))**2
123 iunit =
io_open(
vdw_dir//
'vdw_c6', sys%namespace, action=
'write', position=
'append')
124 write(iunit,
'(3es20.12)') aimag(omega), domega, pol
134 iunit =
io_open(
vdw_dir//
'vdw_c6', sys%namespace, action=
'write', position=
'append')
136 write(iunit,
'(a,es20.12)')
"C_3 [a.u. ] = ", c3
137 write(iunit,
'(a,es20.12)')
"C_6 [a.u. ] = ", c6
138 write(iunit,
'(a,es20.12)')
"C_AT [a.u. ] = ", cat
141 write(iunit,
'(3a,es20.12)')
"C_3 [", &
144 write(iunit,
'(3a,es20.12)')
"C_6 [", &
147 write(iunit,
'(3a,es20.12)')
"C_AT [", &
162 integer :: equiv_axes
178 call parse_variable(sys%namespace,
'TDPolarizationEquivAxes', 0, equiv_axes)
180 select case (equiv_axes)
184 ndir = min(2, sys%space%dim)
186 ndir = min(3, sys%space%dim)
195 integer :: ierr, iunit, ii
196 logical :: file_exists
197 character(len=80) :: dirname
198 real(real64) :: iomega, domega, pol
200 type(
restart_t) :: restart_load, gs_restart
205 gaus_leg_n = gaus_leg_n + 1
208 safe_allocate(gaus_leg_points(1:gaus_leg_n))
209 safe_allocate(gaus_leg_weights(1:gaus_leg_n))
216 gaus_leg_points(gaus_leg_n) = 0.99999_real64
217 gaus_leg_weights(gaus_leg_n) =
m_zero
221 inquire(file=
vdw_dir//
'vdw_c6', exist=file_exists)
222 if (.not. fromscratch .and. file_exists)
then
224 read(iunit,
'(a12,i3)', iostat=ierr) dirname, ii
225 if (ii /= gaus_leg_n)
then
226 message(1) =
"Invalid restart of van der Waals calculation."
227 message(2) =
"The number of points in the Gauss-Legendre integration changed."
228 write(
message(3),
'(i3,a,i3,a)') gaus_leg_n,
" (input) != ", ii,
"(restart)"
233 read(iunit, *, iostat=ierr) iomega, domega, pol
235 gauss_start = gauss_start + 1
250 message(1) =
"Previous gs calculation required."
255 message(1) =
'Info: Setting up Hamiltonian for linear response.'
257 call v_ks_h_setup(sys%namespace, sys%space, sys%gr, sys%ions, sys%ext_partners, sys%st, sys%ks, sys%hm)
265 if (.not. fromscratch)
then
269 write(dirname,
'(a,i1,a)')
"wfs_", dir,
"_1_1"
272 call states_elec_load(restart_load, sys%namespace, sys%space, sys%st, sys%gr, sys%kpoints, ierr, lr=lr(dir,1))
275 message(1) =
"Unable to read response wavefunctions from '"//trim(dirname)//
"'."
299 safe_deallocate_a(gaus_leg_points)
300 safe_deallocate_a(gaus_leg_weights)
313 real(real64) function get_pol(omega)
314 complex(real64),
intent(in) :: omega
316 complex(real64) :: alpha(1:sys%space%dim, 1:sys%space%dim)
323 write(
message(1),
'(3a,f7.3)')
'Info: Calculating response for the ',
index2axis(dir), &
327 call pert%setup_dir(dir)
328 call zsternheimer_solve(sh, sys%namespace, sys%space, sys%gr, sys%kpoints, sys%st, sys%hm, sys%mc, &
329 lr(dir, :), 1, omega, pert, restart_dump,
em_rho_tag(real(omega, real64) ,dir),
em_wfs_tag(dir,1))
333 alpha(:,:), ndir = ndir)
337 get_pol = get_pol + real(alpha(dir, dir), real64)
339 do dir = ndir+1, sys%space%dim
340 get_pol = get_pol + real(alpha(ndir, ndir), real64)
343 get_pol = get_pol / real(sys%space%dim, real64)
345 safe_deallocate_p(pert)
subroutine init_(fromscratch)
character(len=100) function, public em_wfs_tag(idir, ifactor, idir2, ipert)
character(len=100) function, public em_rho_tag(freq, dir, dir2, ipert)
subroutine, public zcalc_polarizability_finite(namespace, space, gr, st, hm, lr, nsigma, pert, zpol, doalldirs, ndir)
alpha_ij(w) = - sum(m occ) [<psi_m(0)|r_i|psi_mj(1)(w)> + <psi_mj(1)(-w)|r_i|psi_m(0)>] minus sign is...
subroutine, public gauss_legendre_points(n, points, weights)
real(real64), parameter, public m_two
real(real64), parameter, public m_zero
real(real64), parameter, public m_pi
some mathematical constants
complex(real64), parameter, public m_zi
real(real64), parameter, public m_one
real(real64), parameter, public m_three
character(len= *), parameter, public vdw_dir
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)
subroutine, public lr_allocate(lr, st, mesh, allocate_rho)
subroutine, public lr_init(lr)
subroutine, public lr_dealloc(lr)
This module defines the meshes, which are used in Octopus.
subroutine, public messages_not_implemented(feature, namespace)
subroutine, public messages_warning(no_lines, all_nodes, namespace)
subroutine, public messages_obsolete_variable(namespace, name, rep)
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)
logical function mpi_grp_is_root(grp)
Is the current MPI process of grpcomm, root.
type(mpi_grp_t), public mpi_world
This module implements the basic mulsisystem class, a container system for other systems.
integer, parameter, public restart_gs
subroutine, public restart_init(restart, namespace, data_type, type, mc, ierr, mesh, dir, exact)
Initializes a restart object.
integer, parameter, public restart_type_dump
subroutine, public restart_open_dir(restart, dirname, ierr)
Change the restart directory to dirname, where "dirname" is a subdirectory of the base restart direct...
integer, parameter, public restart_type_load
integer, parameter, public restart_vdw
subroutine, public restart_end(restart)
subroutine, public restart_close_dir(restart)
Change back to the base directory. To be called after restart_open_dir.
This module handles reading and writing restart information for the states_elec_t.
subroutine, public states_elec_look_and_load(restart, namespace, space, st, mesh, kpoints, is_complex, packed)
subroutine, public states_elec_load(restart, namespace, space, st, mesh, kpoints, ierr, iter, lr, lowest_missing, label, verbose, skip)
returns in ierr: <0 => Fatal error, or nothing read =0 => read all wavefunctions >0 => could only rea...
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_end(this)
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
character(len=20) pure function, public units_abbrev(this)
This module defines the unit system, used for input and output.
type(unit_system_t), public units_out
This module is intended to contain simple general-purpose utility functions and procedures.
character pure function, public index2axis(idir)
subroutine, public v_ks_h_setup(namespace, space, gr, ions, ext_partners, st, ks, hm, calc_eigenval, calc_current)
subroutine vdw_run_legacy(sys, fromScratch)
subroutine, public vdw_run(system, from_scratch)
Class describing the electron system.
Container class for lists of system_oct_m::system_t.
real(real64) function get_pol(omega)