PROGRESS  master
prg_pulaycomponent_mod.F90
Go to the documentation of this file.
1 
6 
7  use bml
8 
9  implicit none
10 
11  private
12 
13  integer,parameter :: dp = kind(1.0d0)
14 
16 
17 contains
18 
30  subroutine prg_pulaycomponent0(rho_bml,ham_bml,pcm_bml,threshold,M,&
31  &bml_type,verbose)
32 
33  implicit none
34 
35  type(bml_matrix_t), intent(in) :: rho_bml
36  type(bml_matrix_t), intent(in) :: ham_bml
37  type(bml_matrix_t) :: aux_bml
38  type(bml_matrix_t), intent(inout) :: pcm_bml
39  integer, intent(in) :: m
40  integer :: norb, verbose
41  real(dp), intent(in) :: threshold
42  character(20), intent(in) :: bml_type
43 
44  if(verbose.eq.2) write(*,*)"In prg_PulayComponent0 ..."
45 
46  norb = bml_get_n(rho_bml)
47 
48  call bml_zero_matrix(bml_type,bml_element_real,dp,norb ,norb,aux_bml)
49 
50  if(bml_get_n(pcm_bml).le.0)then !If pcm is not allocated
51  call bml_zero_matrix(bml_type,bml_element_real,dp,norb,norb,pcm_bml)
52  else
53  call bml_deallocate(pcm_bml) !If pcm is allocated then we set it to 0
54  call bml_zero_matrix(bml_type,bml_element_real,dp,norb,norb,pcm_bml)
55  endif
56 
57  call bml_zero_matrix(bml_type,bml_element_real,dp,norb ,norb,pcm_bml)
58 
59  call bml_multiply(rho_bml, ham_bml, aux_bml, 1.0d0, 1.0d0,threshold) !D*H
60 
61  call bml_multiply(aux_bml,rho_bml,pcm_bml, 1.0d0, 1.0d0,threshold) !(D*H)*D
62 
63  call bml_scale(0.5_dp, pcm_bml)
64 
65  call bml_deallocate(aux_bml)
66 
67  end subroutine prg_pulaycomponent0
68 
81  subroutine prg_pulaycomponentt(rho_bml,ham_bml,zmat_bml,pcm_bml,threshold &
82  &,M,bml_type,verbose)
83 
84  implicit none
85 
86  type(bml_matrix_t), intent(in) :: rho_bml
87  type(bml_matrix_t), intent(in) :: ham_bml
88  type(bml_matrix_t), intent(in) :: zmat_bml
89  type(bml_matrix_t) :: aux_bml
90  type(bml_matrix_t) :: aux1_bml
91  type(bml_matrix_t), intent(inout) :: pcm_bml
92  integer, intent(in) :: m
93  integer :: norb, verbose
94  real(dp), intent(in) :: threshold
95  character(20), intent(in) :: bml_type
96 
97  if(verbose.eq.2) write(*,*)"In prg_PulayComponentT ..."
98 
99  norb = bml_get_n(rho_bml)
100 
101  if(bml_get_n(pcm_bml).le.0)then !If pcm is not allocated.
102  call bml_zero_matrix(bml_type,bml_element_real,dp,norb,norb,pcm_bml)
103  else
104  call bml_deallocate(pcm_bml) !If pcm is allocated then we set it to 0.
105  call bml_zero_matrix(bml_type,bml_element_real,dp,norb,norb,pcm_bml)
106  endif
107 
108  call bml_zero_matrix(bml_type,bml_element_real,dp,norb ,norb,aux_bml)
109  call bml_zero_matrix(bml_type,bml_element_real,dp,norb ,norb,aux1_bml)
110 
111  if(bml_get_n(zmat_bml).lt.0)then
112  stop 'ERROR: zmat_bml not allocated'
113  endif
114 
115  call bml_multiply(zmat_bml,zmat_bml,aux_bml,1.0d0,1.0d0,threshold) !aux=Z*Z
116 
117  call bml_multiply(aux_bml,ham_bml,pcm_bml,1.0d0,1.0d0,threshold) !Z*Z*H
118 
119  call bml_multiply(pcm_bml,rho_bml,aux1_bml,1.0d0,1.0d0,threshold) !aux1=Z*Z*H*D
120 
121  call bml_scale(0.0_dp, pcm_bml)
122 
123  call bml_multiply(ham_bml,aux_bml,pcm_bml,1.0d0,1.0d0,threshold) !H*Z*Z
124 
125  call bml_scale(0.0_dp, aux_bml) !We set aux to 0 to recicle the variable
126 
127  call bml_multiply(rho_bml,pcm_bml,aux_bml,1.0d0,1.0d0,threshold) !D*H*Z*Z
128 
129  call bml_add_deprecated(0.5d0,aux_bml,0.5d0,aux1_bml)
130 
131  call bml_copy(aux_bml,pcm_bml)
132 
133  call bml_deallocate(aux_bml)
134  call bml_deallocate(aux1_bml)
135 
136 
137  end subroutine prg_pulaycomponentt
138 
139 
150  subroutine prg_get_pulayforce(nats,zmat_bml,ham_bml,rho_bml,&
151  dSx_bml,dSy_bml,dSz_bml,hindex,FPUL,threshold)
152  implicit none
153  real(dp), allocatable, intent(inout) :: fpul(:,:)
154  integer, intent(in) :: nats
155  type(bml_matrix_t), intent(in) :: dsx_bml, dsy_bml, dsz_bml
156  type(bml_matrix_t), intent(in) :: rho_bml, ham_bml, zmat_bml
157  integer, intent(in) :: hindex(:,:)
158  integer :: i_a, i_b, i , j, norb
159  real(dp), intent(in) :: threshold
160  type(bml_matrix_t) :: xtmp_bml, ytmp_bml, ztmp_bml, sihd_bml
161  type(bml_matrix_t) :: aux_bml
162  real(dp), allocatable :: diagxtmp(:), diagytmp(:), diagztmp(:)
163  real(dp) :: partrace
164 
165  write(*,*)"In prg_get_pulayforce ..."
166 
167  if(.not.allocated(fpul))then
168  allocate(fpul(3,nats))
169  endif
170 
171  fpul = 0.0_dp
172 
173  norb = bml_get_n(rho_bml)
174 
175  !SIHD = 2*Z*Z'*H*D;
176  call bml_copy_new(zmat_bml,sihd_bml)
177  call bml_copy_new(zmat_bml,aux_bml)
178  call bml_transpose(zmat_bml,aux_bml) !Z'
179  call bml_multiply(zmat_bml,aux_bml,sihd_bml,2.0_dp,0.0_dp,threshold) !2*Z*Z'
180  call bml_multiply(sihd_bml,ham_bml,aux_bml,1.0_dp,0.0_dp,threshold) !2*Z*Z'*H
181  call bml_multiply(aux_bml,rho_bml,sihd_bml,1.0_dp,0.0_dp,threshold) !2*Z*Z'*D
182  call bml_deallocate(aux_bml)
183 
184  call bml_copy_new(rho_bml,xtmp_bml)
185  allocate(diagxtmp(norb))
186  call bml_multiply(dsx_bml,sihd_bml,xtmp_bml,1.0_dp,0.0_dp,threshold)
187  call bml_get_diagonal(xtmp_bml,diagxtmp)
188  call bml_deallocate(xtmp_bml)
189 
190  call bml_copy_new(rho_bml,ytmp_bml)
191  allocate(diagytmp(norb))
192  call bml_multiply(dsy_bml,sihd_bml,ytmp_bml,1.0_dp,0.0_dp,threshold)
193  call bml_get_diagonal(ytmp_bml,diagytmp)
194  call bml_deallocate(ytmp_bml)
195 
196  call bml_copy_new(rho_bml,ztmp_bml)
197  allocate(diagztmp(norb))
198  call bml_multiply(dsz_bml,sihd_bml,ztmp_bml,1.0_dp,0.0_dp,threshold)
199  call bml_get_diagonal(ztmp_bml,diagztmp)
200  call bml_deallocate(ztmp_bml)
201 
202  call bml_deallocate(sihd_bml)
203 
204  !$omp parallel do default(none) private(i) &
205  !$omp private(I_A,I_B,j,partrace) &
206  !$omp shared(hindex,diagxtmp,diagytmp,diagztmp,FPUL,nats)
207  do i = 1,nats
208  i_a = hindex(1,i);
209  i_b = hindex(2,i);
210 
211  partrace = 0.0_dp
212  do j=i_a,i_b
213  partrace = partrace + diagxtmp(j)
214  enddo
215  fpul(1,i) = partrace;
216 
217  partrace = 0.0_dp
218  do j=i_a,i_b
219  partrace = partrace + diagytmp(j)
220  enddo
221  fpul(2,i) = partrace;
222 
223  partrace = 0.0_dp
224  do j=i_a,i_b
225  partrace = partrace + diagztmp(j)
226  enddo
227  fpul(3,i) = partrace;
228 
229  enddo
230  !$omp end parallel do
231 
232  deallocate(diagxtmp)
233  deallocate(diagytmp)
234  deallocate(diagztmp)
235 
236  end subroutine prg_get_pulayforce
237 
238 end module prg_pulaycomponent_mod
Produces a matrix to get the Pulay Component of the forces.
subroutine, public prg_pulaycomponentt(rho_bml, ham_bml, zmat_bml, pcm_bml, threshold, M, bml_type, verbose)
At , .
subroutine, public prg_get_pulayforce(nats, zmat_bml, ham_bml, rho_bml, dSx_bml, dSy_bml, dSz_bml, hindex, FPUL, threshold)
Pulay Force FPUL from .
subroutine, public prg_pulaycomponent0(rho_bml, ham_bml, pcm_bml, threshold, M, bml_type, verbose)
At , .