16 integer,
parameter ::
dp = kind(1.0d0)
21 character(20) :: kerneltype
24 integer :: verbose, nrank
27 real(
dp) :: scalecoeff
41 type(
xlk_type),
intent(inout) :: input
42 integer,
parameter :: nkey_char = 1, nkey_int = 2, nkey_re = 1, nkey_log = 1
43 character(len=*) :: filename
46 character(len=50),
parameter :: keyvector_char(nkey_char) = [character(len=100) :: &
48 character(len=100) :: valvector_char(nkey_char) = [character(len=100) :: &
51 character(len=50),
parameter :: keyvector_int(nkey_int) = [character(len=50) :: &
53 integer :: valvector_int(nkey_int) = (/ &
56 character(len=50),
parameter :: keyvector_re(nkey_re) = [character(len=50) :: &
58 real(
dp) :: valvector_re(nkey_re) = (/&
61 character(len=50),
parameter :: keyvector_log(nkey_log) = [character(len=100) :: &
63 logical :: valvector_log(nkey_log) = (/&
67 character(len=50),
parameter :: startstop(2) = [character(len=50) :: &
71 ,keyvector_int,valvector_int,keyvector_re,valvector_re,&
72 keyvector_log,valvector_log,trim(filename),startstop)
75 input%kerneltype = valvector_char(1)
78 input%verbose = valvector_int(1)
79 input%nrank = valvector_int(2)
84 input%scalecoeff = valvector_re(1)
88 subroutine prg_fermi(D0,QQ,ee,gap,Fe_vec,mu0,H,Z,Nocc,T,OccErrLim,MaxIt,HDIM)
90 integer,
parameter :: prec = 8
91 integer(PREC),
intent(in) :: hdim, nocc
92 real(prec),
parameter :: one = 1.d0, two = 2.d0, zero = 0.d0
93 real(prec),
parameter :: kb = 8.61739d-5
94 real(prec),
intent(in) :: h(hdim,hdim), z(hdim,hdim)
95 real(prec) :: h0(hdim,hdim), fe(hdim,hdim)
96 real(prec),
intent(out) :: d0(hdim,hdim), qq(hdim,hdim), ee(hdim), fe_vec(hdim), gap
97 real(prec) :: x(hdim,hdim)
98 real(prec),
intent(in) :: t, occerrlim
99 real(prec),
intent(inout) :: mu0
100 integer(PREC),
intent(in) :: maxit
101 real(prec) :: occerr, occ, docc, mu_0, beta, occ_i
102 integer(PREC) :: i,iter
105 call prg_mmult(one,z,h,zero,x,
'T',
'N',hdim)
106 call prg_mmult(one,x,z,zero,h0,
'N',
'N',hdim)
107 call eig(h0,qq,ee,
'V',hdim)
113 gap = ee(nocc+1)-ee(nocc)
114 if (mu0 == 0.d0)
then
115 mu0 = 0.5d0*(ee(nocc)+ee(nocc+1))
118 do while (occerr > 1e-9)
123 occ_i = one/(exp(beta*(ee(i)-mu0))+one)
127 docc = docc + beta*occ_i*(one-occ_i)
129 occerr = abs(nocc-occ)
130 if (abs(occerr) > 1e-9)
then
131 mu0 = mu0 + (nocc-occ)/docc
133 if(iter.gt.maxit)
then
137 call prg_mmult(one,qq,fe,zero,x,
'N',
'N',hdim)
138 call prg_mmult(one,x,qq,zero,d0,
'N',
'T',hdim)
142 subroutine prg_kernel_fermi_full(KK,JJ,D0,mu0,mu1,T,RX,RY,RZ,LBox,Hubbard_U,Element_Type,Nr_atoms, &
143 MaxIt,eps, m,HDIM, Max_Nr_Neigh,Coulomb_acc,TIMERATIO,nnRx,nnRy,nnRz,nrnnlist,nnType,H_INDEX_START, &
144 H_INDEX_END,H,S,Z,Nocc,Znuc,QQ,ee,Fe_vec)
146 integer,
parameter :: prec = 8
147 integer(PREC),
intent(in) :: nr_atoms, hdim, nocc,max_nr_neigh
148 real(prec),
parameter :: one = 1.d0, two = 2.d0, zero = 0.d0
149 real(prec),
parameter :: kb = 8.61739d-5
150 real(prec),
intent(in) :: coulomb_acc, timeratio
151 real(prec) :: v(nr_atoms)
152 real(prec),
intent(in) :: rx(nr_atoms), ry(nr_atoms), rz(nr_atoms), lbox(3)
153 integer(PREC),
intent(in) :: h_index_start(nr_atoms), h_index_end(nr_atoms)
154 real(prec),
intent(in) :: znuc(nr_atoms), hubbard_u(nr_atoms)
155 real(prec),
intent(in) :: h(hdim,hdim), s(hdim,hdim), z(hdim,hdim)
156 real(prec) :: h0(hdim,hdim), h1(hdim,hdim)
157 real(prec),
intent(inout) :: d0(hdim,hdim)
158 real(prec) :: x(hdim,hdim), xx(nr_atoms,nr_atoms)
159 real(prec),
intent(in) :: t, eps
160 real(prec),
intent(inout) :: mu0, mu1
161 integer(PREC),
intent(in) :: m, maxit
162 character(10),
intent(in) :: element_type(nr_atoms)
163 integer(PREC),
intent(in) :: nrnnlist(nr_atoms), nntype(nr_atoms,max_nr_neigh)
164 real(prec),
intent(in) :: nnrx(nr_atoms,max_nr_neigh)
165 real(prec),
intent(in) :: nnry(nr_atoms,max_nr_neigh), nnrz(nr_atoms,max_nr_neigh)
166 real(prec) :: coulomb_pot_real(nr_atoms), coulomb_pot(nr_atoms)
167 real(prec) :: coulomb_pot_real_i, coulomb_pot_k(nr_atoms)
168 real(prec) :: coulomb_pot_real_dq_v(nr_atoms), coulomb_pot_dq_v(nr_atoms)
169 real(prec) :: coulomb_force_real_i(3),coulomb_force_k(3,nr_atoms)
170 real(prec) :: d_dq_v(hdim,hdim), h_dq_v(hdim,hdim), dq_v(nr_atoms)
171 real(prec) :: dq_dv(nr_atoms)
172 real(prec),
intent(out) :: kk(nr_atoms,nr_atoms),jj(nr_atoms,nr_atoms)
173 real(prec),
intent(in) :: qq(hdim,hdim), ee(hdim), fe_vec(hdim)
174 integer(PREC) :: i,j,k, iter, mm
179 coulomb_pot_dq_v = zero
187 call ewald_real_space(coulomb_pot_real_i,coulomb_force_real_i,i,rx,ry,rz,lbox, &
188 dq_v,hubbard_u,element_type,nr_atoms,coulomb_acc,timeratio,nnrx,nnry,nnrz,nrnnlist,nntype,hdim,max_nr_neigh)
189 coulomb_pot_real(i) = coulomb_pot_real_i
191 call ewald_k_space(coulomb_pot_k,coulomb_force_k,rx,ry,rz,lbox,dq_v,nr_atoms,coulomb_acc,timeratio,hdim,max_nr_neigh)
192 coulomb_pot_dq_v = coulomb_pot_real+coulomb_pot_k
196 do k = h_index_start(i),h_index_end(i)
197 h_dq_v(k,k) = hubbard_u(i)*dq_v(i) + coulomb_pot_dq_v(i)
200 call prg_mmult(one,s,h_dq_v,zero,x,
'N',
'N',hdim)
201 call prg_mmult(one,h_dq_v,s,one,x,
'N',
'T',hdim)
204 call prg_mmult(one,z,h,zero,x,
'T',
'N',hdim)
205 call prg_mmult(one,x,z,zero,h0,
'N',
'N',hdim)
207 call prg_mmult(one,z,h_dq_v,zero,x,
'T',
'N',hdim)
208 call prg_mmult(one,x,z,zero,h1,
'N',
'N',hdim)
210 call get_deriv_finite_temp(d_dq_v,h0,h1,nocc,t,qq,ee,fe_vec,mu0,eps,hdim)
212 call prg_mmult(two,z,d_dq_v,zero,x,
'N',
'N',hdim)
213 call prg_mmult(one,x,z,zero,d_dq_v,
'N',
'T',hdim)
215 call prg_mmult(one,d_dq_v,s,zero,x,
'N',
'N',hdim)
218 do k = h_index_start(i), h_index_end(i)
219 dq_dv(i) = dq_dv(i) + x(k,k)
227 xx(i,i) = xx(i,i) - one
229 call inv(xx,kk,nr_atoms)
233 subroutine prg_v_kernel_fermi(D0,dq_dv,v,mu0,mu1,T,RX,RY,RZ,LBox,Hubbard_U,Element_Type,Nr_atoms, &
234 MaxIt,eps, m,HDIM, Max_Nr_Neigh,Coulomb_acc,TIMERATIO,nnRx,nnRy,nnRz,nrnnlist,nnType,H_INDEX_START, &
235 H_INDEX_END,H,S,Z,Nocc,Znuc,QQ,ee,Fe_vec)
237 integer,
parameter :: prec = 8
238 integer(PREC),
intent(in) :: nr_atoms, hdim, nocc,max_nr_neigh
239 real(prec),
parameter :: one = 1.d0, two = 2.d0, zero = 0.d0
240 real(prec),
parameter :: kb = 8.61739d-5
241 real(prec),
intent(in) :: coulomb_acc, timeratio, v(nr_atoms)
242 real(prec),
intent(in) :: rx(nr_atoms), ry(nr_atoms), rz(nr_atoms), lbox(3)
243 integer(PREC),
intent(in) :: h_index_start(nr_atoms), h_index_end(nr_atoms)
244 real(prec),
intent(in) :: znuc(nr_atoms), hubbard_u(nr_atoms)
245 real(prec),
intent(in) :: h(hdim,hdim), s(hdim,hdim), z(hdim,hdim)
246 real(prec) :: h0(hdim,hdim), h1(hdim,hdim)
247 real(prec),
intent(inout) :: d0(hdim,hdim)
248 real(prec) :: x(hdim,hdim)
249 real(prec),
intent(in) :: t, eps
250 real(prec),
intent(inout) :: mu0, mu1
251 integer(PREC),
intent(in) :: m, maxit
252 character(10),
intent(in) :: element_type(nr_atoms)
253 integer(PREC),
intent(in) :: nrnnlist(nr_atoms), nntype(nr_atoms,max_nr_neigh)
254 real(prec),
intent(in) :: nnrx(nr_atoms,max_nr_neigh)
255 real(prec),
intent(in) :: nnry(nr_atoms,max_nr_neigh), nnrz(nr_atoms,max_nr_neigh)
256 real(prec) :: coulomb_pot_real(nr_atoms), coulomb_pot(nr_atoms)
257 real(prec) :: coulomb_pot_real_i, coulomb_pot_k(nr_atoms)
258 real(prec) :: coulomb_pot_real_dq_v(nr_atoms), coulomb_pot_dq_v(nr_atoms)
259 real(prec) :: coulomb_force_real_i(3),coulomb_force_k(3,nr_atoms)
260 real(prec) :: d_dq_v(hdim,hdim), h_dq_v(hdim,hdim), dq_v(nr_atoms)
261 real(prec),
intent(out) :: dq_dv(nr_atoms)
262 real(prec),
intent(in) :: qq(hdim,hdim), ee(hdim), fe_vec(hdim)
263 integer(PREC) :: i,j,k, iter, mm
269 call ewald_real_space(coulomb_pot_real_i,coulomb_force_real_i,i,rx,ry,rz,lbox, &
270 dq_v,hubbard_u,element_type,nr_atoms,coulomb_acc,timeratio,nnrx,nnry,nnrz,nrnnlist,nntype,hdim,max_nr_neigh)
271 coulomb_pot_real(i) = coulomb_pot_real_i
273 call ewald_k_space(coulomb_pot_k,coulomb_force_k,rx,ry,rz,lbox,dq_v,nr_atoms,coulomb_acc,timeratio,hdim,max_nr_neigh)
274 coulomb_pot_dq_v = coulomb_pot_real+coulomb_pot_k
278 do k = h_index_start(i),h_index_end(i)
279 h_dq_v(k,k) = hubbard_u(i)*dq_v(i) + coulomb_pot_dq_v(i)
282 call prg_mmult(one,s,h_dq_v,zero,x,
'N',
'N',hdim)
283 call prg_mmult(one,h_dq_v,s,one,x,
'N',
'T',hdim)
286 call prg_mmult(one,z,h,zero,x,
'T',
'N',hdim)
287 call prg_mmult(one,x,z,zero,h0,
'N',
'N',hdim)
289 call prg_mmult(one,z,h_dq_v,zero,x,
'T',
'N',hdim)
290 call prg_mmult(one,x,z,zero,h1,
'N',
'N',hdim)
292 call get_deriv_finite_temp(d_dq_v,h0,h1,nocc,t,qq,ee,fe_vec,mu0,eps,hdim)
294 call prg_mmult(two,z,d_dq_v,zero,x,
'N',
'N',hdim)
295 call prg_mmult(one,x,z,zero,d_dq_v,
'N',
'T',hdim)
297 call prg_mmult(one,d_dq_v,s,zero,x,
'N',
'N',hdim)
299 do k = h_index_start(i), h_index_end(i)
300 dq_dv(i) = dq_dv(i) + x(k,k)
306 subroutine prg_get_deriv_finite_temp(P1,H0,H1,Nocc,T,Q,ev,fe,mu0,eps,HDIM)
308 integer,
parameter :: prec = 8
309 integer(PREC),
intent(in) :: hdim, nocc
310 real(prec),
parameter :: one = 1.d0, zero = 0.d0, two = 2.d0
311 real(prec),
intent(in) :: h0(hdim,hdim), h1(hdim,hdim), q(hdim,hdim), ev(hdim), fe(hdim)
312 real(prec) :: x(hdim,hdim), yy(hdim,hdim), fermifun
313 real(prec) :: p02(hdim,hdim), ii(hdim,hdim), xi(hdim,hdim)
314 real(prec) :: dx1(hdim,hdim)
315 real(prec) :: id0(hdim,hdim), t12(hdim,hdim), ddt(hdim,hdim)
316 real(prec),
intent(out) :: p1(hdim,hdim)
317 real(prec),
intent(in) :: t, eps
318 real(prec),
intent(inout) :: mu0
319 real(prec) :: occerr, trdpdmu, trp0, trp1
320 real(prec) :: beta, cnst, kb, mu1, dh, dm, y, dy, trx, trddt
321 integer(PREC) :: n, cnt, i, j, k,l, ind, ind2, fact
328 call prg_mmult(one,q,h1,zero,x,
'T',
'N',hdim)
329 call prg_mmult(one,x,q,zero,t12,
'N',
'N',hdim)
336 if (abs(ev(i)-ev(j)) < 1e-4)
then
338 y = (ev(i)+ev(j))/2.d0
339 if (abs(beta*(y-mu0)) > 500.d0)
then
342 ddt(i,j) = -beta*exp(beta*(y-mu0))/(exp(beta*(y-mu0))+1.d0)**2
345 ddt(i,j) = (fe(i)-fe(j))/(ev(i)-ev(j))
347 x(i,j) = ddt(i,j)*t12(i,j)
355 trddt = trddt + ddt(i,i)
359 x(i,i) = x(i,i)-ddt(i,i)*mu1
361 call prg_mmult(one,q,x,zero,yy,
'N',
'N',hdim)
362 call prg_mmult(one,yy,q,zero,p1,
'N',
'T',hdim)
368 integer,
parameter :: prec = 8
369 integer(PREC),
intent(in) :: hdim
370 real(prec),
intent(in) :: a(hdim,hdim), b(hdim,hdim), alpha, beta
371 real(prec),
intent(inout) :: c(hdim,hdim)
372 character(1),
intent(in) :: ta, tb
375 call sgemm(ta, tb, hdim, hdim, hdim, alpha, &
376 a, hdim, b, hdim, beta, c, hdim)
378 call dgemm(ta, tb, hdim, hdim, hdim, alpha, &
379 a, hdim, b, hdim, beta, c, hdim)
386 integer,
parameter :: prec = 8
387 integer(PREC),
intent(in) :: hdim
388 real(prec),
intent(in) :: a(hdim,hdim)
389 real(prec),
intent(out) :: q(hdim,hdim), ee(hdim)
390 character(1),
intent(in) ::
type
392 real(prec) :: nono_evals(hdim), nono_work(1 + 6*hdim + 2*hdim*hdim)
393 real(prec) :: nonotmp(hdim,hdim), z(hdim,hdim)
394 integer(PREC) :: nono_iwork(3+5*hdim)
395 integer(PREC) :: i, j, info, nono_lwork
396 real(prec) :: invsqrt,err_check,numthresh
398 nono_lwork = 1 + 6*hdim + 2*hdim*hdim
402 call ssyev(
type,
'U', hdim, q, hdim, ee, nono_work, &
405 call dsyev(
'V',
'U', hdim, q, hdim, ee, nono_work, &
413 integer,
parameter :: prec = 8
414 integer(PREC),
intent(in) :: hdim
415 integer(PREC) :: lda, lwork, m, n, info, ipiv(hdim)
416 real(prec),
intent(in) :: x(hdim,hdim)
417 real(prec),
intent(out) :: xi(hdim,hdim)
418 real(prec) :: work(hdim*hdim)
427 call sgetrf(m, n, xi, lda, ipiv, info)
428 call sgetri(n, xi, n, ipiv, work, lwork, info)
430 call dgetrf(m, n, xi, lda, ipiv, info)
431 call dgetri(n, xi, n, ipiv, work, lwork, info)
441 integer :: i,j,info,s,k,n
442 integer :: nint, na, nb
443 integer,
intent(in) :: verbose
444 real(
dp),
allocatable :: d(:),dl(:),dnewin(:)
445 real(
dp),
allocatable :: dnewout(:)
446 real(
dp),
allocatable :: coef(:,:),b(:),ipiv(:)
448 write(*,*)
"prt_rank1 Verbosity",verbose
Some general parsing functions.
subroutine, public prg_parsing_kernel(keyvector_char, valvector_char, keyvector_int, valvector_int, keyvector_re, valvector_re, keyvector_log, valvector_log, filename, startstop)
The general parsing function. It is used to vectorize a set of "keywords" "value" pairs as included i...
subroutine, public prg_parse_xlkernel(input, filename)
The parser for the mixer routines.
subroutine, public prg_v_kernel_fermi(D0, dq_dv, v, mu0, mu1, T, RX, RY, RZ, LBox, Hubbard_U, Element_Type, Nr_atoms, MaxIt, eps, m, HDIM, Max_Nr_Neigh, Coulomb_acc, TIMERATIO, nnRx, nnRy, nnRz, nrnnlist, nnType, H_INDEX_START, H_INDEX_END, H, S, Z, Nocc, Znuc, QQ, ee, Fe_vec)
subroutine, private prg_eig(A, Q, ee, type, HDIM)
subroutine, private prg_mmult(alpha, A, B, beta, C, TA, TB, HDIM)
subroutine, public prg_kernel_fermi_full(KK, JJ, D0, mu0, mu1, T, RX, RY, RZ, LBox, Hubbard_U, Element_Type, Nr_atoms, MaxIt, eps, m, HDIM, Max_Nr_Neigh, Coulomb_acc, TIMERATIO, nnRx, nnRy, nnRz, nrnnlist, nnType, H_INDEX_START, H_INDEX_END, H, S, Z, Nocc, Znuc, QQ, ee, Fe_vec)
subroutine, private prg_inv(X, XI, HDIM)
subroutine, public prg_rank1(verbose)
Rank1 kernel ....
subroutine, private prg_get_deriv_finite_temp(P1, H0, H1, Nocc, T, Q, ev, fe, mu0, eps, HDIM)
subroutine, public prg_fermi(D0, QQ, ee, gap, Fe_vec, mu0, H, Z, Nocc, T, OccErrLim, MaxIt, HDIM)