TABLE OF CONTENTS


ABINIT/m_matrix [ Modules ]

[ Top ] [ Modules ]

NAME

 m_matrix

FUNCTION

 Module containing some function acting on a matrix 
  (sqrt root)

COPYRIGHT

 Copyright (C) 2009-2024 ABINIT group (BA)
 This file is distributed under the terms of the
 GNU General Public License, see ~abinit/COPYING
 or http://www.gnu.org/copyleft/gpl.txt .

NOTES

SOURCE

19 #if defined HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22 
23 #include "abi_common.h"
24 
25 MODULE m_matrix
26 
27  use defs_basis
28  use m_errors
29  use m_abicore
30 
31  use m_hide_lapack,  only : xginv
32 
33  implicit none
34 
35  private
36 
37 ! public :: init_matrix         ! Main creation method
38  public :: invsqrt_matrix         ! inv of Sqrt of Matrix
39  public :: blockdiago_fordsyev         ! inv of Sqrt of Matrix
40  public :: blockdiago_forzheev         ! inv of Sqrt of Matrix
41 ! public :: inverse_matrix      ! Inverse matrix
42 ! public :: nullify_matrix      ! Nullify the object
43 ! public :: destroy_matrix      ! Frees the allocated memory
44 ! public :: print_matrix        ! Printout of the basic info
45 
46 
47 CONTAINS  !===========================================================

FUNCTION

  Initialize matrix

INPUTS

  ndim = dimension of matrix
  matrix= matrix

OUTPUT

  matrix= square root of the matrix
  force_diag = 0 if it no 0 on diagonal
             = nb of zeros found otherwise

SOURCE

 63 subroutine invsqrt_matrix(matrix,tndim,force_diag)
 64 
 65 !Arguments ------------------------------------
 66 !scalars
 67  integer,intent(in) :: tndim 
 68  complex(dpc),intent(inout) :: matrix(tndim,tndim)
 69  integer, intent(out) :: force_diag
 70 !arrays
 71 
 72 !Local variables-------------------------------
 73 !scalars
 74  integer :: im,im1,im2,info,lwork,nb_of_zero
 75  character(len=500) :: message
 76  real(dp) :: pawprtvol
 77 !arrays
 78  real(dp),allocatable :: eig(:),rwork(:)
 79  complex(dpc),allocatable :: zwork(:),diag(:,:)
 80  complex(dpc),allocatable :: sqrtmat(:,:),zhdp2(:,:),sqrtmatinv(:,:)
 81  complex(dpc),allocatable :: initialmatrix(:,:)
 82  
 83 ! *************************************************************************
 84 
 85 !Do not remove this silly print instruction. Seems needed to avoid floating
 86 !point exception on vm1_gcc51 ...
 87 #if __GFORTRAN__ == 1 && __GNUC__ == 5 && (__GNUC_MINOR__ == 1 || __GNUC_MINOR__ == 2)
 88  write(std_out,'(a)')' invsqrt_matrix at m_matrix.F90 : enter ( needed to avoid FPE with GCC5[1,2] )'
 89 #endif
 90 
 91  DBG_ENTER("COLL")
 92  pawprtvol=2
 93 
 94  ABI_MALLOC(initialmatrix,(tndim,tndim))
 95  initialmatrix=matrix
 96 !  == First diagonalize matrix and keep the matrix for the change of basis
 97  lwork=2*tndim-1
 98  ABI_MALLOC(rwork,(3*tndim-2))
 99  ABI_MALLOC(zwork,(lwork))
100  ABI_MALLOC(eig,(tndim))
101  
102  call zheev('v','u',tndim,matrix,tndim,eig,zwork,lwork,rwork,info)
103  if(pawprtvol>3) then
104    write(message,'(2a)') ch10,'  - rotation matrix - '
105    call wrtout(std_out,message,'COLL')
106    do im1=1,tndim
107      write(message,'(12(1x,18(1x,"(",f7.3,",",f7.3,")")))')&
108 !     write(message,'(12(1x,18(1x,"(",f20.16,",",f20.16,")")))')&
109 &     (matrix(im1,im2),im2=1,tndim)
110     call wrtout(std_out,message,'COLL')
111    end do
112  endif
113  
114  
115  ABI_FREE(zwork)
116  ABI_FREE(rwork)
117  if(info/=0) then
118   message = 'Error in diagonalization of zmat (zheev) ! - '
119   ABI_ERROR(message)
120  end if
121 
122 !  == Secondly Compute sqrt(diagonalized matrix)
123  ABI_MALLOC(diag,(tndim,tndim))
124  diag=czero
125  nb_of_zero=0
126  do im=1,tndim
127 
128    if(eig(im)< -tol8) then
129      message = "  - Eigenvalues from zheev are negative or zero ! - "
130      write(std_out,*)
131      write(std_out,*) "    Eigenvalue=",eig(im)
132      write(std_out,*) "    Matrix is"
133      do im1=1,tndim
134        write(std_out,'(100f7.3)') (initialmatrix(im1,im2),im2=1,tndim)
135      enddo
136      ABI_ERROR(message)
137    else if(abs(eig(im))<tol8) then
138      nb_of_zero=nb_of_zero+1
139    else
140      diag(im,im)=cmplx(one/sqrt(eig(im)),zero,kind=dp)
141    endif
142  enddo
143  force_diag=nb_of_zero
144  ABI_FREE(eig)
145 ! write(std_out,*) "sqrt(eig)                , diag(1,1)",sqrt(eig(1)),diag(1,1)
146 ! write(std_out,*) "cmplx(sqrt(eig(1)),zero,dp) , diag(1,1)",cmplx(sqrt(eig(1)),zero,dp),diag(1,1)
147 ! write(std_out,*) "sqrt(cmplx(eig(1),zero,dp)) , diag(1,1)",sqrt(cmplx(eig(1),zero,dp)),diag(1,1)
148 
149 !  == Thirdly Multiply by  matrix for the change of basis
150  ABI_MALLOC(sqrtmat,(tndim,tndim))
151  ABI_MALLOC(zhdp2,(tndim,tndim))
152  if(pawprtvol>3) then
153    write(message,'(2a)') ch10,'  - 1.0/sqrt(Eigenmatrix) - '
154    call wrtout(std_out,message,'COLL')
155    do im1=1,tndim
156      write(message,'(12(1x,18(1x,"(",f7.3,",",f7.3,")")))')&
157 !     write(message,'(12(1x,18(1x,"(",f20.16,",",f20.16,")")))')&
158 &     (diag(im1,im2),im2=1,tndim)
159     call wrtout(std_out,message,'COLL')
160    end do
161  endif
162 !zgemm(A,B,C) : C = op(A) op(B)
163  call zgemm('n','t',tndim,tndim,tndim,cone,diag,tndim,conjg(matrix),tndim,czero,zhdp2,tndim)
164  call zgemm('n','n',tndim,tndim,tndim,cone,matrix,tndim,zhdp2,tndim,czero,sqrtmat,tndim)
165 ! if(abs(pawprtvol)>=3) then
166  if(pawprtvol>3) then
167    write(message,'(3a)') ch10,"  - inverse Sqrt root of matrix is - "
168    call wrtout(std_out,message,'COLL')
169    do im1=1,tndim
170      write(message,'(12(1x,18(1x,"(",f20.16,",",f20.16,")")))')&
171 &     (sqrtmat(im1,im2),im2=1,tndim)
172      call wrtout(std_out,message,'COLL')
173    end do
174  endif
175 ! endif
176  ABI_FREE(diag)
177 
178 !  == Forthly Compute the inverse of the square root
179 ! call matcginv_dpc(sqrtmat,tndim,tndim)
180  !call xginv(sqrtmat,tndim)
181  ABI_MALLOC(sqrtmatinv,(tndim,tndim))
182  sqrtmatinv=sqrtmat
183  if(pawprtvol>3) then
184    write(message,'(2a)') ch10,"  - inverse Sqrt root of matrix is - "
185    call wrtout(std_out,message,'COLL')
186    do im1=1,tndim
187      write(message,'(12(1x,18(1x,"(",f20.16,",",f20.16,")")))')&
188 &     (sqrtmatinv(im1,im2),im2=1,tndim)
189      call wrtout(std_out,message,'COLL')
190    end do
191  endif
192  ABI_FREE(sqrtmat)
193 
194 !  == Fifthly Check that O^{-0/5} O O{-0/5}=I
195 !  zgemm(A,B,C) : C = op(A) op(B)
196  call zgemm('n','n',tndim,tndim,tndim,cone,initialmatrix,tndim,sqrtmatinv,tndim,czero,zhdp2,tndim)
197  call zgemm('n','n',tndim,tndim,tndim,cone,sqrtmatinv,tndim,zhdp2,tndim,czero,initialmatrix,tndim)
198  if(pawprtvol>3) then
199    write(message,'(3a)') ch10,"  - O^{-0/5} O O^{-0/5}=I - "
200    call wrtout(std_out,message,'COLL')
201    do im1=1,tndim
202      write(message,'(12(1x,18(1x,"(",f10.6,",",f4.1,")")))')&
203 !     write(message,'(12(1x,18(1x,"(",f20.16,",",f20.16,")")))')&
204 &     (initialmatrix(im1,im2),im2=1,tndim)
205      call wrtout(std_out,message,'COLL')
206    end do
207  endif
208  ABI_FREE(zhdp2)
209  matrix=sqrtmatinv
210  ABI_FREE(sqrtmatinv)
211  ABI_FREE(initialmatrix)
212 
213  DBG_EXIT("COLL")
214 
215 end subroutine invsqrt_matrix