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