PROGRESS  master
prg_homolumo_mod.F90
Go to the documentation of this file.
1 
3 !
4 !
5 
7 
8  use bml
9 
10  implicit none
11 
12  private !Everything is private by default
13 
14  integer, parameter :: dp = kind(1.0d0)
15 
16  public :: prg_homolumogap
17  public :: prg_sp2sequence
18 
19 contains
20 
21  !! Calculate the homo-lumo gap
22  subroutine prg_homolumogap(vv, imax, pp, mineval, maxeval, ehomo, elumo, &
23  egap, verbose)
24 
25  integer, intent(in) :: imax
26  integer, intent(in), optional :: verbose
27  integer, intent(in) :: pp(:)
28  real(dp), intent(in) :: vv(:)
29  real(dp), intent(in) :: mineval, maxeval
30  real(dp), intent(inout) :: ehomo, elumo, egap
31 
32  integer :: i, j
33  real(dp) :: precomp, x_a, x_b, y_a, y_b, hgamma
34 
35  x_a = 0.0_dp
36  x_b = 1.0_dp
37  y_a = 0.0_dp
38  y_b = 0.0_dp
39 
40  i = imax
41  do while (vv(i) .le. 0.0)
42  i=i-1
43  enddo
44 
45  hgamma = 6.0_dp - 4.0_dp * sqrt(2.0_dp)
46  hgamma = hgamma * (1.0_dp - hgamma)
47 
48  if(present(verbose))then
49  if(verbose.ge.1) write(*,*)"In prg_homolumogap ..."
50  endif
51 
52  do while (vv(i) .lt. hgamma)
53 
54  precomp = sqrt(1.0_dp - 4.0_dp * vv(i))
55 
56  y_a = 0.5_dp * (1.0_dp + precomp)
57  y_b = 0.5_dp * (1.0_dp - precomp)
58 
59  ! write(*,*)"ya,yb",y_a,y_b
60  ! write(*,*)"y_a = ",y_a,"y_a = ",y_b,"vv(i) = ",vv(i)
61  do j = i-1, 1, -1
62  if (pp(j) .gt. 0) then
63  y_a = sqrt(y_a)
64  y_b = sqrt(y_b)
65  else
66  y_a = 1.0_dp - sqrt(1.0_dp - y_a)
67  y_b = 1.0_dp - sqrt(1.0_dp - y_b)
68  endif
69  enddo
70 
71  x_a = max(x_a, y_a)
72  x_b = min(x_b, y_b)
73 
74  if(present(verbose))then
75  if(verbose.ge.2) write(*,*)"x_a = ",x_a,"x_b = ",x_b
76  endif
77 
78  i = i - 1
79  if (i .lt. 1) then
80  write(*,*) "prg_homolumogap error: i < 1, i = ", i
81  endif
82  enddo
83 
84  ehomo = maxeval - x_a * (maxeval - mineval)
85  elumo = maxeval - x_b * (maxeval - mineval)
86 
87  egap = elumo - ehomo
88 
89  end subroutine prg_homolumogap
90 
91  !! Calculate the SP2 sequence given thw min/max evals and homo amd lumo
92  !! values. Determine sequence of X^2 and 2X-X^2 for SP2.
93  !!
94  !! pp(i) = 0 -> 2X-X^2
95  !! pp(i) = 1 -> x^2
96  !!
97  subroutine prg_sp2sequence(pp, imax, mineval, maxeval, ehomo, elumo, errlimit, verbose)
98 
99  integer, intent(inout) :: imax
100  integer, intent(inout) :: pp(:)
101  real(dp), intent(in) :: mineval, maxeval, ehomo, elumo
102  real(dp), intent(in) :: errlimit
103  integer, intent(in), optional :: verbose
104 
105  integer :: it
106  real(dp) :: eh, el, error, sgm
107 
108  eh = (maxeval - ehomo) / (maxeval - mineval)
109  el = (maxeval - elumo) / (maxeval - mineval)
110  error = 1.0_dp
111 
112  it = 0
113 
114  if(present(verbose))then
115  if(verbose.ge.1) write(*,*)"In prg_sp2sequence ..."
116  endif
117 
118  do while (error .gt. errlimit)
119  it = it + 1
120 
121  if(present(verbose))then
122  if(verbose.ge.2) write(*,*)"error = ",error
123  endif
124 
125  if ((abs(1.0_dp - eh * eh) + abs(el * el)) .lt. &
126  (abs(1.0_dp - (2.0_dp * eh - eh * eh) + &
127  abs(2.0_dp * el - el * el)))) then
128  pp(it) = 1
129  else
130  pp(it) = 0
131  endif
132 
133  sgm = 1.0_dp - 2.0_dp * pp(it)
134  eh = eh + sgm * (eh - eh * eh)
135  el = el + sgm * (el - el * el)
136  error = abs(1.0_dp - eh) + abs(el)
137 
138  if (it .ge. 100) then
139  error = 0.0_dp
140  write(*,*) "prg_sp2sequence error: SP2 not converging"
141  endif
142 
143  enddo
144 
145  imax = it
146 
147  end subroutine prg_sp2sequence
148 
149 end module prg_homolumo_mod
The homolumo module.
subroutine, public prg_homolumogap(vv, imax, pp, mineval, maxeval, ehomo, elumo, egap, verbose)
integer, parameter dp
subroutine, public prg_sp2sequence(pp, imax, mineval, maxeval, ehomo, elumo, errlimit, verbose)