1
!==================================================================
5
use orbital_set, only: get_orbital_set
6
use io_hs, only: read_hs_file
7
use read_curves, only: read_curve_information, mask_to_arrays
18
call getopts('dhls:n:m:M:R:',opt_name,opt_arg,n_opts,iostat)
26
energies_only = .true.
30
read(opt_arg,*) npts_energy
32
read(opt_arg,*) minimum_spec_energy
34
read(opt_arg,*) maximum_spec_energy
36
ref_line_given = .true.
41
write(0,*) "Invalid option: ", opt_arg(1:1)
42
write(0,*) "Usage: mprop [ -d ] [ -h ] MPROP_FILE_ROOT"
43
write(0,*) "Use -h option for manual"
48
nargs = command_argument_count()
49
nlabels = nargs - n_opts + 1
50
if (nlabels /= 1) then
51
write(0,*) "Usage: mprop [ -d ] [ -h ] MPROP_FILE_ROOT"
52
write(0,*) "Use -h option for manual"
56
call get_command_argument(n_opts,value=mflnm,status=iostat)
58
STOP "Cannot get .mprop file root"
61
print "(a,f7.3)", "Using smearing parameter: ", smear
62
print "(a,i6,a)", "Using ", npts_energy, " points in energy range"
64
!==================================================
68
! * LECTURA TIPUS CALCUL
70
open(mpr_u,file=trim(mflnm) // ".mpr", status='old')
74
dos=(trim(what).eq.'DOS')
75
coop=(trim(what).eq.'COOP')
77
!==================================================
78
! * LECTURA sflnm.WFSX
80
write(6,"(1x,a,'.WFSX ...')") trim(sflnm)
82
open(wfs_u,file=trim(sflnm)//'.WFSX',status='old',form='unformatted')
83
read(wfs_u) nkp, gamma_wfsx
84
allocate (wk(nkp), pk(3,nkp))
88
read(wfs_u) !! Symbols, etc
89
if (debug) print *, "WFSX read: nkp, nsp, nnao: ", nkp, nsp, nao
91
allocate (ados(npts_energy,nsp))
94
min_energy = huge(1.0_dp)
95
max_energy = -huge(1.0_dp)
100
read(wfs_u) idummy, pk(1:3,ik), wk(ik)
101
if (idummy /= ik) stop "ik index mismatch in WFS file"
104
read(wfs_u) number_of_wfns
105
nwfmx = max(nwfmx,number_of_wfns)
107
do iw=1,number_of_wfns
110
min_energy = min(min_energy,eigval)
111
max_energy = max(max_energy,eigval)
117
print *, " Maximum number of wfs per k-point: ", nwfmx
118
print "(a,2f12.4)", "Min_energy, max_energy on WFS file: ", &
119
min_energy, max_energy
123
low_e = min_energy - 2*smear
124
high_e = max_energy + 2*smear
125
e_step = (high_e-low_e)/(npts_energy-1)
126
ados(:,1:nsp) = 0.0_dp
141
read(wfs_u) number_of_wfns
142
do iw=1,number_of_wfns
145
do i = 1, npts_energy
146
energy = low_e + e_step*(i-1)
147
weight = delta(energy-eigval)
148
if (weight < 1.0e-6) CYCLE ! Will not contribute
149
ados(i,is) = ados(i,is) + wk(ik) * weight
151
read(wfs_u) ! Skip wfn info
157
open(idos,file=trim(sflnm)//".alldos",form="formatted", &
158
status="unknown",action="write",position="rewind")
159
write(idos,*) "# Energy LARGE-SCALE DOS"
160
do i = 1, npts_energy
161
energy = low_e + e_step*(i-1)
162
write(idos,*) energy, (ados(i,is), is=1,nsp)
169
! Will pick up atoms, zval, and thus N_electrons
172
if (gamma_wfsx .neqv. gamma) STOP "Gamma mismatch"
176
ztot = ztot + zval(isa(ia))
181
! Compute integrated total DOS
183
allocate(intdos(npts_energy))
184
call io_assign(intdos_u)
185
open(intdos_u,file=trim(sflnm)//".intdos",form="formatted", &
186
status="unknown",action="write",position="rewind")
188
write(intdos_u,*) low_e, intdos(1)
189
do i = 2, npts_energy
190
energy = low_e + e_step*(i-1)
191
intdos(i) = intdos(i-1) + sum(ados(i,:)) * e_step * 2.0_dp /nsp
192
write(intdos_u,*) energy, intdos(i)
194
call io_close(intdos_u)
196
! Look for Fermi Energy
197
do i = 2, npts_energy
198
if (intdos(i) > ztot) then
200
energy = low_e + e_step*(i-1)
201
efermi = energy - (intdos(i)-ztot)*e_step/(intdos(i)-intdos(i-1))
206
print *, "Fermi energy: ", efermi
208
if (energies_only) STOP
209
!-------------------------------------------------------------------
211
if (minimum_spec_energy > min_energy) then
212
min_energy = minimum_spec_energy
214
min_energy = min_energy - 2*smear
216
if (maximum_spec_energy < max_energy) then
217
max_energy = maximum_spec_energy
219
max_energy = max_energy + 2*smear
222
print "(a,2f12.4)", "Min_energy, max_energy used: ", &
223
min_energy, max_energy
225
!====================
229
allocate(za(no_u), zc(no_u), zn(no_u), zl(no_u), zx(no_u), zz(no_u))
236
if (io > no(it)) exit
238
do ko = 1, 2*lorb + 1
242
zn(nao)=nquant(it,io)
250
if (nao /= no_u) STOP "nao /= no_u"
252
! ==================================
254
write(6,"('Writing files: ',a,'.stt ...')",advance='no') trim(mflnm)
255
open(stt_u,file=trim(mflnm)//'.stt')
256
write(stt_u,"(/'UNIT CELL ATOMS:')")
257
write(stt_u,"(3x,i4,2x,i3,2x,a2)") (i, isa(i), label(isa(i)), i=1,na_u)
258
write(stt_u,"(/'BASIS SET:')")
259
write(stt_u,"(5x,a20,3(3x,a1))") 'spec', 'n', 'l', 'z'
261
write(stt_u,"(5x,a20)") trim(label(it))
265
if (io > no(it)) exit
266
write(stt_u,"(3(2x,i2))") nquant(it,io), lquant(it,io), zeta(it,io)
267
io = io + 2*lquant(it,io)
271
write(stt_u,"(/'SPIN: ',i2)") nsp
272
write(stt_u,"(/'FERMI ENERGY: ',f18.6)") efermi
274
write(stt_u,"(/'AO LIST:')")
275
taux=repeat(' ',len(taux))
277
taux(1:30)=repeat(' ',30)
279
if (zl(io).eq.0) then
282
elseif (zl(io).eq.1) then
283
if (zx(io).eq.1) taux(ik:ik+1)='py'
284
if (zx(io).eq.2) taux(ik:ik+1)='pz'
285
if (zx(io).eq.3) taux(ik:ik+1)='px'
287
elseif (zl(io).eq.2) then
288
if (zx(io).eq.1) taux(ik:ik+2)='dxy'
289
if (zx(io).eq.2) taux(ik:ik+2)='dyz'
290
if (zx(io).eq.3) taux(ik:ik+2)='dz2'
291
if (zx(io).eq.4) taux(ik:ik+2)='dxz'
292
if (zx(io).eq.5) taux(ik:ik+5)='dx2-y2'
294
elseif (zl(io).eq.3) then
296
elseif (zl(io).eq.4) then
298
elseif (zl(io).eq.5) then
301
write(stt_u,"(3x,i5,2x,i3,2x,a2)",advance='no') &
302
io, za(io), trim(label(zc(io)))
304
write(stt_u,"(3x,i2,a)") zn(io), trim(taux)
306
write(stt_u,"(3x,i2,a,i2.2)") zn(io), trim(taux), zx(io)
310
!==================================
312
if (ref_line_given) then
313
allocate(ref_mask(no_u))
314
print *, "Orbital set spec: ", trim(ref_line)
315
call get_orbital_set(ref_line,ref_mask)
317
if (ref_mask(io)) write(6,fmt="(i5)",advance="no") io
321
STOP "bye from ref_line processing"
325
! Process orbital sets
327
allocate(orb_mask(no_u,2,ncbmx))
328
allocate (koc(ncbmx,2,no_u))
329
call read_curve_information(dos,coop, &
330
mpr_u,no_u,ncbmx,ncb,tit,orb_mask,dtc)
332
orb_mask(:,2,1:ncb) = .true. ! All orbitals considered
334
call mask_to_arrays(ncb,orb_mask(:,1,:),noc(:,1),koc(:,1,:))
335
call mask_to_arrays(ncb,orb_mask(:,2,:),noc(:,2),koc(:,2,:))
338
!=====================
341
allocate (coop_vals(npts_energy,nsp,ncb))
342
allocate (cohp_vals(npts_energy,nsp,ncb))
343
coop_vals(:,:nsp,:ncb)=0.d0
344
cohp_vals(:,:nsp,:ncb)=0.d0
347
allocate (pdos_vals(npts_energy,nsp,ncb))
348
pdos_vals(:,:nsp,:ncb) = 0.0_dp
351
ados(:,:nsp) = 0.0_dp
353
!================================================================
358
allocate(wf(1,1:no_u))
360
allocate(wf(2,1:no_u))
363
!Stream over file, without using too much memory
372
e_step = (max_energy-min_energy)/(npts_energy-1)
378
read(wfs_u) number_of_wfns
379
do iw=1,number_of_wfns
382
! Early termination of iteration
383
if (eigval < min_energy .or. eigval > max_energy) then
384
read(wfs_u) ! Still need to read this
388
read(wfs_u) (wf(:,io), io=1,nao)
390
do i = 1, npts_energy
391
energy = min_energy + e_step*(i-1)
392
weight = delta(energy-eigval)
393
if (weight < 1.0e-6) CYCLE ! Will not contribute
395
ados(i,is) = ados(i,is) + wk(ik) * weight
400
io1=koc(ic,1,i1) ! AO Set I
402
! On site contribution to DOS
407
qcos=(wf(1,io1)**2+wf(2,io1)**2)
410
pdos_vals(i,is,ic)= pdos_vals(i,is,ic) + &
411
qcos * wk(ik) * weight
415
io2=koc(ic,2,i2) ! AO Set II
417
! (qcos, qsin) = C_1*conjg(C_2)
420
qcos = wf(1,io1)*wf(1,io2)
423
qcos= (wf(1,io1)*wf(1,io2) + &
425
qsin= (wf(2,io1)*wf(1,io2) - &
429
do isr=1,nsr(io1,io2)
431
! Note that we want orbitals in
432
! *different* atoms (See Dronskowski)
434
if ( dt(io1,io2,isr) < 1.0e-2_dp) CYCLE
436
! Discard if overlap is very small
437
! (It happens if not neglecting KB overlap)
438
if ( abs(sr(io1,io2,isr)) < 1.0e-10_dp) CYCLE
441
! No distance restrictions for PDOS
442
! Note also that there is no factor of 2
445
alfa=dot_product(pk(1:3,ik),rn(1:3,io1,io2,isr))
448
pdos_vals(i,is,ic)=pdos_vals(i,is,ic) + &
449
(qcos*cos(alfa)+qsin*sin(alfa)) * &
450
sr(io1,io2,isr)*wk(ik) * weight
454
if (dt(io1,io2,isr).ge.dtc(ic,1) .and. &
455
dt(io1,io2,isr).le.dtc(ic,2)) then
457
! Crb = Real(C_1*conjg(C_2)*exp(-i*alfa)) * S_12
458
! or Real(conjg(C_1)*C_2)*exp(+i*alfa)) * S_12
460
coop_vals(i,is,ic)=coop_vals(i,is,ic) + &
461
2.0_dp * (qcos*cos(alfa)+qsin*sin(alfa)) * &
462
sr(io1,io2,isr)*wk(ik) * weight
463
cohp_vals(i,is,ic)=cohp_vals(i,is,ic) + &
464
2.0_dp * (qcos*cos(alfa)+qsin*sin(alfa)) * &
465
hr(io1,io2,isr,is)*wk(ik) * weight
478
!--------------------------------------------------------
480
write(stt_u,"(/'KPOINTS:',i7)") nkp
482
write(stt_u,"(3x,3f9.6)") pk(:,ik)
486
write(stt_u,"(/'PDOS CURVES:')")
488
write(stt_u,"(3x,a)") trim(tit(ic))
489
write(stt_u,"(3x,'AO set I: ',1000i5)") (koc(ic,1,j),j=1,noc(ic,1))
494
write(stt_u,"(/'COOP CURVES:')")
496
write(stt_u,"(3x,a)") trim(tit(ic))
497
write(stt_u,"(3x,'Distance range:',2f9.4)") dtc(ic,:)
498
write(stt_u,"(3x,'AO set I: ',1000i5)") (koc(ic,1,j),j=1,noc(ic,1))
499
write(stt_u,"(3x,'AO set II:',1000i5)") (koc(ic,2,j),j=1,noc(ic,2))
509
open(idos,file=trim(sflnm)//".ados",form="formatted", &
510
status="unknown",action="write",position="rewind")
511
write(idos,*) "# Energy SIMPLE DOS"
512
e_step = (max_energy-min_energy)/(npts_energy-1)
513
do i = 1, npts_energy
514
energy = min_energy + e_step*(i-1)
515
write(idos,*) energy, (ados(i,is), is=1,nsp)
524
open(tab_u,file=trim(mflnm)// "." // trim(tit(ic)) // '.coop')
525
write(tab_u,"(a1,14x,'ENERGY',4(16x,a1,i1))") '#', ("s",m, m=1,nsp)
527
energy = min_energy + e_step*(i-1)
528
write(tab_u,"(f20.8,10(2f13.8,5x)))") & ! Spin in loop
529
energy, (coop_vals(i,is,ic),is=1,nspin)
537
open(tab_u,file=trim(mflnm)// "." // trim(tit(ic)) // '.cohp')
538
write(tab_u,"(a1,14x,'ENERGY',4(16x,a1,i1))") '#', ("s",m, m=1,nsp)
540
energy = min_energy + e_step*(i-1)
541
write(tab_u,"(f20.8,10(2f13.8,5x)))") & ! Spin in loop
542
energy, (cohp_vals(i,is,ic),is=1,nspin)
553
open(tab_u,file=trim(mflnm)// "." // trim(tit(ic)) // '.pdos')
554
write(tab_u,"(a1,14x,'ENERGY',4(16x,a1,i1))") '#', ("s",m, m=1,nsp)
556
energy = min_energy + e_step*(i-1)
557
write(tab_u,"(f20.8,10(2f13.8,5x)))") & ! Spin in loop
558
energy, (pdos_vals(i,is,ic),is=1,nspin)
566
function delta(x) result(res)
567
real(dp), intent(in) :: x
570
if ((abs(x) > 8*smear)) then
575
res = exp(-(x/smear)**2) / (smear*sqrt(pi))