26 use,
intrinsic :: iso_fortran_env
78 type(states_elec_t),
pointer :: st
80 type(states_pair_t),
allocatable :: pair(:)
81 real(real64),
allocatable :: weight(:)
111 type(excited_states_t),
intent(inout) :: excited_state
112 type(states_elec_t),
target,
intent(in) :: ground_state
113 character(len=*),
intent(in) :: filename
114 type(namespace_t),
intent(in) :: namespace
116 integer :: iunit, nst, ispin, nik, &
117 n_possible_pairs, ipair, jpair, ist, ios, nspin, trash
118 integer,
allocatable :: n_filled(:), n_partially_filled(:), n_half_filled(:), n_empty(:), &
119 filled(:, :), partially_filled(:, :), half_filled(:, :)
126 nst = ground_state%nst
127 nik = ground_state%nik
128 ispin = ground_state%d%ispin
129 nspin = ground_state%d%nspin
131 if (nik > 2 .or. ( (nik == 2) .and. (ispin /=
spin_polarized)))
then
132 message(1) =
'Cannot calculate projections onto excited states for periodic systems.'
136 safe_allocate( n_filled(1:nspin))
137 safe_allocate( n_empty(1:nspin))
138 safe_allocate(n_partially_filled(1:nspin))
139 safe_allocate( n_half_filled(1:nspin))
140 safe_allocate( filled(1:nst, 1:nspin))
141 safe_allocate(partially_filled(1:nst, 1:nspin))
142 safe_allocate( half_filled(1:nst, 1:nspin))
146 call occupied_states(ground_state, namespace, 1, n_filled(1), n_partially_filled(1), n_half_filled(1), &
147 filled(:, 1), partially_filled(:, 1), half_filled(:, 1))
148 if (n_partially_filled(1) > 0)
then
149 message(1) =
'Cannot calculate projections onto excited states if there are partially filled orbitals.'
155 if ((n_half_filled(1) /= 0 .and. n_filled(1) > 0) .or. (n_half_filled(1) > 1))
then
156 message(1) =
'Cannot construct excited states from ground states that contain half-filled'
157 message(2) =
'orbitals - unless they are just one-particle states with only one half-filled'
158 message(3) =
'orbital and no doubly occupied ones. Try using the spin-unrestricted mode.'
161 if (n_half_filled(1) == 0)
then
162 n_empty(1) = nst - n_filled(1)
163 n_possible_pairs = n_filled(1) * n_empty(1)
166 n_possible_pairs = n_empty(1)
170 call occupied_states(ground_state, namespace, 1, n_filled(1), n_partially_filled(1), n_half_filled(1), &
171 filled(:, 1), partially_filled(:, 1), half_filled(:, 1))
172 call occupied_states(ground_state, namespace, 2, n_filled(2), n_partially_filled(2), n_half_filled(2), &
173 filled(:, 2), partially_filled(:, 2), half_filled(:, 2))
174 if (n_partially_filled(1) * n_partially_filled(2) > 0)
then
175 message(1) =
'Cannot calculate projections onto excited states if there are partially filled orbitals.'
178 n_empty(1) = nst - n_filled(1)
179 n_empty(2) = nst - n_filled(2)
180 n_possible_pairs = n_filled(1) * n_empty(1) + n_filled(2) * n_empty(2)
183 call occupied_states(ground_state, namespace, 1, n_filled(1), n_partially_filled(1), n_half_filled(1), &
184 filled(:, 1), partially_filled(:, 1), half_filled(:, 1))
185 if (n_partially_filled(1) > 0)
then
186 message(1) =
'Cannot calculate projections onto excited states if there are partially filled orbitals.'
189 n_empty(1) = nst - n_filled(1)
190 n_possible_pairs = n_filled(1) * n_empty(1)
193 iunit =
io_open(trim(filename), namespace, action =
'read', status =
'old', die = .
true.)
199 read(iunit, *,
end = 101)
201 read(iunit, *, iostat = ios) trash, trash, trash, dump
203 message(1) =
'Error attempting to read the electron-hole pairs in file "'//trim(filename)//
'"'
210 message(1) =
'File "'//trim(filename)//
'" is empty?'
212 elseif (ipair > n_possible_pairs)
then
213 message(1) =
'File "'//trim(filename)//
'" contains too many electron-hole pairs.'
217 excited_state%n_pairs = ipair
218 safe_allocate(excited_state%pair(1:ipair))
219 safe_allocate(excited_state%weight(1:ipair))
223 do ipair = 1, excited_state%n_pairs
224 read(iunit, *) excited_state%pair(ipair)%i, excited_state%pair(ipair)%a, &
225 excited_state%pair(ipair)%kk, excited_state%weight(ipair)
226 if (((ispin ==
unpolarized) .or. (ispin ==
spinors)) .and. (excited_state%pair(ipair)%kk /= 1))
then
227 message(1) =
'Error reading excited state in file "'//trim(filename)//
'":'
228 message(2) =
'Cannot treat a electron-hole pair for "down" spin when not working in spin-polarized mode.'
235 do ist = 1, n_filled(excited_state%pair(ipair)%kk)
236 ok = excited_state%pair(ipair)%i == filled(ist, excited_state%pair(ipair)%kk)
241 if (ispin ==
unpolarized .and. (n_half_filled(1) == 1))
then
242 ok = excited_state%pair(ipair)%i == half_filled(1, excited_state%pair(ipair)%kk)
246 write(
message(1),
'(a6,i3,a1,i3,a8,i1,a)')
'Pair (', excited_state%pair(ipair)%i,
',', &
247 excited_state%pair(ipair)%a,
'; k =', excited_state%pair(ipair)%kk,
') is not valid.'
253 do ist = 1, n_filled(excited_state%pair(ipair)%kk)
254 ok = .not. (excited_state%pair(ipair)%a == filled(ist, excited_state%pair(ipair)%kk))
257 if (ispin ==
unpolarized .and. (n_half_filled(1) == 1))
then
258 ok = .not. (excited_state%pair(ipair)%i == half_filled(1, excited_state%pair(ipair)%kk))
260 ok = .not. (excited_state%pair(ipair)%a > nst)
262 write(
message(1),
'(a6,i3,a1,i3,a8,i1,a)')
'Pair (', excited_state%pair(ipair)%i,
',', &
263 excited_state%pair(ipair)%a,
'; k =', excited_state%pair(ipair)%kk,
') is not valid.'
268 do jpair = 1, ipair - 1
269 ok = .not.
pair_is_eq(excited_state%pair(ipair), excited_state%pair(jpair))
271 write(
message(1),
'(a6,i3,a1,i3,a8,i1,a)')
'Pair (', excited_state%pair(ipair)%i,
',', &
272 excited_state%pair(ipair)%a,
'; k =', excited_state%pair(ipair)%kk,
') is repeated in the file.'
280 excited_state%st => ground_state
283 dump = sum(excited_state%weight(1:excited_state%n_pairs)**2)
284 if (.not. abs(dump -
m_one) < 1.0e-5_real64)
then
285 excited_state%weight(1:excited_state%n_pairs) = excited_state%weight(1:excited_state%n_pairs) /
sqrt(dump)
286 message(1) =
'The excited state in file "'//trim(filename)//
'" was not normalized.'
292 safe_deallocate_a(n_filled)
293 safe_deallocate_a(n_partially_filled)
294 safe_deallocate_a(n_half_filled)
295 safe_deallocate_a(n_empty)
296 safe_deallocate_a(filled)
297 safe_deallocate_a(partially_filled)
298 safe_deallocate_a(half_filled)
310 nullify(excited_state%st)
311 safe_deallocate_a(excited_state%pair)
312 safe_deallocate_a(excited_state%weight)
321 character(len=*),
intent(in) :: dirname
322 type(namespace_t),
intent(in) :: namespace
324 integer :: iunit, ipair
328 iunit = io_open(trim(dirname)//
'/excitations', namespace, action =
'write', status =
'replace')
329 do ipair = 1, excited_state%n_pairs
330 write(iunit,
'(3i5,es20.12)') excited_state%pair(ipair)%i, excited_state%pair(ipair)%a, &
331 excited_state%pair(ipair)%kk, excited_state%weight(ipair)
340 logical function pair_is_eq(pair1, pair2)
result(res)
343 res = (pair1%i == pair2%i) .and. (pair1%a == pair2%a) .and. (pair1%kk == pair2%kk)
348#include "excited_states_inc.F90"
351#include "complex.F90"
352#include "excited_states_inc.F90"
double sqrt(double __x) __attribute__((__nothrow__
integer, parameter, public unpolarized
Parameters...
integer, parameter, public spinors
integer, parameter, public spin_polarized
real(real64) function dstates_elec_mpdotp_x(namespace, mesh, excited_state, st, mat)
Returns the dot product of two many-body states; the first one is an "excited_state".
subroutine, public zstates_elec_matrix_swap(mat, pair)
The matrix mat should contain the dot products between two states. One of them (the one operating on ...
complex(real64) function zstates_elec_mpdotp_g(namespace, mesh, st1, st2, mat)
Returns the dot product of two many-body states st1 and st2.
subroutine, public excited_states_output(excited_state, dirname, namespace)
real(real64) function dstates_elec_mpdotp_g(namespace, mesh, st1, st2, mat)
Returns the dot product of two many-body states st1 and st2.
logical function pair_is_eq(pair1, pair2)
complex(real64) function zstates_elec_mpmatrixelement_g(namespace, mesh, st1, st2, opst2)
Returns <st1 | O | st2>, where both st1 and st2 are Slater determinants represented by states_elec_t ...
subroutine, public excited_states_kill(excited_state)
Kills an excited_state structure.
complex(real64) function zstates_elec_mpdotp_x(namespace, mesh, excited_state, st, mat)
Returns the dot product of two many-body states; the first one is an "excited_state".
subroutine, public dstates_elec_matrix_swap(mat, pair)
The matrix mat should contain the dot products between two states. One of them (the one operating on ...
real(real64) function dstates_elec_mpmatrixelement_g(namespace, mesh, st1, st2, opst2)
Returns <st1 | O | st2>, where both st1 and st2 are Slater determinants represented by states_elec_t ...
subroutine, public excited_states_init(excited_state, ground_state, filename, namespace)
Fills in an excited_state structure, by reading a file called "filename". This file describes the "pr...
real(real64), parameter, public m_one
subroutine, public io_close(iunit, grp)
subroutine, public io_skip_header(iunit)
integer function, public io_open(file, namespace, action, status, form, position, die, recl, grp)
This module defines the meshes, which are used in Octopus.
subroutine, public messages_warning(no_lines, 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 occupied_states(st, namespace, ik, n_filled, n_partially_filled, n_half_filled, filled, partially_filled, half_filled)
return information about occupied orbitals in many-body state