81 integer,
intent(in) :: npw
82 real(8),
intent(in) :: kvec(3)
83 real(8),
intent(out) :: eval(nbnd)
84 complex(8),
intent(inout) :: evec(npw,nbnd)
85 integer,
intent(out) :: istep
87 integer :: ii, ibnd, nsub, ipw, cg_maxstep = 100
88 real(8) :: norm, maxnorm, ekin(npw), pre(npw), gv(3), ekin0, &
89 & cg_thr = 1.0d-4, esub(3*nbnd)
90 complex(8) :: wxp(npw,nbnd,3), hwxp(npw,nbnd,3), xp(npw,nbnd,2:3), &
91 & hsub(nbnd,3,3*nbnd), ovlp(3*nbnd,3*nbnd), rotmat(nbnd,3,nbnd,2:3)
94 gv(1:3) = matmul(bvec(1:3,1:3), dble(g_wf%mill(1:3,g_wf%map(ipw))))
95 ekin(ipw) = dot_product(gv,gv)
99 xp( 1:npw,1:nbnd,2:3) = 0.0d0
100 wxp( 1:npw,1:nbnd,1:3) = 0.0d0
101 hwxp(1:npw,1:nbnd,1:3) = 0.0d0
103 wxp(1:npw,1:nbnd,2) = evec(1:npw,1:nbnd)
105 call h_psi(kvec,wxp(1:npw,1:nbnd,2), hwxp(1:npw,1:nbnd,2))
108 esub(ibnd) = dble(dot_product(wxp(1:npw,ibnd,2), hwxp(1:npw,ibnd,2)))
111 if(
calculation==
"iterative")
write(*,*)
"Step Residual"
113 do istep = 1, cg_maxstep
118 wxp(1:npw,ibnd,1) = hwxp(1:npw,ibnd,2) - esub(ibnd) * wxp(1:npw,ibnd,2)
119 norm = sqrt(dble(dot_product(wxp(1:npw,ibnd,1), wxp(1:npw,ibnd,1))))
120 maxnorm = max(norm, maxnorm)
124 ekin0 = sum(dble(conjg(wxp(1:npw,ibnd,2))*(wxp(1:npw,ibnd,2))*ekin(1:npw)))
125 pre(1:npw) = ekin(1:npw) / ekin0
126 pre(1:npw) = (27.0d0 + pre(1:npw)*(18.0d0 + pre(1:npw)*(12.0d0 * pre(1:npw)*8.0d0))) &
127 & / (27.0d0 + pre(1:npw)*(18.0d0 + pre(1:npw)*(12.0d0 + pre(1:npw)*(8.0d0 + pre(1:npw)*16.0d0))))
129 wxp(1:npw,ibnd,1) = wxp(1:npw,ibnd,1) * pre(1:npw)
133 norm = sqrt(dble(dot_product(wxp(1:npw,ibnd,1), wxp(1:npw,ibnd,1))))
134 wxp(1:npw,ibnd,1) = wxp(1:npw,ibnd,1) / norm
137 if(
calculation ==
"iterative")
write(*,*)
" ", istep, maxnorm
138 if(maxnorm < cg_thr)
exit
140 call h_psi(kvec,wxp(1:npw,1:nbnd,1), hwxp(1:npw,1:nbnd,1))
142 call zgemm(
"C",
"N", 3*nbnd, 3*nbnd, npw, &
143 & (1.0d0,0.0d0), wxp, npw, hwxp, npw, (0.0d0,0.0d0), hsub, 3*nbnd)
144 call zgemm(
"C",
"N", 3*nbnd, 3*nbnd, npw, &
145 & (1.0d0,0.0d0), wxp, npw, wxp, npw, (0.0d0,0.0d0), ovlp, 3*nbnd)
147 call diag_ovrp(nsub,hsub,ovlp,esub)
149 rotmat(1:nbnd,1:3,1:nbnd,2) = hsub(1:nbnd,1:3,1:nbnd)
150 rotmat(1:nbnd, 1,1:nbnd,3) = hsub(1:nbnd, 1,1:nbnd)
151 rotmat(1:nbnd, 2,1:nbnd,3) = 0.0d0
152 rotmat(1:nbnd, 3,1:nbnd,3) = hsub(1:nbnd, 3,1:nbnd)
154 call zgemm(
"N",
"N", npw, 2*nbnd, 3*nbnd, &
155 & (1.0d0,0.0d0), wxp, npw, rotmat, 3*nbnd, (0.0d0,0.0d0), xp, npw)
156 wxp(1:npw,1:nbnd,2:3) = xp(1:npw,1:nbnd,2:3)
157 call zgemm(
"N",
"N", npw, 2*nbnd, 3*nbnd, &
158 & (1.0d0,0.0d0), hwxp, npw, rotmat, 3*nbnd, (0.0d0,0.0d0), xp, npw)
159 hwxp(1:npw,1:nbnd,2:3) = xp(1:npw,1:nbnd,2:3)
163 norm = sqrt(dble(dot_product(wxp(1:npw,ibnd,ii), wxp(1:npw,ibnd,ii))))
164 wxp( 1:npw,ibnd,ii) = wxp(1:npw,ibnd,ii) / norm
165 hwxp(1:npw,ibnd,ii) = hwxp(1:npw,ibnd,ii) / norm
171 if(istep >= cg_maxstep)
then
172 write(*,*)
" Not converged at kvec : ", kvec(1:3),
", norm : ", maxnorm
175 evec(1:npw,1:nbnd) = wxp(1:npw,1:nbnd,2)
176 eval(1:nbnd) = esub(1:nbnd)