23 integer,
parameter ::
dp = kind(1.0d0)
24 real(
dp),
parameter ::
pi = 3.14159265358979323846264338327950_dp
29 character(100) :: flavor
30 character(100) :: bml_type, jobname
31 integer :: mdim, ncoeffs, ndim, verbose
33 real(
dp) :: atr, bndfil, ef, estep
34 real(
dp) :: fermitol, kbt, threshold
35 logical :: getef, jon, trkfunc
57 integer,
parameter :: nkey_char = 3, nkey_int = 5, nkey_re = 7, nkey_log = 3
58 character(len=*) :: filename
61 character(len=50),
parameter :: keyvector_char(nkey_char) = [character(len=50) :: &
62 'JobName=',
'BMLType=',
'Flavor=' ]
63 character(len=100) :: valvector_char(nkey_char) = [character(len=100) :: &
64 'MyJob' ,
'Dense' ,
'Alg1' ]
66 character(len=50),
parameter :: keyvector_int(nkey_int) = [character(len=50) :: &
67 'MDim=',
'NDim=',
'NCoeffs=',
'Verbose=',
'NPoints=']
68 integer :: valvector_int(nkey_int) = (/ &
69 -1 , 0 , 50 , 0, 500 /)
71 character(len=50),
parameter :: keyvector_re(nkey_re) = [character(len=50) :: &
72 'NumThresh=',
'FermiTol=',
'BndFil=',
'EStep=',
"ATr=",
"Kbt=",
"Ef=" ]
73 real(
dp) :: valvector_re(nkey_re) = (/&
74 0.0 , 0.00000001 ,0.0, 0.01, 0.0, 0.0, 0.0 /)
76 character(len=50),
parameter :: keyvector_log(nkey_log) = [character(len=50) :: &
77 'GetEf=',
'Jackson=',
'TRKFunction=']
78 logical :: valvector_log(nkey_log) = (/&
79 .false., .false., .false./)
82 character(len=50),
parameter :: startstop(2) = [character(len=50) :: &
86 ,keyvector_int,valvector_int,keyvector_re,valvector_re,&
87 keyvector_log,valvector_log,trim(filename),startstop)
90 chebdata%JobName = valvector_char(1)
92 if(valvector_char(2) ==
"Dense")
then
93 chebdata%bml_type = bml_matrix_dense
94 elseif(valvector_char(2) ==
"Ellpack")
then
95 chebdata%bml_type = bml_matrix_ellpack
97 chebdata%flavor = valvector_char(3)
100 chebdata%threshold = valvector_re(1)
101 chebdata%fermitol = valvector_re(2)
102 chebdata%bndfil = valvector_re(3)
103 chebdata%estep = valvector_re(4)
104 chebdata%atr = valvector_re(5)
105 chebdata%kbt = valvector_re(6)
106 chebdata%ef = valvector_re(7)
109 chebdata%getef = valvector_log(1)
110 chebdata%jon = valvector_log(2)
111 chebdata%trkfunc = valvector_log(3)
114 chebdata%mdim = valvector_int(1)
115 chebdata%ndim = valvector_int(2)
116 chebdata%ncoeffs = valvector_int(3)
117 chebdata%verbose = valvector_int(4)
118 chebdata%npts = valvector_int(5)
142 kbt, ef, bndfil, jon, verbose)
143 character(20) :: bml_type
144 integer :: npts, enpts, i, io
145 integer :: norb, mdim
146 integer,
intent(in) :: ncoeffs, verbose
147 real(
dp) :: alpha, de, maxder, mls_i
148 real(
dp) :: mycoeff, occ, scaledef, scaledkbt
149 real(
dp) :: threshold1
150 real(
dp),
allocatable :: coeffs(:), coeffs1(:), domain(:), domain0(:)
151 real(
dp),
allocatable :: domain2(:), gbnd(:), tn(:), tnm1(:)
152 real(
dp),
allocatable :: tnp1(:), tnp1_dense(:,:), tracest(:)
153 real(
dp),
intent(in) :: athr, bndfil, kbt, threshold
154 real(
dp),
intent(in) :: ef
155 type(bml_matrix_t) :: aux_bml, tn_bml, tnm1_bml, tnp1_bml
156 type(bml_matrix_t) :: x_bml
157 type(bml_matrix_t),
intent(in) :: ham_bml
158 type(bml_matrix_t),
intent(inout) :: rho_bml
159 logical,
intent(in) :: jon
161 if(verbose >= 1)
write(*,*)
"Building rho via Chebyshev expansion of the Fermi function ..."
163 norb = bml_get_n(ham_bml)
164 bml_type = bml_get_type(ham_bml)
166 if(verbose >= 1)mls_i =
mls()
167 call bml_copy_new(ham_bml,x_bml)
168 call bml_gershgorin(x_bml, gbnd)
170 if(verbose >= 1)
write(*,*)
"Time for gershgorin and normalize",
mls()-mls_i
172 enpts = floor((gbnd(2)-gbnd(1))/de)
175 allocate(domain0(enpts))
176 allocate(domain(enpts))
177 allocate(domain2(enpts))
180 allocate(tnp1(enpts))
181 allocate(tnm1(enpts))
183 allocate(tnp1_dense(norb,norb))
186 allocate(coeffs(ncoeffs))
187 allocate(coeffs1(ncoeffs))
188 allocate(tracest(ncoeffs))
192 if(verbose >= 1)mls_i =
mls()
194 if(verbose >= 1)
write(*,*)
"Time for prg_get_chebcoeffs",
mls()-mls_i
197 call bml_zero_matrix(bml_type,bml_element_real,
dp,norb,norb,tnp1_bml)
198 call bml_zero_matrix(bml_type,bml_element_real,
dp,norb,norb,tn_bml)
199 call bml_zero_matrix(bml_type,bml_element_real,
dp,norb,norb,tnm1_bml)
200 call bml_zero_matrix(bml_type,bml_element_real,
dp,norb,norb,aux_bml)
203 if(verbose >= 1)mls_i =
mls()
205 domain0(i) = gbnd(1) + i*de
206 domain0(i) = 2.0_dp*(domain0(i) - gbnd(1))/(gbnd(2)-gbnd(1)) - 1.0_dp
212 if(verbose >= 1)
write(*,*)
"Time for setting the tracking function",
mls()-mls_i
215 if(verbose >= 1)mls_i =
mls()
216 mycoeff =
jackson(ncoeffs,1,jon)*coeffs(1)
217 call bml_add_identity(tnm1_bml, 1.0_dp, threshold)
218 call bml_scale(mycoeff,tnm1_bml,aux_bml)
220 call bml_copy(x_bml,tn_bml)
221 call bml_add_deprecated(1.0_dp,aux_bml,mycoeff,tn_bml,threshold)
223 tracest(1) = bml_trace(tnm1_bml)
224 domain = 0.0_dp + mycoeff*tnm1
225 mycoeff =
jackson(ncoeffs,2,jon)*coeffs(2)
226 tracest(2) = bml_trace(tn_bml)
227 domain = domain + mycoeff*tn
230 if(verbose >= 1)
write(*,*)
"Chebyshev recursion ..."
233 mycoeff = coeffs(i+1)*
jackson(ncoeffs,i+1,jon)
235 call bml_copy(tnm1_bml,tnp1_bml)
238 threshold1 = threshold*(athr*real(i-1) + (1.0_dp-athr))
240 call bml_multiply(x_bml,tn_bml,tnp1_bml,2.0_dp,-1.0_dp,threshold1)
241 tracest(i+1) = bml_trace(tnp1_bml)
244 write(*,*)
"Time for mult",
mls()-mls_i
245 write(*,*)
"Coeff",abs(mycoeff)
246 write(*,*)
"Bandwidth of Tn, Threshold",bml_get_bandwidth(tnp1_bml),threshold1
247 write(*,*)
"Sparsity of Tn",bml_get_sparsity(tnp1_bml,threshold)
250 tnp1 = 2.0_dp*domain0*tn - tnp1
252 call bml_add_deprecated(1.0_dp,aux_bml,mycoeff,tnp1_bml,threshold)
253 domain = domain + mycoeff*tnp1
255 call bml_copy(tn_bml,tnm1_bml)
256 call bml_copy(tnp1_bml,tn_bml)
261 if(verbose >= 1)
write(*,*)
"Time for recursion",
mls()-mls_i
263 if(verbose >= 2)
then
265 write(io,*)
"# Energy, FApprox, Fermi"
267 write(io,*)gbnd(1) + i*de,domain(i),
fermi(gbnd(1) + i*de, ef, kbt)
271 if(verbose >= 2)
then
273 write(*,*)
"TargetKbt =",scaledkbt
274 write(*,*)
"AbsMaxDerivative =",maxder
275 write(*,*)
"kbT = 1/(4*AbsMaxDerivative) =",1.0_dp/(4.0_dp*maxder)
278 call bml_copy(aux_bml,rho_bml)
279 call bml_scale(2.0d0, rho_bml)
281 if(verbose >= 1)
write(*,*)
"TotalOccupation =", bml_trace(rho_bml)
308 kbt, ef, bndfil, getef, fermitol, jon, npts, trkfunc, verbose)
310 character(20) :: bml_type
311 integer :: npts, enpts, i, io
312 integer :: norb, mdim
313 integer,
intent(in) :: ncoeffs, verbose
314 real(
dp) :: alpha, de, maxder, mls_i, mls_r
315 real(
dp) :: mycoeff, occ, scaledef
316 real(
dp) :: threshold1, fermitol
317 real(
dp),
allocatable :: coeffs(:), coeffs1(:), domain(:), domain0(:)
318 real(
dp),
allocatable :: domain2(:), gbnd(:), tn(:), tnm1(:)
319 real(
dp),
allocatable :: tnp1(:), tnp1_dense(:,:), tracest(:)
320 real(
dp),
intent(in) :: athr, bndfil, kbt, threshold
321 real(
dp),
intent(out) :: ef
322 type(bml_matrix_t) :: aux_bml, tn_bml, tnm1_bml, tnp1_bml
323 type(bml_matrix_t) :: x_bml
324 type(bml_matrix_t),
intent(in) :: ham_bml
325 type(bml_matrix_t),
intent(inout) :: rho_bml
326 logical,
intent(in) :: getef, jon, trkfunc
328 if(verbose >= 1)
write(*,*)
"Building rho via Chebyshev expansion of the Fermi function ..."
331 norb = bml_get_n(ham_bml)
332 mdim = bml_get_m(ham_bml)
333 bml_type = bml_get_type(ham_bml)
334 mdim = bml_get_m(ham_bml)
335 if(verbose >= 1)mls_i =
mls()
336 call bml_copy_new(ham_bml,x_bml)
338 call bml_gershgorin(x_bml, gbnd)
339 if(verbose >= 1)
write(*,*)
"Estimation for emin, emax", gbnd(1), gbnd(2)
341 if(verbose >= 1)
write(*,*)
"Time for gershgorin and normalize",
mls()-mls_i
345 enpts = floor((gbnd(2)-gbnd(1))/de)
348 allocate(domain0(enpts))
349 allocate(domain(enpts))
350 allocate(domain2(enpts))
353 allocate(tnp1(enpts))
354 allocate(tnm1(enpts))
356 allocate(tnp1_dense(norb,norb))
360 allocate(coeffs(ncoeffs))
361 allocate(coeffs1(ncoeffs))
362 allocate(tracest(ncoeffs))
366 if(verbose >= 1)mls_i =
mls()
368 if(verbose >= 1)
write(*,*)
"Time for prg_get_chebcoeffs",
mls()-mls_i
371 call bml_zero_matrix(bml_type,bml_element_real,
dp,norb,mdim,tnp1_bml)
372 call bml_zero_matrix(bml_type,bml_element_real,
dp,norb,mdim,tn_bml)
373 call bml_zero_matrix(bml_type,bml_element_real,
dp,norb,mdim,tnm1_bml)
374 call bml_zero_matrix(bml_type,bml_element_real,
dp,norb,mdim,aux_bml)
380 domain0(i) = gbnd(1) + i*de
381 domain0(i) = 2.0_dp*(domain0(i) - gbnd(1))/(gbnd(2)-gbnd(1)) - 1.0_dp
387 write(*,*)
"Time for setting the tracking function",
mls()-mls_i
391 if(verbose >= 1)
write(*,*)
"Computing Ef ..."
393 if(verbose >= 1)mls_i =
mls()
394 call bml_add_identity(tnm1_bml, 1.0_dp, threshold)
396 call bml_copy(x_bml,tn_bml)
397 tracest(2) = bml_trace(tn_bml)
399 call bml_copy(tnm1_bml,tnp1_bml)
400 threshold1 = threshold*(athr*real(i-1) + (1.0_dp-athr))
401 call bml_multiply(x_bml,tn_bml,tnp1_bml,2.0_dp,-1.0_dp,threshold1)
402 tracest(i+1) = bml_trace(tnp1_bml)
403 call bml_copy(tn_bml,tnm1_bml)
404 call bml_copy(tnp1_bml,tn_bml)
406 if(verbose >= 1)
write(*,*)
"Time for computing traces",
mls()-mls_i
409 call bml_deallocate(tnp1_bml)
410 call bml_deallocate(tn_bml)
411 call bml_deallocate(tnm1_bml)
412 call bml_zero_matrix(bml_type,bml_element_real,
dp,norb,mdim,tnp1_bml)
413 call bml_zero_matrix(bml_type,bml_element_real,
dp,norb,mdim,tn_bml)
414 call bml_zero_matrix(bml_type,bml_element_real,
dp,norb,mdim,tnm1_bml)
418 gbnd(2),bndfil,norb,fermitol,jon,verbose)
419 if(verbose >= 1)
write(*,*)
"Time for prg_get_chebcoeffs_fermi_nt",
mls()-mls_i
420 if(verbose >= 1)
write(*,*)
"Converged Ef",ef
425 if(verbose >= 1)mls_r =
mls()
426 mycoeff =
jackson(ncoeffs,1,jon)*coeffs(1)
427 call bml_add_identity(tnm1_bml, 1.0_dp, threshold)
428 call bml_scale(mycoeff,tnm1_bml,aux_bml)
430 tracest(1) = bml_trace(tnm1_bml)
431 domain = 0.0_dp + mycoeff*tnm1
435 mycoeff =
jackson(ncoeffs,2,jon)*coeffs(2)
436 call bml_copy(x_bml,tn_bml)
437 call bml_add_deprecated(1.0_dp,aux_bml,mycoeff,tn_bml,threshold)
439 tracest(2) = bml_trace(tn_bml)
440 domain = domain + mycoeff*tn
444 if(verbose >= 1)
write(*,*)
"Chebyshev recursion ..."
447 mycoeff = coeffs(i+1)*
jackson(ncoeffs,i+1,jon)
449 call bml_copy(tnm1_bml,tnp1_bml)
450 if(trkfunc)tnp1 = tnm1
452 if(verbose >= 4)mls_i =
mls()
453 threshold1 = threshold*(athr*real(i-1) + (1.0_dp-athr))
455 call bml_multiply(x_bml,tn_bml,tnp1_bml,2.0_dp,-1.0_dp,threshold1)
456 tracest(i+1) = bml_trace(tnp1_bml)
459 write(*,*)
"Time for mult",
mls()-mls_i
460 write(*,*)
"Coeff",i,abs(mycoeff)
461 write(*,*)
"Bandwidth of Tn, Threshold",bml_get_bandwidth(tnp1_bml),threshold1
462 write(*,*)
"Sparsity of Tn",bml_get_sparsity(tnp1_bml,threshold)
465 if(trkfunc)tnp1 = 2.0_dp*domain0*tn - tnp1
467 call bml_add_deprecated(1.0_dp,aux_bml,mycoeff,tnp1_bml,threshold)
468 if(trkfunc)domain = domain + mycoeff*tnp1
470 call bml_copy(tn_bml,tnm1_bml)
471 call bml_copy(tnp1_bml,tn_bml)
478 occ = 2.0_dp*bml_trace(aux_bml)
479 if(verbose >= 1)
write(*,*)
"Step, Occupation",i,occ
480 write(*,*)
"Time for", i,
"recursion",
mls()-mls_i
483 if(verbose >= 1)
write(*,*)
"Time for recursion",
mls()-mls_r
487 write(io,*)
"# Energy, FApprox, Fermi"
489 write(io,*)gbnd(1) + i*de,domain(i),
fermi(gbnd(1) + i*de, ef, kbt)
494 if(verbose >= 2)
then
496 write(*,*)
"TargetKbt =",kbt
497 write(*,*)
"AbsMaxDerivative =",maxder
498 write(*,*)
"Actual Kbt = 1/(4*AbsMaxDerivative) =",1.0_dp/(4.0_dp*maxder)
501 call bml_copy(aux_bml,rho_bml)
502 call bml_scale(2.0d0, rho_bml)
504 if(verbose >= 1)
write(*,*)
"TotalOccupation =", bml_trace(rho_bml)
513 deallocate(tnp1_dense)
519 call bml_deallocate(tnp1_bml)
520 call bml_deallocate(tn_bml)
521 call bml_deallocate(tnm1_bml)
522 call bml_deallocate(aux_bml)
523 call bml_deallocate(x_bml)
533 integer,
intent(in) :: ncoeffs,i
534 logical,
intent(in) :: jon
542 jackson = real(ncoeffs)*cos(
pi/(real(ncoeffs+1))) &
543 + sin(
pi/(real(ncoeffs+1)))*1.0_dp/tan(
pi/(real(ncoeffs+1)))
548 jackson = real(ncoeffs - i + 1)*cos(
pi*i/(real(ncoeffs+1))) &
549 + sin(
pi*i/(real(ncoeffs+1)))*1.0_dp/tan(
pi/(real(ncoeffs+1)))
570 integer,
intent(in) :: ncoeffs, npts
571 real(dp) :: Int, Kr, Kr0, x
573 real(dp),
intent(in) :: ef, emax, emin, kbt
574 real(dp),
intent(inout) :: coeffs(:)
577 kr = 0.5_dp*real(npts+1.0d0)
578 kr0 = real(npts+1.0d0)
589 xj = cos((j+0.5_dp)*
pi/(npts + 1))
590 x = (emax-emin)*(xj + 1.0d0)/2.0d0 + emin
591 int = int +
tr(i,xj)*
fermi(x,ef,kbt)
595 coeffs(i+1) = int/kr0
619 emax,bndfil,norb,tol,jon,verbose)
622 integer,
intent(in) :: ncoeffs, norb, verbose, npts
623 real(dp) :: f1, f2, nel
624 real(dp) :: prod, step
625 real(dp),
intent(in) :: bndfil, emax, emin, kbt
626 real(dp),
intent(in) :: tol, tracesT(:)
627 real(dp),
intent(inout) :: coeffs(:), ef
628 logical,
intent(in) :: jon
630 nel = bndfil*2.0_dp*real(norb,dp)
637 if(verbose >= 1)
write(*,*)
"In prg_get_chebcoeffs_fermi ..."
641 f1 = f1 + 2.0_dp*
jackson(ncoeffs,i,jon)*coeffs(i)*tracest(i)
648 stop
"Bisection method in prg_get_chebcoeffs_fermi is not converging ..."
651 if(verbose >= 2)
write(*,*)
"ef,f(ef)",ef,f1
652 if(abs(f1).lt.tol)
then
662 f2 = f2 + 2.0_dp*
jackson(ncoeffs,i,jon)*coeffs(i)*tracest(i)
696 ,bndfil,norb,tol,jon,verbose)
699 integer,
intent(in) :: ncoeffs, norb, verbose, npts
700 real(dp) :: ef0, f1, f2, nel
702 real(dp),
intent(in) :: bndfil, emax, emin, kbt
703 real(dp),
intent(in) :: tol, tracesT(:)
704 real(dp),
intent(inout) :: coeffs(:), ef
705 logical,
intent(in) :: jon
707 nel = bndfil*2.0_dp*real(norb,dp)
713 if(verbose >= 1)
write(*,*)
"In prg_get_chebcoeffs_fermi_nt ..."
720 f1 = f1 + 2.0_dp*
jackson(ncoeffs,i,jon)*coeffs(i)*tracest(i)
733 f2 = f2 + 2.0_dp*
jackson(ncoeffs,i,jon)*coeffs(i)*tracest(i)
739 ef = -f2*step/(f2-f1) + ef0
745 stop
"Newton method in prg_get_chebcoeffs_fermi_nt is not converging ..."
755 f2 = f2 + 2.0_dp*
jackson(ncoeffs,i,jon)*coeffs(i)*tracest(i)
760 if(verbose >= 2)
write(*,*)
"ef,f(ef)",ef,f2
762 ef = -f2*step/(f2-f1) + ef0
765 if(abs(f1).lt.tol)
then
778 real(
dp),
intent(in) :: x
779 integer,
intent(in) :: r
791 real(
dp),
intent(in) :: e, ef, kbt
793 fermi = 1.0_dp/(1.0_dp+exp((e-ef)/(kbt)))
803 real(
dp),
intent(in) :: func(:), de
808 do j=1,
size(func, dim=1)-1
Module to obtain the density matrix by applying a Chebyshev polynomial expansion.
subroutine prg_get_chebcoeffs_fermi_nt(npts, kbt, ef, tracesT, ncoeffs, coeffs, emin, emax, bndfil, norb, tol, jon, verbose)
Gets the coefficients of the Chebyshev expansion with Ef computation.
real(dp) function jackson(ncoeffs, i, jon)
Evaluates the Jackson Kernel Coefficients.
subroutine, public prg_build_density_cheb_fermi(ham_bml, rho_bml, athr, threshold, ncoeffs, kbt, ef, bndfil, getef, fermitol, jon, npts, trkfunc, verbose)
Builds the density matrix from for a Fermi function approximated with a Chebyshev polynomial expansi...
real(dp) function absmaxderivative(func, de)
Gets the absolute maximum of the derivative of a function.
subroutine, public prg_build_density_cheb(ham_bml, rho_bml, athr, threshold, ncoeffs, kbt, ef, bndfil, jon, verbose)
Builds the density matrix from for a Fermi function approximated with a Chebyshev polynomial expansi...
subroutine prg_get_chebcoeffs_fermi_bs(npts, kbt, ef, tracesT, ncoeffs, coeffs, emin, emax, bndfil, norb, tol, jon, verbose)
Gets the coefficients of the Chebyshev expansion with Ef computation.
subroutine, public prg_parse_cheb(chebdata, filename)
Chebyshev parser. This module is used to parse all the input variables for the cheb electronic struct...
real(dp) function tr(r, x)
Chebyshev polynomial obtained by recursion.
subroutine prg_get_chebcoeffs(npts, kbt, ef, ncoeffs, coeffs, emin, emax)
Gets the coefficients of the Chebyshev expansion.
real(dp) function fermi(e, ef, kbt)
Gives the Fermi distribution value for energy e.
Module to obtain the density matrix by diagonalizing an orthogonalized Hamiltonian.
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...
The prg_normalize module.
subroutine, public prg_normalize_cheb(h_bml, mu, emin, emax, alpha, scaledmu)
Normalize a Hamiltonian matrix prior to running the Chebyshev algorithm.
Module to handle input output files for the PROGRESS lib.
subroutine, public prg_open_file(io, name)
Opens a file to write.
General Cheb solver type.