Octopus
energy_calc.F90
Go to the documentation of this file.
1!! Copyright (C) 2002-2006 M. Marques, A. Castro, A. Rubio, G. Bertsch
2!!
3!! This program is free software; you can redistribute it and/or modify
4!! it under the terms of the GNU General Public License as published by
5!! the Free Software Foundation; either version 2, or (at your option)
6!! any later version.
7!!
8!! This program is distributed in the hope that it will be useful,
9!! but WITHOUT ANY WARRANTY; without even the implied warranty of
10!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11!! GNU General Public License for more details.
12!!
13!! You should have received a copy of the GNU General Public License
14!! along with this program; if not, write to the Free Software
15!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16!! 02110-1301, USA.
17!!
18
19#include "global.h"
20
22 use batch_oct_m
23 use comm_oct_m
24 use debug_oct_m
26 use energy_oct_m
31 use global_oct_m
32 use grid_oct_m
35 use ions_oct_m
36 use lda_u_oct_m
37 use mesh_oct_m
43 use pcm_oct_m
45 use smear_oct_m
46 use space_oct_m
50 use unit_oct_m
53 use xc_oct_m
54
55 implicit none
56
57 private
58 public :: &
64
65contains
66
67 ! ---------------------------------------------------------
71 subroutine energy_calc_total(namespace, space, hm, gr, st, ext_partners, iunit, full)
72 type(namespace_t), intent(in) :: namespace
73 class(space_t), intent(in) :: space
74 type(hamiltonian_elec_t), intent(inout) :: hm
75 type(grid_t), intent(in) :: gr
76 type(states_elec_t), intent(inout) :: st
77 type(partner_list_t), intent(in) :: ext_partners
78 integer, optional, intent(in) :: iunit
79 logical, optional, intent(in) :: full
80
81 logical :: full_
82 type(states_elec_t) :: xst
84 type(gauge_field_t), pointer :: gfield
85
86 push_sub(energy_calc_total)
87
88 full_ = .false.
89 if (present(full)) full_ = full
90
91 hm%energy%eigenvalues = states_elec_eigenvalues_sum(st)
92
93 if (full_ .or. hm%theory_level == hartree .or. hm%theory_level == hartree_fock &
94 .or. hm%theory_level == generalized_kohn_sham_dft) then
95 if (states_are_real(st)) then
96 hm%energy%kinetic = denergy_calc_electronic(namespace, hm, gr%der, st, terms = term_kinetic)
97 hm%energy%extern_local = denergy_calc_electronic(namespace, hm, gr%der, st, terms = term_local_external)
98 hm%energy%extern_non_local = denergy_calc_electronic(namespace, hm, gr%der, st, terms = term_non_local_potential)
99 hm%energy%extern = hm%energy%extern_local + hm%energy%extern_non_local
100 else
101 hm%energy%kinetic = zenergy_calc_electronic(namespace, hm, gr%der, st, terms = term_kinetic)
102
103 hm%energy%extern_local = zenergy_calc_electronic(namespace, hm, gr%der, st, terms = term_local_external)
104
105 hm%energy%extern_non_local = zenergy_calc_electronic(namespace, hm, gr%der, st, terms = term_non_local_potential)
106 hm%energy%extern = hm%energy%extern_local + hm%energy%extern_non_local
107 end if
108 end if
109
110 ! Computes the HF energy when not doing the ACE
111 if( full_ .and. (hm%theory_level == hartree_fock .or. &
112 (hm%theory_level == generalized_kohn_sham_dft .and. family_is_hybrid(hm%xc))) &
113 .and. .not. hm%exxop%useACE ) then
114 call xst%nullify()
115 if (states_are_real(st)) then
116 call dexchange_operator_compute_potentials(hm%exxop, namespace, space, gr, st, &
117 xst, hm%kpoints, hm%energy%exchange_hf)
118 else
119 call zexchange_operator_compute_potentials(hm%exxop, namespace, space, gr, st, &
120 xst, hm%kpoints, hm%energy%exchange_hf)
121 end if
122 call states_elec_end(xst)
123 else
124 if(.not. hm%exxop%useACE) hm%energy%exchange_hf = m_zero
125 end if
126
127 if (hm%pcm%run_pcm) then
128 hm%pcm%counter = hm%pcm%counter + 1
129 if (hm%pcm%localf) then
130 call pcm_elect_energy(hm%ions, hm%pcm, hm%energy%int_ee_pcm, hm%energy%int_en_pcm, &
131 hm%energy%int_ne_pcm, hm%energy%int_nn_pcm, &
132 e_int_e_ext = hm%energy%int_e_ext_pcm, &
133 e_int_n_ext = hm%energy%int_n_ext_pcm )
134 else
135 call pcm_elect_energy(hm%ions, hm%pcm, hm%energy%int_ee_pcm, hm%energy%int_en_pcm, &
136 hm%energy%int_ne_pcm, hm%energy%int_nn_pcm )
137 end if
138 end if
139
140 select case (hm%theory_level)
142 hm%energy%total = hm%ep%eii + hm%energy%eigenvalues
143
144 case (hartree)
145 hm%energy%total = hm%ep%eii + m_half * (hm%energy%eigenvalues + hm%energy%kinetic + hm%energy%extern)
146
148 hm%energy%total = hm%ep%eii + &
149 m_half*(hm%energy%eigenvalues + hm%energy%kinetic + hm%energy%extern - hm%energy%intnvxc &
150 - hm%energy%int_dft_u) &
151 + hm%energy%exchange + hm%energy%exchange_hf + hm%energy%correlation &
152 + hm%energy%vdw - hm%energy%intnvstatic + hm%energy%dft_u
153
154 ! FIXME: pcm terms are only added to total energy in DFT case
155
156 case (kohn_sham_dft)
157 hm%energy%total = hm%ep%eii + hm%energy%eigenvalues &
158 - hm%energy%hartree + hm%energy%exchange + hm%energy%correlation + hm%energy%vdw - hm%energy%intnvxc &
159 - hm%energy%pcm_corr + hm%energy%int_ee_pcm + hm%energy%int_en_pcm &
160 + hm%energy%int_nn_pcm + hm%energy%int_ne_pcm &
161 + hm%energy%int_e_ext_pcm + hm%energy%int_n_ext_pcm &
162 + hm%energy%dft_u - hm%energy%int_dft_u - hm%energy%intnvstatic &
163 + hm%energy%photon_exchange
165 end select
166
167 hm%energy%entropy = smear_calc_entropy(st%smear, st%eigenval, st%nik, st%nst, st%kweights, st%occ)
168 if (st%smear%method == smear_fixed_occ) then ! no temperature available
169 hm%energy%TS = m_zero
170 else
171 hm%energy%TS = st%smear%dsmear * hm%energy%entropy
172 end if
173
174 gfield => list_get_gauge_field(ext_partners)
175 if(associated(gfield)) hm%energy%total = hm%energy%total + gauge_field_get_energy(gfield)
176
177 if (allocated(hm%vberry)) then
178 hm%energy%total = hm%energy%total + hm%energy%berry
179 else
180 hm%energy%berry = m_zero
181 end if
182
183 if (optional_default(iunit, -1) > 0) then
184 write(message(1), '(6x,a, f18.8)')'Total = ', units_from_atomic(units_out%energy, hm%energy%total)
185 write(message(2), '(6x,a, f18.8)')'Free = ', units_from_atomic(units_out%energy, hm%energy%total - hm%energy%TS)
186 write(message(3), '(6x,a)') '-----------'
187 call messages_info(3, iunit)
188
189 write(message(1), '(6x,a, f18.8)')'Ion-ion = ', units_from_atomic(units_out%energy, hm%ep%eii)
190 write(message(2), '(6x,a, f18.8)')'Eigenvalues = ', units_from_atomic(units_out%energy, hm%energy%eigenvalues)
191 write(message(3), '(6x,a, f18.8)')'Hartree = ', units_from_atomic(units_out%energy, hm%energy%hartree)
192 write(message(4), '(6x,a, f18.8)')'Int[n*v_xc] = ', units_from_atomic(units_out%energy, hm%energy%intnvxc)
193 write(message(5), '(6x,a, f18.8)')'Exchange = ', &
194 units_from_atomic(units_out%energy, hm%energy%exchange+hm%energy%exchange_hf)
195 write(message(6), '(6x,a, f18.8)')'Correlation = ', units_from_atomic(units_out%energy, hm%energy%correlation)
196 write(message(7), '(6x,a, f18.8)')'vanderWaals = ', units_from_atomic(units_out%energy, hm%energy%vdw)
197 write(message(8), '(6x,a, f18.8)')'Delta XC = ', units_from_atomic(units_out%energy, hm%energy%delta_xc)
198 write(message(9), '(6x,a, f18.8)')'Entropy = ', hm%energy%entropy ! the dimensionless sigma of Kittel&Kroemer
199 write(message(10), '(6x,a, f18.8)')'-TS = ', -units_from_atomic(units_out%energy, hm%energy%TS)
200 write(message(11), '(6x,a, f18.8)')'Photon ex. = ', units_from_atomic(units_out%energy, hm%energy%photon_exchange)
201 call messages_info(11, iunit)
202
203 if (hm%pcm%run_pcm) then
204 write(message(1),'(6x,a, f18.8)')'E_e-solvent = ', units_from_atomic(units_out%energy, hm%energy%int_ee_pcm + &
205 hm%energy%int_en_pcm + &
206 hm%energy%int_e_ext_pcm)
207 write(message(2),'(6x,a, f18.8)')'E_n-solvent = ', units_from_atomic(units_out%energy, hm%energy%int_nn_pcm + &
208 hm%energy%int_ne_pcm + &
209 hm%energy%int_n_ext_pcm)
210 write(message(3),'(6x,a, f18.8)')'E_M-solvent = ', units_from_atomic(units_out%energy, &
211 hm%energy%int_ee_pcm + hm%energy%int_en_pcm + &
212 hm%energy%int_nn_pcm + hm%energy%int_ne_pcm + &
213 hm%energy%int_e_ext_pcm + hm%energy%int_n_ext_pcm)
214 call messages_info(3, iunit)
215 end if
216
217 if (full_) then
218 write(message(1), '(6x,a, f18.8)')'Kinetic = ', units_from_atomic(units_out%energy, hm%energy%kinetic)
219 write(message(2), '(6x,a, f18.8)')'External = ', units_from_atomic(units_out%energy, hm%energy%extern)
220 write(message(3), '(6x,a, f18.8)')'Non-local = ', units_from_atomic(units_out%energy, hm%energy%extern_non_local)
221 write(message(4), '(6x,a, f18.8)')'Int[n*v_E] = ', units_from_atomic(units_out%energy, hm%energy%intnvstatic)
222 call messages_info(4, iunit)
223 end if
224 if (allocated(hm%vberry) .and. space%is_periodic()) then
225 write(message(1), '(6x,a, f18.8)')'Berry = ', units_from_atomic(units_out%energy, hm%energy%berry)
226 call messages_info(1, iunit)
227 end if
228 if (hm%lda_u_level /= dft_u_none) then
229 write(message(1), '(6x,a, f18.8)')'Hubbard = ', units_from_atomic(units_out%energy, hm%energy%dft_u)
230 write(message(2), '(6x,a, f18.8)')'Int[n*v_U] = ', units_from_atomic(units_out%energy, hm%energy%int_dft_u)
231 call messages_info(2, iunit)
232 end if
233 end if
234
235 pop_sub(energy_calc_total)
236 end subroutine energy_calc_total
237
238 ! --------------------------------------------------------------------
239
240 subroutine energy_calc_eigenvalues(namespace, hm, der, st)
241 type(namespace_t), intent(in) :: namespace
242 type(hamiltonian_elec_t), intent(inout) :: hm
243 type(derivatives_t), intent(in) :: der
244 type(states_elec_t), intent(inout) :: st
245
247
248 if (states_are_real(st)) then
249 call dcalculate_eigenvalues(namespace, hm, der, st)
250 else
251 call zcalculate_eigenvalues(namespace, hm, der, st)
252 end if
253
255 end subroutine energy_calc_eigenvalues
256
257 ! ---------------------------------------------------------
258 subroutine energy_calc_virial_ex(der, vxc, st, ex)
259 type(derivatives_t), intent(in) :: der
260 real(real64), intent(in) :: vxc(:,:)
261 type(states_elec_t), intent(in) :: st
262 real(real64), intent(out) :: ex
263
264 integer :: idir, ip, isp
265 real(real64), allocatable :: gradvx(:,:), nrgradvx(:)
266 real(real64) :: rr, xx(der%dim)
267
268 push_sub(energy_calc_virial_ex)
269
270 assert(st%d%ispin /= spinors)
271
272 safe_allocate(nrgradvx(1:der%mesh%np_part))
273 safe_allocate(gradvx(1:der%mesh%np, 1:der%dim))
274
275 ex = m_zero
276 do isp = 1, st%d%nspin
277 !We output the energy from the virial relation
278 nrgradvx(1:der%mesh%np) = vxc(1:der%mesh%np,isp)
279 call dderivatives_grad(der, nrgradvx, gradvx)
280 nrgradvx = m_zero
281 do idir = 1, der%dim
282 do ip = 1, der%mesh%np
283 call mesh_r(der%mesh, ip, rr, coords=xx)
284 nrgradvx(ip) = nrgradvx(ip) - gradvx(ip, idir) * st%rho(ip, isp) * xx(idir)
285 end do
286 end do
287 ex = ex + dmf_integrate(der%mesh, nrgradvx)
288 end do
289
290 safe_deallocate_a(gradvx)
291 safe_deallocate_a(nrgradvx)
292
293 pop_sub(energy_calc_virial_ex)
294 end subroutine energy_calc_virial_ex
295
296
297#include "undef.F90"
298#include "real.F90"
299#include "energy_calc_inc.F90"
300
301#include "undef.F90"
302#include "complex.F90"
303#include "energy_calc_inc.F90"
304
305end module energy_calc_oct_m
306
307!! Local Variables:
308!! mode: f90
309!! coding: utf-8
310!! End:
This module implements batches of mesh functions.
Definition: batch.F90:133
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
subroutine, public dderivatives_grad(der, ff, op_ff, ghost_update, set_bc, to_cartesian)
apply the gradient to a mesh function
integer, parameter, public spinors
subroutine, public energy_calc_total(namespace, space, hm, gr, st, ext_partners, iunit, full)
This subroutine calculates the total energy of the system. Basically, it adds up the KS eigenvalues,...
real(real64) function, public zenergy_calc_electronic(namespace, hm, der, st, terms)
subroutine dcalculate_eigenvalues(namespace, hm, der, st)
calculates the eigenvalues of the orbitals
subroutine, public energy_calc_virial_ex(der, vxc, st, ex)
subroutine zcalculate_eigenvalues(namespace, hm, der, st)
calculates the eigenvalues of the orbitals
real(real64) function, public denergy_calc_electronic(namespace, hm, der, st, terms)
subroutine, public energy_calc_eigenvalues(namespace, hm, der, st)
subroutine, public zexchange_operator_compute_potentials(this, namespace, space, gr, st, xst, kpoints, ex, F_out)
subroutine, public dexchange_operator_compute_potentials(this, namespace, space, gr, st, xst, kpoints, ex, F_out)
type(gauge_field_t) function, pointer, public list_get_gauge_field(partners)
real(real64) function, public gauge_field_get_energy(this)
real(real64), parameter, public m_zero
Definition: global.F90:187
real(real64), parameter, public m_half
Definition: global.F90:193
This module implements the underlying real-space grid.
Definition: grid.F90:117
integer, parameter, public term_local_external
integer, parameter, public term_non_local_potential
integer, parameter, public term_kinetic
integer, parameter, public generalized_kohn_sham_dft
integer, parameter, public hartree
integer, parameter, public hartree_fock
integer, parameter, public independent_particles
integer, parameter, public kohn_sham_dft
This module defines classes and functions for interaction partners.
integer, parameter, public dft_u_none
Definition: lda_u.F90:200
This module defines functions over batches of mesh functions.
Definition: mesh_batch.F90:116
This module defines various routines, operating on mesh functions.
real(real64) function, public dmf_integrate(mesh, ff, mask, reduce)
Integrate a function on the mesh.
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:118
pure subroutine, public mesh_r(mesh, ip, rr, origin, coords)
return the distance to the origin for a given grid point
Definition: mesh.F90:336
subroutine, public messages_info(no_lines, iunit, verbose_limit, stress, all_nodes, namespace)
Definition: messages.F90:624
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:160
subroutine, public pcm_elect_energy(ions, pcm, E_int_ee, E_int_en, E_int_ne, E_int_nn, E_int_e_ext, E_int_n_ext)
Calculates the solute-solvent electrostatic interaction energy .
Definition: pcm.F90:1544
real(real64) function, public smear_calc_entropy(this, eigenvalues, nik, nst, kweights, occ)
Definition: smear.F90:589
integer, parameter, public smear_fixed_occ
Definition: smear.F90:171
pure logical function, public states_are_real(st)
This module handles spin dimensions of the states and the k-point distribution.
subroutine, public states_elec_end(st)
finalize the states_elec_t object
real(real64) function, public states_elec_eigenvalues_sum(st, alt_eig)
function to calculate the eigenvalues sum using occupations as weights
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
Definition: unit.F90:132
This module defines the unit system, used for input and output.
type(unit_system_t), public units_out
Definition: xc.F90:114
logical pure function, public family_is_hybrid(xcs)
Returns true if the functional is an hybrid functional.
Definition: xc.F90:607
class representing derivatives
The states_elec_t class contains all electronic wave functions.