Line data Source code
1 : MODULE m_greensfBZint
2 :
3 : USE m_types
4 : USE m_juDFT
5 : USE m_constants
6 : USE m_greensfEigVecCoeffs
7 : USE m_symMMPmat
8 : USE m_rotMMPmat
9 :
10 : IMPLICIT NONE
11 :
12 : CONTAINS
13 :
14 456 : SUBROUTINE greensfBZint(ikpt,nBands,spin_ind,gfinp,sym,atoms,noco,nococonv,input,kpts,&
15 456 : scalarGF,eigVecCoeffs,greensfBZintCoeffs)
16 :
17 : INTEGER, INTENT(IN) :: ikpt ! current k-point
18 : INTEGER, INTENT(IN) :: nBands !Bands handled on this rank
19 : INTEGER, INTENT(IN) :: spin_ind !spin index
20 : TYPE(t_gfinp), INTENT(IN) :: gfinp
21 : TYPE(t_sym), INTENT(IN) :: sym
22 : TYPE(t_atoms), INTENT(IN) :: atoms
23 : TYPE(t_noco), INTENT(IN) :: noco
24 : TYPE(t_nococonv), INTENT(IN) :: nococonv
25 : TYPE(t_input), INTENT(IN) :: input
26 : TYPE(t_kpts), INTENT(IN) :: kpts
27 : TYPE(t_scalarGF), INTENT(IN) :: scalarGF(:)
28 : TYPE(t_eigVecCoeffs), INTENT(IN) :: eigVecCoeffs
29 : TYPE(t_greensfBZintCoeffs),INTENT(INOUT) :: greensfBZintCoeffs
30 :
31 : INTEGER :: i_gf,l,lp,atomType,atomTypep,i_gf_rot
32 : INTEGER :: natom,natomp,natom_start,natom_end
33 : INTEGER :: i_elem,i_elemLO,nLO,imatSize,imat,iBand,iop
34 : INTEGER :: spin1,spin2,atom,atomp
35 : REAL :: atomDiff(3)
36 : LOGICAL :: l_sphavg,l_intersite
37 456 : COMPLEX, ALLOCATABLE :: im(:,:,:,:)
38 456 : COMPLEX, ALLOCATABLE :: imSym(:,:)
39 456 : TYPE(t_eigVecCoeffs) :: eigVecCoeffs_rot
40 : TYPE(t_gfelementtype) :: rep_elem
41 :
42 456 : IF(spin_ind==3) THEN
43 4 : spin1 = 2
44 4 : spin2 = 1
45 : ELSE
46 452 : spin1 = spin_ind
47 452 : spin2 = spin_ind
48 : ENDIF
49 :
50 456 : call greensfBZintCoeffs%reset()
51 456 : eigVecCoeffs_rot = eigVecCoeffs%rotate_to_rep_atom(atoms,sym,lmaxU_const)
52 :
53 456 : CALL timestart("Green's Function: Brillouin-Zone-Integration")
54 10660 : DO i_gf = 1, gfinp%n
55 :
56 : !Get the information about the current element
57 10204 : l = gfinp%elem(i_gf)%l
58 10204 : lp = gfinp%elem(i_gf)%lp
59 10204 : atomType = gfinp%elem(i_gf)%atomType
60 10204 : atomTypep = gfinp%elem(i_gf)%atomTypep
61 10204 : l_sphavg = gfinp%elem(i_gf)%l_sphavg
62 10204 : l_intersite = gfinp%elem(i_gf)%isIntersite()
63 40816 : atomDiff = gfinp%elem(i_gf)%atomDiff
64 10204 : atom = gfinp%elem(i_gf)%atom
65 10204 : atomp = gfinp%elem(i_gf)%atomp
66 :
67 10204 : IF(.NOT.gfinp%isUnique(i_gf, distinct_symmetry_equivalent_diffs=.TRUE.)) CYCLE
68 10164 : IF(gfinp%elem(i_gf)%representative_elem>0) THEN
69 5004 : rep_elem = gfinp%elem(gfinp%elem(i_gf)%representative_elem)
70 5004 : IF(rep_elem%atom==atom.AND.rep_elem%atomp==atomp) CYCLE
71 : ENDIF
72 :
73 5160 : i_elem = gfinp%uniqueElements(atoms,max_index=i_gf,l_sphavg=l_sphavg)
74 5160 : i_elemLO = gfinp%uniqueElements(atoms,max_index=i_gf,lo=.TRUE.,l_sphavg=l_sphavg)
75 :
76 5160 : nLO = 0
77 5160 : imatSize = 1
78 5160 : IF(.NOT.l_sphavg) THEN
79 120 : imatSize = 4
80 120 : nLO = gfinp%elem(i_gf)%countLOs(atoms)
81 120 : IF(nLO/=0) THEN
82 80 : imatSize = 4+4*nLO+nLO**2
83 : ENDIF
84 : ENDIF
85 :
86 0 : ALLOCATE(im(-lmaxU_const:lmaxU_const,-lmaxU_const:lmaxU_const,nBands,&
87 17626818 : imatSize),source=cmplx_0)
88 :
89 5160 : natom_start = MERGE(atoms%firstAtom(atomType),atom,.NOT.l_intersite)
90 924 : natom_end = MERGE(atoms%firstAtom(atomType) + atoms%neq(atomType) - 1,atom,.NOT.l_intersite)
91 : !Loop over equivalent atoms
92 10320 : DO natom = natom_start , natom_end
93 :
94 5160 : if (l_intersite) then
95 4236 : natomp = atomp
96 : else
97 924 : natomp = natom
98 : endif
99 :
100 31020 : DO iop = 1, MERGE(1, sym%nop, .NOT.l_intersite)
101 :
102 20700 : IF(l_intersite) THEN
103 19776 : i_gf_rot = gfinp%find_symmetry_rotated_greensf(atoms,sym,i_gf,iop,distinct_kresolved_int=.false.)
104 19776 : i_elem = gfinp%uniqueElements(atoms,max_index=i_gf_rot,l_sphavg=l_sphavg)
105 19776 : i_elemLO = gfinp%uniqueElements(atoms,max_index=i_gf_rot,lo=.TRUE.,l_sphavg=l_sphavg)
106 : ENDIF
107 :
108 : CALL greensfEigVecCoeffs(nBands,l,lp,natom,natomp,atomType,atomTypep,spin1,spin2,&
109 20700 : l_sphavg,atoms,scalarGF(i_gf),eigVecCoeffs_rot,im)
110 :
111 :
112 : !The eigenvector coefficients already contains part of the interstitial phase
113 : !but not necessarily the right one
114 20700 : IF(natom/=natomp) THEN
115 : im = im * exp(-tpi_const*ImagUnit*dot_product(kpts%bk(:,ikpt), atoms%taual(:,natom) &
116 7864128 : - atoms%taual(:,natomp)))
117 : ENDIF
118 :
119 20700 : IF(spin_ind<3) THEN
120 87259238 : im = conjg(im)
121 : ELSE
122 26008 : im = -im
123 : ENDIF
124 :
125 : #ifndef CPP_NOTYPEPROCINOMP
126 : !$omp parallel default(none) &
127 : !$omp shared(sym,kpts,atoms,greensfBZintCoeffs,im,nococonv,noco,atomType,imatSize,nBands) &
128 : !$omp shared(l_intersite,l,lp,natom,natomp,spin_ind,iop,atomDiff,i_elem,i_elemLO,ikpt,nLO,l_sphavg) &
129 25860 : !$omp private(imat,iBand,imSym)
130 : #endif
131 : ALLOCATE(imSym(-lmaxU_const:lmaxU_const,-lmaxU_const:lmaxU_const),source=cmplx_0)
132 : #ifndef CPP_NOTYPEPROCINOMP
133 : !$omp do collapse(2)
134 : #endif
135 : DO imat = 1, imatSize
136 : DO iBand = 1, nBands
137 :
138 : IF(l_intersite) THEN
139 : imSym = ImagUnit**(l-lp)/REAL(sym%nop) * symMMPmat(im(:,:,iBand,imat),sym,natom,l,lp=lp,phase=(spin_ind.EQ.3),&
140 : bk=kpts%bk(:,ikpt),atomDiff=atomDiff,&
141 : taualdiff=atoms%taual(:,natom) - atoms%taual(:,natomp),sym_op_list=[iop])
142 : ELSE
143 : imSym = ImagUnit**(l-lp)/atoms%neq(atomType) * symMMPmat(im(:,:,iBand,imat),sym,natom,l,lp=lp,phase=(spin_ind.EQ.3))
144 : ENDIF
145 :
146 : !Rotate into the local real frame
147 : IF(noco%l_noco) THEN
148 : IF (.NOT.l_intersite) THEN
149 : imSym = rotMMPmat(imSym,nococonv%alph(atomType),nococonv%beta(atomType),0.0,l,lp=lp,inverse=.TRUE.)
150 : ENDIF
151 : ELSE IF(noco%l_soc) THEN
152 : imSym = rotMMPmat(imSym,nococonv%phi,nococonv%theta,0.0,l,lp=lp,inverse=.TRUE.)
153 : ENDIF
154 :
155 : #ifndef CPP_NOTYPEPROCINOMP
156 : !$omp critical
157 : CALL greensfBZintCoeffs%add_contribution(i_elem, i_elemLO, iBand, nLO, imat, l_sphavg, imSym)
158 : !$omp end critical
159 : #else
160 : CALL greensfBZintCoeffs%add_contribution(i_elem, i_elemLO, iBand, nLO, imat, l_sphavg, imSym)
161 : #endif
162 : ENDDO
163 : ENDDO
164 : #ifndef CPP_NOTYPEPROCINOMP
165 : !$omp end do
166 : DEALLOCATE(imSym)
167 : !$omp end parallel
168 : #else
169 : DEALLOCATE(imSym)
170 : #endif
171 :
172 : ENDDO
173 : ENDDO !natom
174 10620 : DEALLOCATE(im)
175 : ENDDO !i_gf
176 456 : CALL timestop("Green's Function: Brillouin-Zone-Integration")
177 :
178 :
179 912 : END SUBROUTINE greensfBZint
180 :
181 : END MODULE m_greensfBZint
|