PROGRESS  master
prg_charges_mod.F90
Go to the documentation of this file.
1 
6 
8  use bml
10  use prg_graph_mod
11  use prg_system_mod
12 
13  implicit none
14 
15  private
16 
17  integer, parameter :: dp = kind(1.0d0)
18 
20 
21 contains
22 
30  subroutine prg_get_charges(rho_bml,over_bml,hindex,charges,numel,spindex,mdimin,threshold)
31  character(20) :: bml_type, bml_mode
32  integer :: i, j, nats, norb
33  integer :: mdim
34  integer, intent(in) :: hindex(:,:), mdimin, spindex(:)
35  real(dp) :: znuc
36  real(dp), allocatable :: rho_diag(:)
37  real(dp), allocatable, intent(inout) :: charges(:)
38  real(dp), intent(in) :: numel(:), threshold
39  type(bml_matrix_t) :: aux_bml
40  type(bml_matrix_t), intent(inout) :: over_bml, rho_bml
41 
42  norb = bml_get_n(rho_bml)
43  bml_type = bml_get_type(rho_bml)
44  bml_mode = bml_get_distribution_mode(rho_bml)
45  nats = size(hindex,dim=2)
46 
47  if(mdimin.lt.0)then
48  mdim = norb
49  else
50  mdim = mdimin
51  endif
52 
53  if(.not.allocated(charges)) allocate(charges(nats))
54  allocate(rho_diag(norb))
55 
56  call bml_zero_matrix(bml_type,bml_element_real,dp,norb,mdim,aux_bml, &
57  bml_mode)
58 
59  call bml_multiply(rho_bml,over_bml,aux_bml,1.0_dp,0.0_dp,threshold)
60 
61 #ifdef DO_MPI
62  if (getnranks() .gt. 1 .and. &
63  bml_get_distribution_mode(aux_bml) == bml_dmode_distributed) then
64  call prg_allgatherparallel(aux_bml)
65  endif
66 #endif
67 
68  call bml_get_diagonal(aux_bml,rho_diag)
69 
70  do i = 1,nats
71  znuc = numel(spindex(i))
72  charges(i)=0.0_dp
73  do j = hindex(1,i),hindex(2,i)
74  charges(i) = charges(i) + rho_diag(j)
75  enddo
76  charges(i) = charges(i) - znuc
77  enddo
78 
79  deallocate(rho_diag)
80  call bml_deallocate(aux_bml)
81 
82  end subroutine prg_get_charges
83 
98  subroutine prg_get_hscf(ham0_bml,over_bml,ham_bml,spindex,hindex,hubbardu,charges,&
99  coulomb_pot_r,coulomb_pot_k,mdimin,threshold)
100  character(20) :: bml_type
101  integer :: i, j, nats, norb, mdim
102  integer, intent(in) :: hindex(:,:), mdimin, spindex(:)
103  real(dp), allocatable :: coulomb_pot(:), diagonal(:)
104  real(dp), intent(in) :: charges(:), coulomb_pot_k(:), coulomb_pot_r(:), hubbardu(:)
105  real(dp), intent(in) :: threshold
106  type(bml_matrix_t) :: aux_bml
107  type(bml_matrix_t), intent(in) :: ham0_bml, over_bml
108  type(bml_matrix_t), intent(inout) :: ham_bml
109 
110  nats = size(coulomb_pot_r)
111  allocate(coulomb_pot(nats))
112 
113  norb = bml_get_n(ham0_bml)
114  if(hindex(2,nats) .ne. norb)then
115  write(*,*)"ERROR in prg_get_hscf. hindex incompatible with ham0"
116  stop
117  endif
118 
119  if(mdimin.lt.0)then
120  mdim = norb
121  else
122  mdim = mdimin
123  endif
124 
125  allocate(diagonal(norb))
126 
127  call bml_copy_new(ham0_bml,ham_bml)
128 
129  bml_type = bml_get_type(ham_bml)
130 
131  coulomb_pot = coulomb_pot_k + coulomb_pot_r
132 
133  call bml_zero_matrix(bml_type,bml_element_real,dp,mdim,norb,aux_bml)
134 
135  do i = 1,nats
136  do j = hindex(1,i),hindex(2,i)
137  diagonal(j) = hubbardu(spindex(i))*charges(i) + coulomb_pot(i)
138  enddo
139  enddo
140 
141  call bml_set_diagonal(aux_bml,diagonal)
142 
143  call bml_multiply(over_bml,aux_bml,ham_bml,0.5_dp,1.0_dp,threshold) ! h = h + 0.5*s*h1
144 
145  call bml_multiply(aux_bml,over_bml,ham_bml,0.5_dp,1.0_dp,threshold) ! h = h + 0.5*h1*s
146 
147  deallocate(diagonal)
148  deallocate(coulomb_pot)
149  call bml_deallocate(aux_bml)
150 
151  end subroutine prg_get_hscf
152 
153 
154  subroutine prg_get_hscf_v2(ham0_bml,over_bml,ham_bml,spindex,hindex,hubbardu,charges,&
155  coulomb_pot_r,coulomb_pot_k,mdimin,threshold)
156  character(20) :: bml_type
157  integer :: i, j, nats, norb, mdim
158  integer, intent(in) :: hindex(:,:), mdimin, spindex(:)
159  real(dp), allocatable :: coulomb_pot(:), diagonal(:)
160  real(dp), intent(in) :: charges(:), coulomb_pot_k(:),coulomb_pot_r(:), hubbardu(:)
161  real(dp), intent(in) :: threshold
162  type(bml_matrix_t) :: aux_bml
163  type(bml_matrix_t), intent(in) :: ham0_bml, over_bml
164  type(bml_matrix_t), intent(inout) :: ham_bml
165 
166  nats = size(coulomb_pot_r)
167  allocate(coulomb_pot(nats))
168 
169  norb = bml_get_n(ham0_bml)
170  if(hindex(2,nats) .ne. norb)then
171  write(*,*)"ERROR in prg_get_hscf. hindex incompatible with ham0"
172  stop
173  endif
174 
175  if(mdimin.lt.0)then
176  mdim = norb
177  else
178  mdim = mdimin
179  endif
180 
181  allocate(diagonal(norb))
182 
183  call bml_copy_new(ham0_bml,ham_bml)
184 
185  bml_type = bml_get_type(ham_bml)
186 
187  coulomb_pot = coulomb_pot_k + coulomb_pot_r
188 
189  call bml_zero_matrix(bml_type,bml_element_real,dp,mdim,norb,aux_bml)
190 
191  do i = 1,nats
192  do j = hindex(1,i),hindex(2,i)
193  diagonal(j) = hubbardu(spindex(i))*charges(i) + coulomb_pot(i)
194  enddo
195  enddo
196 
197  call bml_set_diagonal(aux_bml,diagonal)
198  call bml_multiply(over_bml,aux_bml,ham_bml,0.5_dp,1.0_dp,threshold) ! h = h+ 0.5*s*h1
199 
200  call bml_multiply(aux_bml,over_bml,ham_bml,0.5_dp,1.0_dp,threshold) ! h = h+ 0.5*h1*s
201 
202  deallocate(diagonal)
203  deallocate(coulomb_pot)
204  call bml_deallocate(aux_bml)
205 
206  end subroutine prg_get_hscf_v2
207 
208 
209 end module prg_charges_mod
A module to compute the Mulliken charges of a chemical system.
subroutine, public prg_get_hscf(ham0_bml, over_bml, ham_bml, spindex, hindex, hubbardu, charges, coulomb_pot_r, coulomb_pot_k, mdimin, threshold)
Constructs the SCF Hamiltonian given H0, HubbardU and charges. This routine does: ,...
subroutine, public prg_get_hscf_v2(ham0_bml, over_bml, ham_bml, spindex, hindex, hubbardu, charges, coulomb_pot_r, coulomb_pot_k, mdimin, threshold)
subroutine, public prg_get_charges(rho_bml, over_bml, hindex, charges, numel, spindex, mdimin, threshold)
Constructs the charges from the density matrix.
integer, parameter dp
The graph module.
Module to handle input output files for the PROGRESS lib.
The parallel module.
subroutine, public prg_allgatherparallel(a)
integer function, public getnranks()
A module to read and handle chemical systems.