root/trunk/src/casida.F90 @ 2905

Revision 2905, 24.7 KB (checked in by acastro, 3 years ago)

I changed the "mag" component of the states data type, by a new "spin"
data type.

The reason is that mag was not providing enough information. It
provided <Sz> and the occupation of the spinor (in a combined way),
but nothing about <Sx> or <Sy>. Now spin is (as it should be) a
three-vector, containing for each state the expectation value of each
one of the spin components.

I had to change a couple of tests, but I was as careful as I could to
make sure that the results did not change; just the presentation.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1!! Copyright (C) 2002-2006 M. Marques, A. Castro, A. Rubio, G. Bertsch
2!!
3!! This program is free software; you can redistribute it and/or modify
4!! it under the terms of the GNU General Public License as published by
5!! the Free Software Foundation; either version 2, or (at your option)
6!! any later version.
7!!
8!! This program is distributed in the hope that it will be useful,
9!! but WITHOUT ANY WARRANTY; without even the implied warranty of
10!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11!! GNU General Public License for more details.
12!!
13!! You should have received a copy of the GNU General Public License
14!! along with this program; if not, write to the Free Software
15!! Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
16!! 02111-1307, USA.
17!!
18!! $Id$
19
20#include "global.h"
21
22module casida_m
23  use datasets_m
24  use excited_states_m
25  use global_m
26  use hamiltonian_m
27  use io_m
28  use lib_adv_alg_m
29  use lib_oct_m
30  use lib_oct_parser_m
31  use math_m
32  use mesh_function_m
33  use mesh_m
34  use messages_m
35  use mpi_m
36  use multicomm_m
37  use output_m
38  use poisson_m
39  use restart_m
40  use states_m
41  use system_m
42  use units_m
43  use xc_m
44 
45  implicit none
46
47  private
48  public :: casida_run
49
50  integer, parameter ::    &
51    CASIDA_EPS_DIFF   = 1, &
52    CASIDA_PETERSILKA = 2, &
53    CASIDA_CASIDA     = 3
54
55  type casida_t
56    integer :: type          ! CASIDA_EPS_DIFF | CASIDA_PETERSILKA | CASIDA_CASIDA
57
58    integer, pointer  :: n_occ(:)       ! number of occupied states
59    integer, pointer  :: n_unocc(:)     ! number of unoccupied states
60    character(len=80) :: wfn_list
61
62    integer           :: n_pairs        ! number of pairs to take into acount
63    type(states_pair_t), pointer :: pair(:)
64
65    FLOAT,   pointer  :: mat(:,:)       ! general purpose matrix
66    FLOAT,   pointer  :: w(:)           ! The excitation energies.
67    FLOAT,   pointer  :: tm(:, :)       ! The transition matrix elements (between the many-particle states)
68    FLOAT,   pointer  :: f(:)           ! The (dipole) strengths
69    FLOAT,   pointer  :: s(:)           ! The diagonal part of the S-matrix
70
71    logical           :: parallel_in_eh_pairs
72    type(mpi_grp_t)   :: mpi_grp
73  end type casida_t
74
75contains
76
77  ! ---------------------------------------------------------
78  subroutine casida_run(sys, h, fromScratch)
79    type(system_t),      intent(inout) :: sys
80    type(hamiltonian_t), intent(inout) :: h
81    logical,             intent(inout) :: fromScratch
82
83    type(casida_t) :: cas
84    integer :: i, ierr, kpoints, dim, nst, n_filled, n_partially_filled, n_half_filled
85    character(len=80) :: trandens
86
87    call push_sub('casida.casida_run')
88
89    message(1) = 'Info: Starting linear response calculation.'
90    call write_info(1)
91
92    call restart_look(trim(tmpdir)//'restart_gs', sys%gr%m, kpoints, dim, nst, ierr)
93    if(ierr.ne.0) then
94      message(1) = 'Could not properly read wave-functions from "'//trim(tmpdir)//'restart_gs".'
95      call write_fatal(1)
96    end if
97
98    if(sys%st%d%ispin == SPINORS) then
99      message(1) = 'Linear response TDDFT ("Casida" mode) is not implemented for spinors-DFT.'
100      call write_fatal(1)
101    end if
102
103    sys%st%nst    = nst
104    sys%st%st_end = nst
105    deallocate(sys%st%eigenval, sys%st%occ)
106
107    call states_allocate_wfns(sys%st, sys%gr%m)
108
109    ALLOCATE(sys%st%eigenval(sys%st%nst, sys%st%d%nik), sys%st%nst*sys%st%d%nik)
110    ALLOCATE(sys%st%occ(sys%st%nst, sys%st%d%nik), sys%st%nst*sys%st%d%nik)
111
112    if(sys%st%d%ispin == SPINORS) then
113      ALLOCATE(sys%st%spin(3, sys%st%nst, sys%st%d%nik), sys%st%nst*sys%st%d%nik*3)
114      sys%st%spin = M_ZERO
115    end if
116    sys%st%eigenval = huge(REAL_PRECISION)
117    sys%st%occ      = M_ZERO
118
119    call restart_read(trim(tmpdir)//'restart_gs', sys%st, sys%gr, sys%geo, ierr)
120    if(ierr.ne.0) then
121      message(1) = 'Could not properly read wave-functions from "'//trim(tmpdir)//'restart_gs".'
122      call write_fatal(1)
123    end if
124
125    ALLOCATE(cas%n_occ(sys%st%d%nspin), sys%st%d%nspin)
126    ALLOCATE(cas%n_unocc(sys%st%d%nspin), sys%st%d%nspin)
127
128    cas%n_occ(:) = 0
129    do i = 1, sys%st%d%nspin
130      call occupied_states(sys%st, i, n_filled, n_partially_filled, n_half_filled)
131      cas%n_occ(i) = n_filled + n_partially_filled + n_half_filled
132      cas%n_unocc(i) = sys%st%nst - cas%n_occ(i)
133    end do
134
135    select case(sys%st%d%ispin)
136    case(UNPOLARIZED)
137      write(message(1),'(a,i4,a)') "Info: Found",cas%n_occ(1)," occupied states."
138      write(message(2),'(a,i4,a)') "Info: Found",cas%n_unocc(1)," unoccupied states."
139      call write_info(2)
140    case(SPIN_POLARIZED)
141      write(message(1),'(a,i4,a)') "Info: Found",cas%n_occ(1)," occupied states with spin up."
142      write(message(2),'(a,i4,a)') "Info: Found",cas%n_unocc(1)," unoccupied states with spin up."
143      write(message(3),'(a,i4,a)') "Info: Found",cas%n_occ(2)," occupied states with spin down."
144      write(message(4),'(a,i4,a)') "Info: Found",cas%n_unocc(2)," unoccupied states with spin down."
145      call write_info(4)
146    end select
147
148
149    ! setup Hamiltonian
150    message(1) = 'Info: Setting up Hamiltonian.'
151    call write_info(1)
152    call system_h_setup(sys, h)
153
154    !%Variable LinearResponseKohnShamStates
155    !%Type string
156    !%Section Linear Response::Casida
157    !%Description
158    !% The calculation of the excitation spectrum of a system in the frequency-domain
159    !% formulation of linear-response time-dependent density functional theory (TDDFT)
160    !% implies the use of a basis set of occupied/unoccupied Kohn-Sham orbitals. This
161    !% basis set should, in principle, include all pairs formed by all occupied states,
162    !% and an infinite number of unoccupied states. In practice, one has to truncate this
163    !% basis set, selecting a number of occupied and unoccupied states that will form the
164    !% pairs. These states are specified with this variable. If there are, say, 10 occupied
165    !% states, and one sets this variable to the value "10-18", this means that occupied
166    !% states from 10 to 15, and unoccupied states from 16 to 18 will be considered.
167    !%
168    !% This variable is a string in list form, i.e. expressions such as "1,2-5,8-15" are
169    !% valid. You should include a non-null number of unoccupied states and a non-null number
170    !% of occupied states.
171    !%End
172    call loct_parse_string(check_inp('LinearResponseKohnShamStates'), "1-1024", cas%wfn_list)
173    write(message(1),'(a,a)') "Info: States that form the basis: ",trim(cas%wfn_list)
174    Call write_info(1)
175
176    !%Variable LinearResponseTransitionDensities
177    !%Type string
178    !%Section Linear Response::Casida
179    !%Description
180    !% Specifies which transition densities are to be calculated and written down. The
181    !% transition density for the many-body state n will be written to a file called
182    !% linear/rho0n.
183    !%
184    !% By default, no transition density is calculated.
185    !%
186    !% This variable is a string in list form, i.e. expressions such as "1,2-5,8-15" are
187    !% valid.
188    !%End
189    call loct_parse_string(check_inp('LinearResponseTransitionDensities'), "0", trandens)
190
191    ! Initialize structure
192    call casida_type_init(cas, sys%gr%sb%dim, sys%st%d%nspin, sys%mc)
193
194    if(fromScratch) call loct_rm(trim(tmpdir)//'restart_casida')
195
196    ! First, print the differences between KS eigenvalues (first approximation to the
197    ! excitation energies, or rather, to the DOS.
198    message(1) = "Info: Approximating resonance energies through KS eigenvalue differences"
199    call write_info(1)
200    cas%type = CASIDA_EPS_DIFF
201    call casida_work(sys, h, cas)
202    call casida_write(cas, 'eps-diff')
203
204    ! Then, calculate the excitation energies by making use of the Petersilka approximation
205    message(1) = "Info: Calculating resonance energies a la Petersilka"
206    call write_info(1)
207    cas%type = CASIDA_PETERSILKA
208    call casida_work(sys, h, cas)
209    call casida_write(cas, 'petersilka')
210
211    ! And finally, solve the full Casida problem.
212    message(1) = "Info: Calculating resonance energies a la Casida"
213    call write_info(1)
214    cas%type = CASIDA_CASIDA
215    call casida_work(sys, h, cas)
216    call casida_write(cas, 'casida')
217
218    ! Calculate and write the transition matrix
219    if (sys%st%d%wfs_type == M_REAL) then
220      call dget_transition_densities(cas, sys, trandens)
221    else
222      call zget_transition_densities(cas, sys, trandens)
223    end if
224
225    call casida_type_end(cas)
226
227    call pop_sub()
228  end subroutine casida_run
229
230  ! ---------------------------------------------------------
231  ! allocates stuff, and constructs the arrays pair_i and pair_j
232  subroutine casida_type_init(cas, dim, nspin, mc)
233    type(casida_t), intent(inout) :: cas
234    integer, intent(in) :: dim, nspin
235    type(multicomm_t), intent(in) :: mc
236
237    integer :: i, a, j, k
238
239    call push_sub('casida.casida_type_init')
240
241    ! count pairs
242    cas%n_pairs = 0
243    do k = 1, nspin
244      do a = cas%n_occ(k)+1, cas%n_occ(k) + cas%n_unocc(k)
245        if(loct_isinstringlist(a, cas%wfn_list)) then
246          do i = 1, cas%n_occ(k)
247            if(loct_isinstringlist(i, cas%wfn_list)) then
248              cas%n_pairs = cas%n_pairs + 1
249            end if
250          end do
251        end if
252      end do
253    end do
254
255    if(cas%n_pairs < 1) then
256      message(1) = "Error: Maybe there are no unoccupied states?"
257      call write_fatal(1)
258    end if
259
260    ! allocate stuff
261    ALLOCATE(cas%pair(cas%n_pairs), cas%n_pairs)
262    ALLOCATE(cas%mat(cas%n_pairs, cas%n_pairs), cas%n_pairs*cas%n_pairs)
263    ALLOCATE(cas%tm(cas%n_pairs, dim), cas%n_pairs*dim)
264    ALLOCATE(cas%f(cas%n_pairs), cas%n_pairs)
265    ALLOCATE(cas%s(cas%n_pairs), cas%n_pairs)
266    ALLOCATE(cas%w(cas%n_pairs), cas%n_pairs)
267
268    ! create pairs
269    j = 1
270    do k = 1, nspin
271      do a = cas%n_occ(k)+1, cas%n_occ(k) + cas%n_unocc(k)
272        if(loct_isinstringlist(a, cas%wfn_list)) then
273          do i = 1, cas%n_occ(k)
274            if(loct_isinstringlist(i, cas%wfn_list)) then
275              cas%pair(j)%i = i
276              cas%pair(j)%a = a
277              cas%pair(j)%sigma = k
278              j = j + 1
279            end if
280          end do
281        end if
282      end do
283    end do
284
285    ! now let us take care of initializing the parallel stuff
286    cas%parallel_in_eh_pairs = multicomm_strategy_is_parallel(mc, P_STRATEGY_OTHER)
287    if(cas%parallel_in_eh_pairs) then
288      call mpi_grp_init(cas%mpi_grp, mc%group_comm(P_STRATEGY_OTHER))
289    else
290      call mpi_grp_init(cas%mpi_grp, -1)
291    end if
292
293    call pop_sub()
294  end subroutine casida_type_init
295
296
297  ! ---------------------------------------------------------
298  subroutine casida_type_end(cas)
299    type(casida_t), intent(inout) :: cas
300    call push_sub('casida.casida_type_end')
301
302    ASSERT(associated(cas%pair))
303    deallocate(cas%pair, cas%mat, cas%tm, cas%s, cas%f, cas%w)
304    nullify   (cas%pair, cas%mat, cas%tm, cas%s, cas%f, cas%w)
305
306    call pop_sub()
307  end subroutine casida_type_end
308
309
310  ! ---------------------------------------------------------
311  ! this subroutine calculates electronic excitation energies using
312  ! the matrix formulation of M. Petersilka, or of M. Casida
313  subroutine casida_work(sys, h, cas)
314    type(system_t), target, intent(inout) :: sys
315    type(hamiltonian_t),    intent(in)    :: h
316    type(casida_t),         intent(inout) :: cas
317
318    logical, allocatable :: saved_K(:, :)         ! which matrix elements have been loaded
319    type(states_t), pointer :: st
320    type(mesh_t),   pointer :: m
321
322    FLOAT, allocatable :: rho(:, :), fxc(:,:,:), pot(:)
323    integer :: is, j_old, b_old, mu_old
324
325    call push_sub('casida.casida_work')
326
327    ! sanity checks
328    ASSERT(cas%type>=CASIDA_EPS_DIFF.and.cas%type<=CASIDA_CASIDA)
329
330    ! some shortcuts
331    st => sys%st
332    m  => sys%gr%m
333
334    ! initialize stuff
335    ALLOCATE(saved_K(cas%n_pairs, cas%n_pairs), cas%n_pairs*cas%n_pairs)
336    cas%mat = M_ZERO
337    saved_K = .false.
338    cas%tm  = M_ZERO
339    cas%f   = M_ZERO
340    cas%w   = M_ZERO
341    cas%s   = M_ZERO
342
343    ! load saved matrix elements
344    call load_saved()
345
346    ! This is to be allocated here, and is used inside K_term.
347    ALLOCATE(pot(m%np), m%np)
348    j_old = -1; b_old = -1; mu_old = -1
349
350    ! We calculate here the kernel, since it will be needed later.
351    ALLOCATE(rho(m%np, st%d%nspin), m%np*st%d%nspin)
352    ALLOCATE(fxc(m%np, st%d%nspin, st%d%nspin), m%np*st%d%nspin*st%d%nspin)
353    rho = M_ZERO; fxc = M_ZERO
354
355    if(associated(st%rho_core)) then
356      do is = 1, st%d%spin_channels
357        rho(1:m%np, is) = st%rho(1:m%np, is) + st%rho_core(1:m%np)/st%d%spin_channels
358      end do
359    else
360      rho(1:m%np, 1:st%d%nspin) = st%rho(1:m%np, 1:st%d%nspin)
361    end if
362    call xc_get_fxc(sys%ks%xc, m, rho, st%d%ispin, fxc)
363
364    select case(cas%type)
365    case(CASIDA_EPS_DIFF)
366      call solve_petersilka()
367    case(CASIDA_PETERSILKA)
368      call solve_petersilka()
369    case(CASIDA_CASIDA)
370      call solve_casida()
371    end select
372
373    ! clean up
374    deallocate(fxc, rho, pot, saved_K)
375
376    call pop_sub()
377  contains
378
379    ! ---------------------------------------------------------
380    subroutine solve_petersilka
381      integer :: ia, iunit, k
382      FLOAT   :: f
383      FLOAT, allocatable :: deltav(:), x(:)
384
385      call push_sub('casida.solve_petersilka')
386
387      ! initialize progress bar
388      if(mpi_grp_is_root(mpi_world)) call loct_progress_bar(-1, cas%n_pairs)
389
390      ! file to save matrix elements
391      iunit = io_open(trim(tmpdir)//'restart_casida', action='write', position='append', is_tmp=.true.)
392
393      do ia = 1, cas%n_pairs
394        cas%w(ia) = st%eigenval(cas%pair(ia)%a, cas%pair(ia)%sigma) - &
395                    st%eigenval(cas%pair(ia)%i, cas%pair(ia)%sigma)
396
397        if(cas%type == CASIDA_PETERSILKA) then
398          if(saved_K(ia, ia)) then
399            f = cas%mat(ia, ia)
400          else
401            f = K_term(cas%pair(ia), cas%pair(ia))
402            write(iunit, *) ia, ia, f
403          end if
404          cas%w(ia) = cas%w(ia) + M_TWO*f
405        end if
406
407        if(mpi_grp_is_root(mpi_world)) call loct_progress_bar(ia, cas%n_pairs)
408      end do
409
410      ALLOCATE(x(cas%n_pairs), cas%n_pairs)
411      ALLOCATE(deltav(m%np), m%np)
412      do k = 1, m%sb%dim
413       
414        !WARNING: should x always be real?
415        x = dks_matrix_elements(cas, st, m, deltav)
416
417        !FIXME: Calculate the oscillator strengths and matrix elements a la Petersilka
418      end do
419      deallocate(x, deltav)
420
421      if(mpi_grp_is_root(mpi_world)) write(*, "(1x)")
422
423      ! close restart file
424      call io_close(iunit)
425      call pop_sub()
426    end subroutine solve_petersilka
427
428
429    ! ---------------------------------------------------------
430    subroutine solve_casida()
431      FLOAT :: temp
432      integer :: ia, jb, k
433      integer :: max, actual, iunit, counter
434      FLOAT, allocatable :: deltav(:)
435
436      FLOAT, allocatable :: dx(:), tmp(:,:)
437      CMPLX, allocatable :: zx(:)
438      type(states_pair_t), pointer :: p, q
439#ifdef HAVE_MPI
440      FLOAT, allocatable :: mpi_mat(:,:)
441#endif
442
443      call push_sub('casida.solve_casida')
444
445      max = (cas%n_pairs*(1 + cas%n_pairs)/2)/cas%mpi_grp%size
446      counter = 0
447      actual = 0
448      if(mpi_grp_is_root(mpi_world)) call loct_progress_bar(-1, max)
449
450      if(.not.mpi_grp_is_root(mpi_world)) cas%mat = M_ZERO
451
452      ! calculate the matrix elements of (v + fxc)
453      do jb = 1, cas%n_pairs
454        actual = actual + 1
455        if(mod(actual, cas%mpi_grp%size) .ne. cas%mpi_grp%rank) cycle
456        do ia = jb, cas%n_pairs
457          counter = counter + 1
458          ! if not loaded, then calculate matrix element
459          if(.not.saved_K(ia, jb)) then
460            cas%mat(ia, jb) = K_term(cas%pair(ia), cas%pair(jb))
461          end if
462          if(jb /= ia) cas%mat(jb, ia) = cas%mat(ia, jb) ! the matrix is symmetric
463        end do
464        if(mpi_grp_is_root(mpi_world)) call loct_progress_bar(counter, max)
465      end do
466
467      ! sum all matrix elements
468#ifdef HAVE_MPI
469      if(cas%parallel_in_eh_pairs) then
470        ALLOCATE(mpi_mat(cas%n_pairs, cas%n_pairs), cas%n_pairs*cas%n_pairs)
471        call MPI_Allreduce(cas%mat(1,1), mpi_mat(1,1), cas%n_pairs**2, &
472          MPI_FLOAT, MPI_SUM, cas%mpi_grp%comm, mpi_err)
473        cas%mat = mpi_mat
474        deallocate(mpi_mat)
475      end if
476#endif
477      !if(mpi_grp_is_root(cas%mpi_grp)) print *, "mat =", cas%mat
478
479      ! all processors with the exception of the first are done
480      if (mpi_grp_is_root(cas%mpi_grp)) then
481
482        ! complete progress bar
483        if(mpi_grp_is_root(mpi_world)) write(stdout, '(1x)')
484
485        ! complete the matrix and output the restart file
486        iunit = io_open(trim(tmpdir)//'restart_casida', action='write', position='append', is_tmp=.true.)
487        do ia = 1, cas%n_pairs
488          p => cas%pair(ia)
489          temp = st%eigenval(p%a, p%sigma) - st%eigenval(p%i, p%sigma)
490
491          do jb = ia, cas%n_pairs
492            q => cas%pair(jb)
493            if(.not.saved_K(ia, jb)) write(iunit, *) ia, jb, cas%mat(ia, jb)
494
495            if(sys%st%d%ispin == UNPOLARIZED) then
496              cas%mat(ia, jb)  = M_FOUR * sqrt(temp) * cas%mat(ia, jb) * &
497                sqrt(st%eigenval(q%a, 1) - st%eigenval(q%i, 1))
498            else if(sys%st%d%ispin == SPIN_POLARIZED) then
499              cas%mat(ia, jb)  = M_TWO * sqrt(temp) * cas%mat(ia, jb) * &
500                sqrt(st%eigenval(q%a, q%sigma) - st%eigenval(q%i, q%sigma))
501            end if
502
503            if(jb /= ia) cas%mat(jb, ia) = cas%mat(ia, jb) ! the matrix is symmetric
504          end do
505          cas%mat(ia, ia) = temp**2 + cas%mat(ia, ia)
506        end do
507        call io_close(iunit)
508        ALLOCATE(tmp(1:cas%n_pairs,1:cas%n_pairs),cas%n_pairs*cas%n_pairs)
509        tmp(1:cas%n_pairs,1:cas%n_pairs) = cas%mat(1:cas%n_pairs,1:cas%n_pairs)
510        ! now we diagonalize the matrix
511        call lalg_eigensolve(cas%n_pairs, tmp, cas%mat, cas%w)
512        DEALLOCATE(tmp)
513
514        do ia = 1, cas%n_pairs
515          if(cas%w(ia) < M_ZERO) then
516            write(message(1),'(a,i4,a)') 'For whatever reason, the excitation energy',ia,' is negative.'
517            write(message(2),'(a)')      'This should not happen.'
518            call write_warning(2)
519            cas%w(ia) = M_ZERO
520          else
521            cas%w(ia) = sqrt(cas%w(ia))
522          end if
523        end do
524
525        ! And let us now get the S matrix...
526        do ia = 1, cas%n_pairs
527          if(sys%st%d%ispin == UNPOLARIZED) then
528            cas%s(ia) = M_HALF / ( st%eigenval(cas%pair(ia)%a, 1) - st%eigenval(cas%pair(ia)%i, 1) )
529          elseif(sys%st%d%ispin == SPIN_POLARIZED) then
530            cas%s(ia) = M_ONE / ( st%eigenval(cas%pair(ia)%a, cas%pair(ia)%sigma) - &
531                                  st%eigenval(cas%pair(ia)%i, cas%pair(ia)%sigma) )
532          end if
533        end do
534
535        ALLOCATE(deltav(m%np), m%np)
536        if (st%d%wfs_type == M_REAL) then
537          ALLOCATE(dx(cas%n_pairs), cas%n_pairs)
538          do k = 1, m%sb%dim
539            deltav(1:m%np) = m%x(1:m%np, k)
540            ! let us get now the x vector.
541            dx = dks_matrix_elements(cas, st, m, deltav)
542            ! And now we are able to get the transition matrix elements between many-electron states.
543            do ia = 1, cas%n_pairs
544              cas%tm(ia, k) = dtransition_matrix_element(cas, ia, dx)
545            end do
546          end do
547          deallocate(deltav, dx)
548        else
549          ALLOCATE(zx(cas%n_pairs), cas%n_pairs)
550          do k = 1, m%sb%dim
551            deltav(1:m%np) = m%x(1:m%np, k)
552            ! let us get now the x vector.
553            zx = zks_matrix_elements(cas, st, m, deltav)
554            ! And now we are able to get the transition matrix elements between many-electron states.
555            do ia = 1, cas%n_pairs
556              cas%tm(ia, k) = ztransition_matrix_element(cas, ia, zx)
557            end do
558          end do
559          deallocate(deltav, zx)
560        end if
561
562
563        ! And the oscillatory strengths.
564        do ia = 1, cas%n_pairs
565          cas%f(ia) = (M_TWO/m%sb%dim) * cas%w(ia) * sum( (abs(cas%tm(ia, :)))**2 )
566        end do
567
568      end if
569
570#if defined(HAVE_MPI)
571      if(cas%parallel_in_eh_pairs) then
572        call MPI_Barrier(cas%mpi_grp%comm, mpi_err)
573      end if
574#endif
575
576      call pop_sub()
577    end subroutine solve_casida
578
579
580    ! return the matrix element of <i(p),a(p)|v + fxc|j(q),b(q)>
581    function K_term(p, q)
582      FLOAT :: K_term
583      type(states_pair_t), intent(in) :: p, q
584
585      integer :: i, j, sigma, a, b, mu
586      FLOAT, allocatable :: rho_i(:), rho_j(:)
587
588      i = p%i; a = p%a; sigma = p%sigma
589      j = q%i; b = q%a; mu = q%sigma
590
591      ALLOCATE(rho_i(m%np), m%np)
592      ALLOCATE(rho_j(m%np), m%np)
593
594      if (st%d%wfs_type == M_REAL) then
595        rho_i(:) =  st%dpsi(1:m%np, 1, i, sigma) * st%dpsi(1:m%np, 1, a, sigma)
596        rho_j(:) =  st%dpsi(1:m%np, 1, j, mu) * st%dpsi(1:m%np, 1, b, mu)
597      else
598        rho_i(:) =  st%zpsi(1:m%np, 1, i, sigma) * conjg(st%zpsi(1:m%np, 1, a, sigma))
599        rho_j(:) =  conjg(st%zpsi(1:m%np, 1, j, mu)) * st%zpsi(1:m%np, 1, b, mu)
600      end if
601
602      !  first the Hartree part (only works for real wfs...)
603      if( j.ne.j_old  .or.   b.ne.b_old   .or.  mu.ne.mu_old) then
604        pot = M_ZERO
605        if( (.not.h%ip_app) ) call dpoisson_solve(sys%gr, pot, rho_j, all_nodes=.false.)
606      end if
607
608      K_term = dmf_dotp(m, rho_i(:), pot(:))
609      rho(1:m%np, 1) = rho_i(1:m%np) * rho_j(1:m%np) * fxc(1:m%np, sigma, mu)
610      K_term = K_term + dmf_integrate(m, rho(:, 1))
611
612      j_old = j; b_old = b; mu_old = mu
613
614      deallocate(rho_i, rho_j)
615    end function K_term
616
617    ! ---------------------------------------------------------
618    subroutine load_saved
619      integer :: iunit, err
620      integer :: ia, jb
621      FLOAT   :: val
622
623      call push_sub('casida.load_saved')
624
625      iunit = io_open(trim(tmpdir)//'restart_casida', action='read', status='old', die=.false., is_tmp=.true.)
626      if( iunit <= 0) return
627
628      do
629        read(iunit, fmt=*, iostat=err) ia, jb, val
630        if(err.ne.0) exit
631        if((ia > 0.and.ia <= cas%n_pairs) .and. (jb > 0.and.jb <= cas%n_pairs)) then
632          cas%mat(ia, jb) = val
633          saved_K(ia, jb) = .true.
634          cas%mat(jb, ia) = val
635          saved_K(jb, ia) = .true.
636        end if
637      end do
638
639      if(iunit > 0) call io_close(iunit)
640      call pop_sub()
641    end subroutine load_saved
642
643  end subroutine casida_work
644
645
646  ! ---------------------------------------------------------
647  subroutine casida_write(cas, filename)
648    type(casida_t), intent(in) :: cas
649    character(len=*),  intent(in) :: filename
650
651    character(len=5) :: str
652    integer :: iunit, ia, jb, dim
653    FLOAT   :: temp
654    integer, allocatable :: ind(:)
655    FLOAT, allocatable :: w(:)
656
657    if(.not.mpi_grp_is_root(cas%mpi_grp)) return
658
659    call push_sub('casida.casida_write')
660
661    dim = size(cas%tm, 2)
662
663    ALLOCATE(w(cas%n_pairs), cas%n_pairs)
664    ALLOCATE(ind(cas%n_pairs), cas%n_pairs)
665    w = cas%w
666    call sort(w, ind)
667
668    ! output excitation energies and oscillator strengths
669    call io_mkdir('linear')
670    iunit = io_open('linear/'//trim(filename), action='write')
671
672    if(cas%type == CASIDA_EPS_DIFF) write(iunit, '(2a4)', advance='no') 'From', ' To '
673
674    select case(dim)
675    case(1); write(iunit, '(3(a15,1x))') 'E' , '<x>', '<f>'
676    case(2); write(iunit, '(4(a15,1x))') 'E' , '<x>', '<y>', '<f>'
677    case(3); write(iunit, '(5(a15,1x))') 'E' , '<x>', '<y>', '<z>', '<f>'
678    end select
679    do ia = 1, cas%n_pairs
680      if((cas%type==CASIDA_EPS_DIFF).or.(cas%type==CASIDA_PETERSILKA)) then
681        write(iunit, '(2i4)', advance='no') cas%pair(ind(ia))%i, cas%pair(ind(ia))%a
682      end if
683      write(iunit, '(5(es15.8,1x))') cas%w(ind(ia)) / units_out%energy%factor, &
684        cas%tm(ind(ia), 1:dim) / units_out%length%factor, cas%f(ind(ia))
685    end do
686    call io_close(iunit)
687
688    ! output eigenvectors in casida approach
689
690    if(cas%type.ne.CASIDA_CASIDA) return
691
692    call io_mkdir('linear/excitations')
693    do ia = 1, cas%n_pairs
694      write(str,'(i5.5)') ia
695      iunit = io_open('linear/excitations/'//trim(str), action='write')
696      ! First, a little header
697      write(iunit,'(a,es14.5)') '# Energy ['// trim(units_out%energy%abbrev) // '] = ', &
698                                cas%w(ind(ia)) / units_out%energy%factor
699        write(iunit,'(a,es14.5)') '# <X> ['//trim(units_out%length%abbrev)// '] = ', &
700                                  cas%tm(ind(ia),1) / units_out%length%factor
701      if(dim > 1) &
702        write(iunit,'(a,es14.5)') '# <Y> ['//trim(units_out%length%abbrev)// '] = ', &
703                                  cas%tm(ind(ia),2) / units_out%length%factor
704      if(dim > 2) &
705        write(iunit,'(a,es14.5)') '# <Z> ['//trim(units_out%length%abbrev)// '] = ', &
706                                  cas%tm(ind(ia),3) / units_out%length%factor
707
708      temp = M_ONE
709      ! I do not know what this does, or what is for.
710      !if( maxval(cas%mat(:, ind(ia))) < abs(minval(cas%mat(:, ind(ia)))) ) temp = -temp
711
712      do jb = 1, cas%n_pairs
713        write(iunit,*) cas%pair(jb)%i, cas%pair(jb)%a, cas%pair(jb)%sigma, temp * cas%mat(jb, ind(ia))
714      end do
715      call io_close(iunit)
716    end do
717
718    deallocate(w, ind)
719    call pop_sub()
720  end subroutine casida_write
721
722
723#include "undef.F90"
724#include "real.F90"
725#include "casida_inc.F90"
726
727#include "undef.F90"
728#include "complex.F90"
729#include "casida_inc.F90"
730
731end module casida_m
732
733!! Local Variables:
734!! mode: f90
735!! coding: utf-8
736!! End:
Note: See TracBrowser for help on using the browser.