73 subroutine x_fbe_calc (id, namespace, psolver, sl_solver, gr, st, space, ex, vxc)
74 integer,
intent(in) :: id
75 type(namespace_t),
intent(in) :: namespace
76 type(poisson_t),
intent(in) :: psolver
77 type(sturm_liouville_t),
intent(inout) :: sl_solver
78 type(grid_t),
target,
intent(in) :: gr
79 type(states_elec_t),
intent(inout) :: st
80 type(space_t),
intent(in) :: space
81 real(real64),
intent(inout) :: ex
82 real(real64),
contiguous,
optional,
intent(inout) :: vxc(:,:)
85 real(real64),
allocatable :: fxc(:,:,:), internal_vxc(:,:)
91 call dx_fbe_calc(namespace, psolver, sl_solver, gr, st, ex, vxc=vxc)
93 call zx_fbe_calc(namespace, psolver, sl_solver, gr, st, ex, vxc=vxc)
96 safe_allocate(fxc(1:gr%np_part, 1:gr%box%dim, 1:st%d%spin_channels))
97 safe_allocate(internal_vxc(1:gr%np, 1:st%d%spin_channels))
101 call dx_fbe_calc(namespace, psolver, sl_solver, gr, st, ex, vxc=internal_vxc, fxc=fxc)
103 call zx_fbe_calc(namespace, psolver, sl_solver, gr, st, ex, vxc=internal_vxc, fxc=fxc)
107 if (
present(vxc))
then
108 do ispin = 1, st%d%spin_channels
117 if (
present(vxc))
then
118 call lalg_axpy(gr%np, st%d%spin_channels,
m_one, internal_vxc, vxc)
121 safe_deallocate_a(fxc)
122 safe_deallocate_a(internal_vxc)
132 real(real64) function get_virial_energy(gr, nspin, fxc) result(exc)
133 type(grid_t),
intent(in) :: gr
134 integer,
intent(in) :: nspin
135 real(real64),
intent(in) :: fxc(:,:,:)
137 integer :: isp, idir, ip
138 real(real64),
allocatable :: rfxc(:)
139 real(real64) :: xx(gr%box%dim), rr
141 push_sub(get_virial_energy)
145 safe_allocate(rfxc(1:gr%np))
148 call mesh_r(gr, ip, rr, coords=xx)
149 do idir = 1, gr%box%dim
150 rfxc(ip) = rfxc(ip) + fxc(ip, idir, isp) * xx(idir)
154 safe_deallocate_a(rfxc)
157 pop_sub(get_virial_energy)
168 subroutine lda_c_fbe (st, n_blocks, l_dens, l_dedd, l_zk)
169 type(states_elec_t),
intent(in) :: st
170 integer,
intent(in) :: n_blocks
171 real(real64),
intent(in) :: l_dens(:,:)
172 real(real64),
intent(inout) :: l_dedd(:,:)
173 real(real64),
optional,
intent(inout) :: l_zk(:)
176 real(real64) :: rho, beta, beta2, e_c
182 q = ((5.0_real64*
sqrt(m_pi)**5)/(m_three*(m_one-
log(m_two))))**(m_third)
183 if (
present(l_zk)) l_zk = m_zero
186 rho = sum(l_dens(1:st%d%spin_channels, ip))
187 if (rho < 1e-20_real64)
then
188 l_dedd(1:st%d%spin_channels, ip) = m_zero
191 rho = max(rho, 1e-12_real64)
192 beta = q*rho**m_third
197 l_dedd(1:st%d%spin_channels, ip) = (m_pi/(q**3))*((
sqrt(m_pi)*beta/(m_one+
sqrt(m_pi)*beta))**2 -m_one) * beta
199 l_dedd(1:st%d%spin_channels, ip) = l_dedd(1:st%d%spin_channels, ip) &
200 - (5.0_real64*
sqrt(m_pi))/(m_three*q**3)*(
log(m_one+
sqrt(m_pi)*beta) &
201 -m_half/(m_one+
sqrt(m_pi)*beta)**2 + m_two/(m_one+
sqrt(m_pi)*beta)) + (5.0_real64*
sqrt(m_pi))/(m_two*q**3)
203 if (st%d%nspin == 1 .and.
present(l_zk))
then
206 e_c = (9.0_real64*q**3)/m_two/beta &
207 - m_two*q**3*
sqrt(m_pi) &
208 - 12.0_real64/beta2*(q**3/
sqrt(m_pi)) &
209 + m_three/(m_pi*rho)*(m_one/(m_one+
sqrt(m_pi)*beta) - m_one &
210 + 5.0_real64*
log(m_one+
sqrt(m_pi)*beta))
213 e_c = e_c - 5.0_real64/6.0_real64*( &
214 7.0_real64*q**3/beta &
215 + m_three/(m_pi*rho*(m_one+
sqrt(m_pi)*beta)) &
216 - 17.0_real64*q**3/
sqrt(m_pi)/beta2 &
217 - 11.0_real64*q**3*
sqrt(m_pi)/(m_three) &
218 + (20.0_real64/(m_pi*rho) + m_two*
sqrt(m_pi)*q**3)*
log(m_one+
sqrt(m_pi)*beta) &
219 - m_three/(m_pi*rho))
222 else if(st%d%nspin == 2)
then
225 do ispin = 1, st%d%spin_channels
226 l_dedd(ispin, ip) = l_dedd(ispin, ip) * m_two * l_dens(-ispin+3, ip) / rho
236 subroutine fbe_c_lda_sl (namespace, psolver, sl_solver, gr, st, space, ec, vxc)
237 type(namespace_t),
intent(in) :: namespace
238 type(poisson_t),
intent(in) :: psolver
239 type(sturm_liouville_t),
intent(inout) :: sl_solver
240 type(grid_t),
target,
intent(in) :: gr
241 type(states_elec_t),
intent(inout) :: st
242 type(space_t),
intent(in) :: space
243 real(real64),
intent(inout) :: ec
244 real(real64),
contiguous,
optional,
intent(inout) :: vxc(:,:)
246 integer :: idir, ip, ispin
247 real(real64),
allocatable :: fxc(:,:,:), internal_vxc(:,:), grad_rho(:,:,:), tmp1(:,:), tmp2(:,:)
248 real(real64) :: q, beta, rho, l_gdens
252 safe_allocate(internal_vxc(1:gr%np, 1:st%d%spin_channels))
255 safe_allocate(tmp1(1:st%d%spin_channels, 1:gr%np))
256 safe_allocate(tmp2(1:st%d%spin_channels, 1:gr%np))
257 tmp1 = transpose(st%rho(1:gr%np, 1:st%d%spin_channels))
259 internal_vxc = transpose(tmp2)
260 safe_deallocate_a(tmp1)
261 safe_deallocate_a(tmp2)
264 q = ((5.0_real64*
sqrt(m_pi)**5)/(m_three*(m_one-
log(m_two))))**(m_third)
266 safe_allocate(fxc(1:gr%np_part, 1:gr%box%dim, 1:st%d%spin_channels))
267 safe_allocate(grad_rho(1:gr%np, 1:gr%box%dim, 1:st%d%spin_channels))
268 do ispin = 1, st%d%spin_channels
269 call dderivatives_grad(gr%der, st%rho(:, ispin), grad_rho(:, :, ispin))
272 do ispin = 1, st%d%spin_channels
273 do idir = 1, gr%box%dim
275 rho = sum(st%rho(ip, 1:st%d%spin_channels))
276 if (st%rho(ip, ispin) < 1e-20_real64)
then
277 fxc(ip, idir, ispin) = m_zero
280 rho = max(rho, 1e-12_real64)
281 beta = rho**m_third * q
283 l_gdens = sum(grad_rho(ip, idir, 1:st%d%spin_channels))
285 if (st%d%spin_channels == 1)
then
286 fxc(ip, idir, ispin) = l_gdens * &
287 ( m_pi * beta**2/((m_one +
sqrt(m_pi)*beta)**2) - m_one &
288 + m_third * m_pi * beta**2 / ((m_one +
sqrt(m_pi)*beta)**3) )
290 fxc(ip, idir, ispin) = m_two * (grad_rho(ip, idir, 3-ispin) * &
291 (m_pi * beta**2/((m_one +
sqrt(m_pi)*beta)**2) - m_one ) &
292 + l_gdens * (m_third * m_pi * beta**2 / ((m_one +
sqrt(m_pi)*beta)**3) ) &
293 * st%rho(ip, 3-ispin) / rho)
296 fxc(ip, idir, ispin) = fxc(ip, idir, ispin) * m_pi/(m_three*beta**2) * st%rho(ip, ispin)
302 if (
present(vxc))
then
303 do ispin = 1, st%d%spin_channels
304 call sturm_liouville_solve_from_div(sl_solver, namespace, st%rho(:, ispin), fxc(:, :, ispin), internal_vxc(:, ispin))
312 if (
present(vxc))
then
313 call lalg_axpy(gr%np, st%d%spin_channels, m_one, internal_vxc, vxc)
316 safe_deallocate_a(fxc)
323#include "xc_fbe_inc.F90"
326#include "complex.F90"
327#include "xc_fbe_inc.F90"
constant times a vector plus a vector
double log(double __x) __attribute__((__nothrow__
double sqrt(double __x) __attribute__((__nothrow__
This module implements batches of mesh functions.
This module implements common operations on batches of mesh functions.
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
real(real64), parameter, public m_zero
real(real64), parameter, public m_one
This module implements the underlying real-space grid.
Computes and , suitable as an operator callback for iterative solvers (CG, QMR, etc....
This module is intended to contain "only mathematical" functions and procedures.
This module defines various routines, operating on mesh functions.
This module defines the meshes, which are used in Octopus.
pure subroutine, public mesh_r(mesh, ip, rr, origin, coords)
return the distance to the origin for a given grid point
This module defines non-local operators.
This module is an helper to perform ring-pattern communications among all states.
This module is intended to contain "only mathematical" functions and procedures.
pure logical function, public states_are_real(st)
This module provides routines for communicating all batches in a ring-pattern scheme.
This module handles spin dimensions of the states and the k-point distribution.
General Sturm-Liouville solver for equations of the form .
subroutine, public sturm_liouville_solve_from_div(this, namespace, rho, f, v, psolver)
Solve the Sturm-Liouville equation from a divergence.
subroutine, public lda_c_fbe(st, n_blocks, l_dens, l_dedd, l_zk)
Computes the local density correlation potential and energy obtained from the Colle-Salvetti approxim...
subroutine dx_fbe_calc(namespace, psolver, sl_solver, gr, st, ex, vxc, fxc)
subroutine, public fbe_c_lda_sl(namespace, psolver, sl_solver, gr, st, space, ec, vxc)
Sturm-Liouville version of the FBE local-density correlation functional.
subroutine zx_fbe_calc(namespace, psolver, sl_solver, gr, st, ex, vxc, fxc)
subroutine, public x_fbe_calc(id, namespace, psolver, sl_solver, gr, st, space, ex, vxc)
Interface to X(x_fbe_calc) Two possible run modes possible: adiabatic and Sturm-Liouville....
real(real64) function get_virial_energy(gr, nspin, fxc)
Computes the energy from the force virial relation.
integer, parameter, public xc_oep_x_fbe_sl
Exchange approximation based on the force balance equation - Sturn-Liouville version.
integer, parameter, public xc_oep_x_fbe
Exchange approximation based on the force balance equation.