48
47
double precision util_erfc
53
54
double precision undovl
54
55
parameter(undovl=-20d0*2.3025d0)
55
56
parameter (zero=0.d0,toll=1.d-9,one=1.d0,
56
57
, kbau=1.d0,eps=1.d-4)
57
external dft_scaleMO ! FA-added-02-22-11
58
59
integer rtdb ! FA-02-22-11, for occupations
59
60
integer switch_focc ! FA-02-22-11, for occupations
60
61
logical status ! FA-02-22-11, for occupations
62
double precision anoc(2),new_ntotel
64
70
sqrtpi=sqrt(acos(-1d0))
68
74
if(ipol.eq.2) rhfuhf=1d0
69
if(ssmear.lt.toll.or.iter.lt.-1) then
74
78
if (rtdb_get(rtdb, 'dft:debugfon', mt_log, 1,
76
80
if (debug_fon .and. me.eq.0)
77
& write(luout,*) "fon is on ",fon
81
& write(luout,*) "fractional occupation (fon) is on ",fon
84
c average fractional occupations (leading orbitals)
81
status = dft_checkdg(rtdb,nmo_fon,ncore_fon,nel_fon,
86
status = dft_fon(rtdb,nmo_fon,ncore_fon,nel_fon,
82
87
. nbf,ntotel,focc,noc,ipol,me)
83
cng if(dft_checkdg(nmo_fon,ncore_fon,nel_fon,
84
cng . nbf,ntotel,focc,noc,ipol,me)) then
86
89
call dft_focdm(focc(1+(isp-1)*nbf),noc(isp),geom,
88
* g_vecs(isp),g_dens(isp),toll)
90
& AO_bas_han,nbf,g_vecs(isp),g_dens(isp),toll)
92
if(ssmear.lt.toll)return
95
if(ssmear.lt.toll.or.iter.lt.-1) then
95
97
if (odftps) call pstat_on(ps_dgemm)
99
c fractional occupation by orbital
98
status=rtdb_get(rtdb,'focc:occ-switch',
99
& mt_int,1,switch_focc)
101
status=rtdb_get(rtdb,'focc:occup_switch', mt_int,1,switch_focc)
100
102
if (switch_focc.eq.1 .and. status) then ! using specified occupations
102
call dft_scaleMO(rtdb,g_vecs, ! IN : MO vectors
103
& focc,g_dens, ! OUT : density matrix
104
& noc, ! IN/OUT : orbital occupations
106
enddo ! end-loop-ispin
104
call dft_frac_mo(rtdb,g_vecs(isp),focc,nbf,ipol,ntotel)
105
call dft_focdm(focc(1+(isp-1)*nbf),noc(isp),geom,
106
& AO_bas_han,nbf,g_vecs(isp),g_dens(isp),toll)
108
109
else ! default occupations
110
111
call ga_dgemm('N', 'T', nbf, nbf, noc(isp),
111
112
$ 2d0/dble(ipol), g_vecs(isp),g_vecs(isp),
112
113
$ zero, g_dens(isp))
115
115
endif ! switch_focc
117
117
if (odftps) call pstat_off(ps_dgemm)
119
121
if (.not. MA_Push_Get(MT_Dbl, nbf, 'tmpm', ltmpm, itmpm))
120
122
& call errquit('dftdensm: failed to alloc tmpm',nbf, MA_ERR)
126
if(nocinit.eq.1) then
128
anoc(1)=ncore_fon(1)+nel_fon(1)
129
anoc(2)=ncore_fon(2)+nel_fon(2)
136
new_ntotel=rhfuhf*(anoc(1)+anoc(2))
130
146
call dfill(nbf*ipol, 0.d0, focc, 1)
131
147
if(spinset.and.ipol.eq.2) then
133
call dft_zero(2,nbf,nmo,noc(1),efermi(1),evals,
149
call dft_zero(2,nbf,nmo,anoc(1),efermi(1),evals,
134
150
, ssmear,toll,.true.)
135
call dft_zero(2,nbf,nmo,noc(2),efermi(2),evals(nbf+1),
151
call dft_zero(2,nbf,nmo,anoc(2),efermi(2),evals(nbf+1),
136
152
. ssmear,toll,.true.)
139
call dft_zero(ipol,nbf,nmo,ntotel,efermi(1),evals,ssmear,
155
cold call dft_zero(ipol,nbf,nmo,ntotel,efermi(1),evals,ssmear,
156
call dft_zero(ipol,nbf,nmo,new_ntotel,
157
E efermi(1),evals,ssmear,
141
159
efermi(2)=efermi(1)
477
double precision avg_fon
478
double precision nel_fon(2)
479
integer nmo_fon(2), ncore_fon(2)
494
double precision avg_fon, avg_fon2
495
double precision nel_fon(4)
496
integer nmo_fon(4), ncore_fon(2)
481
498
double precision ncheck
486
if (rtdb_get(rtdb, 'dft:debugfon', mt_log, 1,
505
if (.not. rtdb_get(rtdb, 'dft:debugfon', mt_log, 1, debug))
508
c do average fractional occupation by default
510
if (.not.rtdb_get(rtdb,'dft:avg_fon',mt_log,1,do_avg_fon))
511
& do_avg_fon = .true.
513
c do average occupation starting with core orbitals
514
do_core_fon = .false.
515
if (.not.rtdb_get(rtdb,'dft:core_fon',mt_log,1,do_core_fon))
516
& do_core_fon = .false.
489
518
if (me.eq.0 .and. debug) then
490
519
write (luout,*) 'FON: ipol, noc, ntotel',ipol,noc(:),ntotel
520
write (luout,*) 'do_avg_fon: ', do_avg_fon
495
c ... jochen: this functionality was not doing what
496
c I thought it was doing. Let's try differently
499
c$$$ avg_fon = dble(nel_fon(ispin))/dble(nmo_fon(ispin))
500
c$$$ do i=1,noc(ispin)-nel_fon(ispin)
501
c$$$ focc(i,ispin) = 2d0/ipol
503
c$$$ ncheck=(noc(ispin)-nel_fon(ispin)+1d0)*
504
c$$$ . 2d0/dble(ipol)
505
c$$$ do i = noc(ispin)-nel_fon(ispin)+1,
506
c$$$ , noc(ispin)-nel_fon(ispin)+nmo_fon(ispin)
507
c$$$ focc(i,ispin) = avg_fon*(2d0/ipol)
508
c$$$ ncheck=ncheck+focc(i,ispin)
512
c ... jochen: new code:
515
524
do ispin = 1,ipol
517
if (nmo_fon(ispin).lt.1) call errquit(
518
& 'dft_densm:fon nmo_fon <1',
520
if (nel_fon(ispin).lt.0d0) call errquit(
521
& 'dft_scf_so:fon nel_fon <0',
524
avg_fon = nel_fon(ispin)/dble(nmo_fon(ispin))
525
ncor = ncore_fon(ispin)
527
if (i>nbf) call errquit(
528
& 'dft_densm:fon focc index exceeds nbf',
530
focc(i,ispin) = 2d0/ipol
531
ncheck = ncheck + focc(i,ispin)
533
do i = 1,nmo_fon(ispin)
534
if (i+ncor>nbf) call errquit(
535
& 'dft_densm:fon focc index exceeds nbf',
537
focc(i+ncor,ispin) = avg_fon
538
ncheck = ncheck + focc(i+ncor,ispin)
525
if (nmo_fon(ispin).lt.1)
526
& call errquit('dft_densm:fon nmo_fon <1',1, INPUT_ERR)
527
if (nel_fon(ispin).lt.0d0)
528
& call errquit('dft_scf_so:fon nel_fon <0',1, INPUT_ERR)
530
avg_fon = nel_fon(ispin)/dble(nmo_fon(ispin)) ! average occupation
531
if (nmo_fon(ispin+2).lt.1.or.nel_fon(ispin+2).le.0d0) then
534
avg_fon2 = nel_fon(ispin+2)/dble(nmo_fon(ispin+2)) ! average occupation
536
nfilled = ncore_fon(ispin) ! number of filled orbitals for each spin
543
c fill the molecular orbitals either starting from the core or valence states
544
if (do_core_fon) then
546
c partially filled molecular orbitals
547
do i = 1,nmo_fon(ispin)
548
if (i > nbf) call errquit(
549
& 'dft_densm:fon focc index exceeds nbf',1,INPUT_ERR)
551
focc(i,ispin) = avg_fon ! assign average occupation
553
focc(i,ispin) = nel_fon(ispin) ! assign given fractional electron
555
ncheck = ncheck + focc(i,ispin)
556
if (me.eq.0 .and. debug)
557
& write(luout,*) i,ispin,focc(i,ispin)
560
c fully filled molecular orbitals
562
if (i+nmo_fon(ispin)>nbf) call errquit(
563
& 'dft_densm:fon focc index exceeds nbf',1,INPUT_ERR)
564
focc(i+nmo_fon(ispin),ispin) = 2d0/ipol
565
ncheck = ncheck + focc(i+nmo_fon(ispin),ispin)
566
if (me.eq.0 .and. debug)
567
& write(luout,*) i,ispin,focc(i+nmo_fon(ispin),ispin)
572
c fully filled molecular orbitals
574
if (i>nbf) call errquit(
575
& 'dft_densm:fon focc index exceeds nbf',1,INPUT_ERR)
576
focc(i,ispin) = 2d0/ipol
577
ncheck = ncheck + focc(i,ispin)
578
if (me.eq.0 .and. debug)
579
& write(luout,*) i,ispin,focc(i,ispin)
582
c partially filled molecular orbitals
583
do i = 1,nmo_fon(ispin)
584
if (i+nfilled > nbf) call errquit(
585
& 'dft_densm:fon focc index exceeds nbf',1,INPUT_ERR)
587
focc(i+nfilled,ispin) = avg_fon ! assign average occupation
589
focc(i+nfilled,ispin) = nel_fon(ispin) ! assign given fractional electron
591
ncheck = ncheck + focc(i+nfilled,ispin)
592
if (me.eq.0 .and. debug)
593
& write(luout,*) i,ispin,focc(i+nfilled,ispin)
596
c second partially filled molecular orbitals
597
do i = 1,nmo_fon(ispin+2)
598
if (i+nfilled > nbf) call errquit(
599
& 'dft_densm:fon focc index exceeds nbf',1,INPUT_ERR)
601
focc(i+nfilled+nmo_fon(ispin),ispin) = avg_fon2 ! assign average occupation
603
focc(i+nfilled+nmo_fon(ispin),ispin) = nel_fon(ispin+2) ! assign given fractional electron
605
ncheck = ncheck + focc(i+nfilled+nmo_fon(ispin),ispin)
606
if (me.eq.0 .and. debug)
607
& write(luout,*) i,ispin,focc(i+nfilled+nmo_fon(ispin),ispin)
608
end do ! nmo_fon second partial
542
612
if (me.eq.0 .and. debug) then
543
write (luout,*) 'FON: focc:',focc(:,1)
613
write(luout,*) 'FON: focc:',focc(:,1)
614
write(luout,*) 'ncheck:' , ncheck
615
write(luout,*) 'ntotel:' , ntotel
546
618
if(abs(ncheck-dble(ntotel)).gt.1d-3 .and. me.eq.0) then
547
c write(luout,*) ' frac. electrons ',ncheck,' vs ',ntotel
552
c if(me.eq.0) write(luout,'(5x,a)') 'FON applied'
626
c $Id: dft_densm.F 24151 2013-05-02 01:03:46Z edo $