1
subroutine dft_uks_energy( g_vecs, eone, etwo, exc, enrep, energy,
16
c $Id: dft_uks_energy.F 21176 2011-10-10 06:35:49Z d3y133 $
19
double precision energy
22
double precision eone, etwo, enrep, Exc(2)
24
integer gtype, grow, gcol
25
integer d(4), f(8), nfock
26
integer g_a_dens, g_a_coul, g_a_exch, g_a_xc
27
integer g_b_dens, g_b_coul, g_b_exch, g_b_xc
29
integer g_tmp(6),ifock
30
double precision jfac(4), kfac(4), one, zero, mone
31
parameter (one=1.0d0, zero=0.0d0, mone=-1.0d0)
32
double precision e_a_coul, e_a_exch, e_b_coul, e_b_exch,
34
double precision errmaxa, errmaxb
35
integer ga_create_atom_blocked
36
external ga_create_atom_blocked
41
integer dims(3),chunk(3)
43
double precision xc_hfexch
50
odebug = util_print('uks_debug', print_debug)
51
call uhf_jkfac(jfac,kfac)
52
if (.not.cuhf_init_flag)
53
$ call errquit('dft_uks_energy: UKS internal block invalid',0,
55
call ga_inquire(g_grad, gtype, grow, gcol)
56
if ((grow.ne.cuhf_vlen).or.(gcol.ne.1))
57
$ call errquit('dft_uks_energy: invalid vector length',0,
60
if (.not. rtdb_get(bgj_get_rtdb_handle(),
61
& 'cphf_solve:cphf_uhf', mt_log, 1, cphf_uhf)) then
65
c Arrays for AO density, coulomb and exchange matrices
67
g_a_coul = ga_create_atom_blocked(geom, basis, 'uks:a coul')
68
g_b_coul = ga_create_atom_blocked(geom, basis, 'uks:b coul')
69
g_a_exch = ga_create_atom_blocked(geom, basis, 'uks:a exch')
70
g_b_exch = ga_create_atom_blocked(geom, basis, 'uks:b exch')
71
if(cphf_uhf .or. xc_gotxc())then
72
g_a_xc = ga_create_atom_blocked(geom, basis, 'uks:a xc')
73
g_b_xc = ga_create_atom_blocked(geom, basis, 'uks:b xc')
75
g_a_dens = ga_create_atom_blocked(geom, basis, 'uks:a dens')
76
g_b_dens = ga_create_atom_blocked(geom, basis, 'uks:b dens')
77
call ga_zero(g_a_dens)
78
call ga_zero(g_b_dens)
80
c Make the densites and build the fock matrices
82
call ga_dgemm('n', 't', nbf, nbf, nalpha, one, g_vecs(1),
83
$ g_vecs(1), zero, g_a_dens)
84
if (nbeta .gt. 0) then
85
call ga_dgemm('n', 't', nbf, nbf, nbeta, one, g_vecs(2),
86
$ g_vecs(2), zero, g_b_dens)
88
call ga_zero(g_b_dens)
91
c Since UHF can break spatial symmetry by localizing the orbitals
92
c the densities may not be totally symmetric, but since the
93
c Hamiltonian is symmetric contraction with the integrals projects
94
c out the totally symmetric component ... hence we can symmetrize
95
c the densities and exploit symmetry. Compute the max change in any
96
c element due to symmetrizing and print a warning if it is big.
98
c !! If this is the case then where does the 'force' for symmetry
99
c breaking come from? Must be missing something?
100
c !! Yes, the symmetrization does not take to irrep of the wave-
101
c function into account. Instead it generates some totally symmetric
102
c density, which is wrong if the wavefunction has a different
105
call ga_copy(g_a_dens,g_a_coul)
106
call ga_copy(g_b_dens,g_b_coul)
108
if (oscfps) call pstat_on(ps_sym_sym)
109
call sym_symmetrize(geom, basis, .true., g_a_dens)
110
if (oscfps) call pstat_off(ps_sym_sym)
111
if (oscfps) call pstat_on(ps_sym_sym)
112
call sym_symmetrize(geom, basis, .true., g_b_dens)
113
if (oscfps) call pstat_off(ps_sym_sym)
115
call ga_dadd(one, g_a_dens, mone, g_a_coul, g_a_coul)
116
call ga_dadd(one, g_b_dens, mone, g_b_coul, g_b_coul)
117
call ga_maxelt(g_a_coul, errmaxa)
118
call ga_maxelt(g_b_coul, errmaxb)
119
if (max(errmaxa,errmaxb).gt.1d-4) then
120
if (ga_nodeid().eq.0) then
121
write(6,77) errmaxa,errmaxb
122
77 format(' Warning: spatial symmetry breaking in UKS: ',
129
call ga_print(g_vecs(1))
130
call ga_print(g_vecs(2))
131
call ga_print(g_a_dens)
132
call ga_print(g_b_dens)
135
call ga_zero(g_a_coul)
136
call ga_zero(g_b_coul)
137
call ga_zero(g_a_exch)
138
call ga_zero(g_b_exch)
139
if(cphf_uhf .or. xc_gotxc())then
151
if(cphf_uhf .or. xc_gotxc())then
156
c two extra ga's are passed to fock_2e to get the xc matrix
163
call do_riscf (.false.)
164
if (.not.cam_exch) then
169
call fock_2e(geom, basis, nfock, jfac, kfac, tol2e,
170
$ oskel, d, f, .false.)
171
else ! for attenuated calculations
173
c calculate the CAM exchange
176
g_tmp(ifock) = ga_create_atom_blocked(geom, basis, 'tmp')
180
call case_setflags(.true.)
189
call fock_2e_cam(geom, basis, nfock, jfac, kfac, tol2e,
190
& oskel, d, g_tmp, .false., .false.)
191
call ga_dadd(1d0,f,1d0,g_tmp,f)
193
c calculate the full Coulomb
195
call case_setflags(.false.)
204
call fock_2e_cam(geom, basis, nfock, jfac, kfac, tol2e,
205
& oskel, d, g_tmp, .false., .true.)
206
call ga_dadd(1d0,f,1d0,g_tmp,f)
209
if (.not. ga_destroy(g_tmp))
210
& call errquit('uhf: ga corrupt?',0, GA_ERR)
212
call do_riscf (.true.)
219
call fock_xc(geom, nbf, basis, 4*2, d, f(5), Exc, nExc, .false.)
225
$ (ga_ddot(g_a_dens,g_a_coul) + ga_ddot(g_a_dens,g_b_coul))
227
$ (ga_ddot(g_b_dens,g_a_coul) + ga_ddot(g_b_dens,g_b_coul))
228
e_a_exch = 0.5d0*ga_ddot(g_a_dens,g_a_exch)
229
e_b_exch = 0.5d0*ga_ddot(g_b_dens,g_b_exch)
231
etwo = e_a_coul + e_b_coul
232
exc(1) = exc(1) - e_a_exch - e_b_exch
234
etwo = e_a_coul + e_b_coul - e_a_exch - e_b_exch
236
c take this out? it seems that the xc_gotxc part does essentially the
237
c same thing apart from the fact that the energy is added on properly.
239
e_a_xc = ga_ddot(g_a_dens,g_a_xc)
240
e_b_xc = ga_ddot(g_b_dens,g_b_xc)
241
etwo = etwo + e_a_xc + e_b_xc
244
if (odebug .and. ga_nodeid().eq.0) then
245
write(6,*) ' coulomb energies', e_a_coul, e_b_coul
246
write(6,*) ' exchang energies', e_a_exch, e_b_exch
250
call ga_print(g_a_coul)
251
call ga_print(g_a_exch)
254
c Form energies and AO fock matrices
256
c Fa (in g_a_coul) = h + J(a) + J(b) - K(a)
257
c Fb (in g_b_coul) = h + J(a) + J(b) - K(b)
259
c E = ((Da + Db)*h + Da*Fa + Db*Fb) / 2
260
c Eone = h * (Da + Db)
262
c 2e denotes 2-electron components only
264
call ga_dadd(one, g_a_coul, one, g_b_coul, g_a_coul)
265
call ga_copy(g_a_coul, g_b_coul)
266
call ga_dadd(one, g_a_coul, mone, g_a_exch, g_a_coul)
267
call ga_dadd(one, g_b_coul, mone, g_b_exch, g_b_coul)
268
if(cphf_uhf.or.xc_gotxc())then
269
call ga_dadd(one, g_a_coul, one, g_a_xc, g_a_coul)
270
call ga_dadd(one, g_b_coul, one, g_b_xc, g_b_coul)
273
c reuse g_a_exch to hold the 1-e integrals
276
call ga_zero(g_hcore)
277
call int_1e_ga(basis, basis, g_hcore, 'kinetic', oskel)
278
call int_1e_ga(basis, basis, g_hcore, 'potential', oskel)
280
$ (ga_ddot(g_a_dens,g_hcore) + ga_ddot(g_b_dens,g_hcore))
281
call ga_dadd(one, g_hcore, one, g_a_coul, g_a_coul)
282
call ga_dadd(one, g_hcore, one, g_b_coul, g_b_coul)
285
if (oscfps) call pstat_on(ps_sym_sym)
286
call sym_symmetrize(geom, basis, .false., g_a_coul)
287
if (oscfps) call pstat_off(ps_sym_sym)
288
if (oscfps) call pstat_on(ps_sym_sym)
289
call sym_symmetrize(geom, basis, .false., g_b_coul)
290
if (oscfps) call pstat_off(ps_sym_sym)
294
call ga_print(g_a_coul)
295
call ga_print(g_b_coul)
298
c Transform the Fock matrices to the MO basis using g_a_dens
301
call two_index_transf(g_a_coul, g_vecs(1), g_vecs(1),
302
$ g_a_dens, cuhf_g_falpha)
303
call two_index_transf(g_b_coul, g_vecs(2), g_vecs(2),
304
$ g_a_dens, cuhf_g_fbeta)
307
call ga_print(cuhf_g_falpha)
308
call ga_print(cuhf_g_fbeta)
311
c Free up dead global arrays
313
if (.not. ga_destroy(g_a_dens)) call errquit('uks_e: destroy',0,
315
if (.not. ga_destroy(g_b_dens)) call errquit('uks_e: destroy',0,
317
if(cphf_uhf .or. xc_gotxc())then
318
if (.not. ga_destroy(g_a_xc)) call errquit('uks_e: destroy',0,
320
if (.not. ga_destroy(g_b_xc)) call errquit('uks_e: destroy',0,
323
if (.not. ga_destroy(g_a_exch)) call errquit('uks_e: destroy',0,
325
if (.not. ga_destroy(g_b_exch)) call errquit('uks_e: destroy',0,
327
if (.not. ga_destroy(g_a_coul)) call errquit('uks_e: destroy',0,
329
if (.not. ga_destroy(g_b_coul)) call errquit('uks_e: destroy',0,
332
c extract the gradient
334
call uhf_get_grad(g_grad)
336
if (odebug) call ga_print(g_grad)
338
if (.not. geom_nuc_rep_energy(geom, enrep))
339
$ call errquit('dft_uks_energy: no repulsion energy?', 0,
341
energy = eone + etwo + enrep
343
energy = energy + Exc(1) + Exc(2)
346
if (odebug .and. ga_nodeid().eq.0) then
347
write(6,*) ' eone, etwo, enrep, energy ',
348
$ eone, etwo, enrep, energy