64 real(real64),
pointer :: rho_aux(:) => null()
65 real(real64),
pointer :: lapl_rho_aux(:) => null()
66 real(real64),
allocatable :: diag_lapl(:)
77 subroutine x_fbe_calc (id, namespace, psolver, gr, st, space, ex, vxc)
78 integer,
intent(in) :: id
79 type(namespace_t),
intent(in) :: namespace
80 type(poisson_t),
intent(in) :: psolver
81 type(grid_t),
target,
intent(in) :: gr
82 type(states_elec_t),
intent(inout) :: st
83 type(space_t),
intent(in) :: space
84 real(real64),
intent(inout) :: ex
85 real(real64),
contiguous,
optional,
intent(inout) :: vxc(:,:)
87 real(real64),
allocatable :: fxc(:,:,:), internal_vxc(:,:)
94 call dx_fbe_calc(namespace, psolver, gr, st, ex, vxc=vxc)
96 call zx_fbe_calc(namespace, psolver, gr, st, ex, vxc=vxc)
99 safe_allocate(fxc(1:gr%np_part, 1:gr%box%dim, 1:st%d%spin_channels))
100 safe_allocate(internal_vxc(1:gr%np, 1:st%d%spin_channels))
104 call dx_fbe_calc(namespace, psolver, gr, st, ex, vxc=internal_vxc, fxc=fxc)
106 call zx_fbe_calc(namespace, psolver, gr, st, ex, vxc=internal_vxc, fxc=fxc)
110 if (
present(vxc))
then
118 call lalg_axpy(gr%np, st%d%spin_channels,
m_one, internal_vxc, vxc)
120 safe_deallocate_a(fxc)
121 safe_deallocate_a(internal_vxc)
133 type(namespace_t),
intent(in) :: namespace
134 type(grid_t),
target,
intent(in) :: gr
135 type(states_elec_t),
target,
intent(in) :: st
136 type(space_t),
intent(in) :: space
137 real(real64),
contiguous,
intent(inout) :: fxc(:,:,:)
138 real(real64),
contiguous,
intent(inout) :: vxc(:,:)
140 real(real64),
allocatable :: rhs(:)
141 integer :: iter, ispin
143 real(real64),
parameter :: threshold = 1e-7_real64
144 character(len=80) :: name
146 type(nl_operator_t) :: op(1)
150 assert(ubound(fxc, dim=1) >= gr%np_part)
155 name =
'FBE preconditioner'
157 safe_allocate(diag_lapl(1:op(1)%np))
161 safe_allocate(rhs(1:gr%np))
162 safe_allocate(lapl_rho_aux(1:gr%np))
164 do ispin = 1, st%d%spin_channels
167 rho_aux => st%rho(:, ispin)
173 iter, userdata=[c_loc(gr)], residue = res, threshold = threshold, showprogress = .false.)
175 write(
message(1),
'(a, i6, a)')
"Info: Sturm-Liouville solver converged in ", iter,
" iterations."
176 write(
message(2),
'(a, es14.6)')
"Info: The residue is ", res
180 safe_deallocate_p(lapl_rho_aux)
181 safe_deallocate_a(rhs)
182 safe_deallocate_a(diag_lapl)
196 real(real64),
contiguous,
intent(in) :: x(:)
197 real(real64),
contiguous,
intent(out) :: hx(:)
198 type(c_ptr),
intent(in) :: userdata(:)
201 real(real64),
allocatable :: vxc(:)
202 real(real64),
allocatable :: prod(:)
203 real(real64),
allocatable :: lapl_vxc(:)
204 real(real64),
allocatable :: lapl_product(:)
205 type(
grid_t),
pointer :: gr
207 assert(
size(userdata) == 1)
208 assert(c_associated(userdata(1)))
209 call c_f_pointer(userdata(1), gr)
211 safe_allocate(vxc(1:gr%np_part))
212 safe_allocate(lapl_vxc(1:gr%np))
216 safe_allocate(prod(1:gr%np_part))
217 safe_allocate(lapl_product(1:gr%np))
218 do ip = 1, gr%np_part
219 prod(ip) = rho_aux(ip) * vxc(ip)
224 hx(ip) =
m_half * (rho_aux(ip) * lapl_vxc(ip) - vxc(ip) * lapl_rho_aux(ip) + lapl_product(ip))
227 safe_deallocate_a(vxc)
228 safe_deallocate_a(prod)
229 safe_deallocate_a(lapl_vxc)
230 safe_deallocate_a(lapl_product)
239 real(real64),
contiguous,
intent(in) :: x(:)
240 real(real64),
contiguous,
intent(out) :: hx(:)
241 type(c_ptr),
intent(in) :: userdata(:)
244 type(
grid_t),
pointer :: gr
246 assert(
size(userdata) == 1)
247 assert(c_associated(userdata(1)))
248 call c_f_pointer(userdata(1), gr)
252 hx(ip) = x(ip) / (max(rho_aux(ip), 1.0e-12_real64) * diag_lapl(ip))
259 real(real64) function get_virial_energy(gr, nspin, fxc) result(exc)
260 type(
grid_t),
intent(in) :: gr
261 integer,
intent(in) :: nspin
262 real(real64),
intent(in) :: fxc(:,:,:)
264 integer :: isp, idir, ip
265 real(real64),
allocatable :: rfxc(:)
266 real(real64) :: xx(gr%box%dim), rr
268 push_sub(get_virial_energy)
272 safe_allocate(rfxc(1:gr%np))
275 call mesh_r(gr, ip, rr, coords=xx)
276 do idir = 1, gr%box%dim
277 rfxc(ip) = rfxc(ip) + fxc(ip, idir, isp) * xx(idir)
281 safe_deallocate_a(rfxc)
284 pop_sub(get_virial_energy)
295 subroutine lda_c_fbe (st, n_blocks, l_dens, l_dedd, l_zk)
296 type(states_elec_t),
intent(in) :: st
297 integer,
intent(in) :: n_blocks
298 real(real64),
intent(in) :: l_dens(:,:)
299 real(real64),
intent(inout) :: l_dedd(:,:)
300 real(real64),
optional,
intent(inout) :: l_zk(:)
303 real(real64) :: rho, beta, beta2, e_c
309 q = ((5.0_real64*
sqrt(m_pi)**5)/(m_three*(m_one-
log(m_two))))**(m_third)
310 if (
present(l_zk)) l_zk = m_zero
313 rho = sum(l_dens(1:st%d%spin_channels, ip))
314 if (rho < 1e-20_real64)
then
315 l_dedd(1:st%d%spin_channels, ip) = m_zero
318 rho = max(rho, 1e-12_real64)
319 beta = q*rho**m_third
324 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
326 l_dedd(1:st%d%spin_channels, ip) = l_dedd(1:st%d%spin_channels, ip) &
327 - (5.0_real64*
sqrt(m_pi))/(m_three*q**3)*(
log(m_one+
sqrt(m_pi)*beta) &
328 -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)
330 if (st%d%nspin == 1 .and.
present(l_zk))
then
333 e_c = (9.0_real64*q**3)/m_two/beta &
334 - m_two*q**3*
sqrt(m_pi) &
335 - 12.0_real64/beta2*(q**3/
sqrt(m_pi)) &
336 + m_three/(m_pi*rho)*(m_one/(m_one+
sqrt(m_pi)*beta) - m_one &
337 + 5.0_real64*
log(m_one+
sqrt(m_pi)*beta))
340 e_c = e_c - 5.0_real64/6.0_real64*( &
341 7.0_real64*q**3/beta &
342 + m_three/(m_pi*rho*(m_one+
sqrt(m_pi)*beta)) &
343 - 17.0_real64*q**3/
sqrt(m_pi)/beta2 &
344 - 11.0_real64*q**3*
sqrt(m_pi)/(m_three) &
345 + (20.0_real64/(m_pi*rho) + m_two*
sqrt(m_pi)*q**3)*
log(m_one+
sqrt(m_pi)*beta) &
346 - m_three/(m_pi*rho))
349 else if(st%d%nspin == 2)
then
352 do ispin = 1, st%d%spin_channels
353 l_dedd(ispin, ip) = l_dedd(ispin, ip) * m_two * l_dens(-ispin+3, ip) / rho
363 subroutine fbe_c_lda_sl (namespace, gr, st, space, ec, vxc)
364 type(namespace_t),
intent(in) :: namespace
365 type(grid_t),
target,
intent(in) :: gr
366 type(states_elec_t),
intent(inout) :: st
367 type(space_t),
intent(in) :: space
368 real(real64),
intent(inout) :: ec
369 real(real64),
contiguous,
optional,
intent(inout) :: vxc(:,:)
371 integer :: idir, ip, ispin
372 real(real64),
allocatable :: fxc(:,:,:), internal_vxc(:,:), grad_rho(:,:,:), tmp1(:,:), tmp2(:,:)
373 real(real64) :: q, beta, rho, l_gdens
377 safe_allocate(internal_vxc(1:gr%np, 1:st%d%spin_channels))
380 safe_allocate(tmp1(1:st%d%spin_channels, 1:gr%np))
381 safe_allocate(tmp2(1:st%d%spin_channels, 1:gr%np))
382 tmp1 = transpose(st%rho(1:gr%np, 1:st%d%spin_channels))
384 internal_vxc = transpose(tmp2)
385 safe_deallocate_a(tmp1)
386 safe_deallocate_a(tmp2)
389 q = ((5.0_real64*
sqrt(m_pi)**5)/(m_three*(m_one-
log(m_two))))**(m_third)
391 safe_allocate(fxc(1:gr%np_part, 1:gr%box%dim, 1:st%d%spin_channels))
392 safe_allocate(grad_rho(1:gr%np, 1:gr%box%dim, 1:st%d%spin_channels))
393 do ispin = 1, st%d%spin_channels
394 call dderivatives_grad(gr%der, st%rho(:, ispin), grad_rho(:, :, ispin))
397 do ispin = 1, st%d%spin_channels
398 do idir = 1, gr%box%dim
400 rho = sum(st%rho(ip, 1:st%d%spin_channels))
401 if (st%rho(ip, ispin) < 1e-20_real64)
then
402 fxc(ip, idir, ispin) = m_zero
405 rho = max(rho, 1e-12_real64)
406 beta = rho**m_third * q
408 l_gdens = sum(grad_rho(ip, idir, 1:st%d%spin_channels))
410 if (st%d%spin_channels == 1)
then
411 fxc(ip, idir, ispin) = l_gdens * &
412 ( m_pi * beta**2/((m_one +
sqrt(m_pi)*beta)**2) - m_one &
413 + m_third * m_pi * beta**2 / ((m_one +
sqrt(m_pi)*beta)**3) )
415 fxc(ip, idir, ispin) = m_two * (grad_rho(ip, idir, 3-ispin) * &
416 (m_pi * beta**2/((m_one +
sqrt(m_pi)*beta)**2) - m_one ) &
417 + l_gdens * (m_third * m_pi * beta**2 / ((m_one +
sqrt(m_pi)*beta)**3) ) &
418 * st%rho(ip, 3-ispin) / rho)
421 fxc(ip, idir, ispin) = fxc(ip, idir, ispin) * m_pi/(m_three*beta**2) * st%rho(ip, ispin)
427 if (
present(vxc))
then
435 call lalg_axpy(gr%np, st%d%spin_channels, m_one, internal_vxc, vxc)
437 safe_deallocate_a(fxc)
444#include "xc_fbe_inc.F90"
447#include "complex.F90"
448#include "xc_fbe_inc.F90"
constant times a vector plus a vector
Copies a vector x, to a vector y.
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.
subroutine, public derivatives_get_lapl(this, namespace, op, space, name, order)
subroutine, public dderivatives_lapl(der, ff, op_ff, ghost_update, set_bc, factor)
apply the Laplacian to a mesh function
subroutine, public dderivatives_div(der, ff, op_ff, ghost_update, set_bc, to_cartesian)
apply the divergence operator to a vector of mesh functions
real(real64), parameter, public m_zero
real(real64), parameter, public m_half
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.
real(real64) function, public dmf_dotu_aux(f1, f2)
dot product between two vectors (mesh functions) without conjugation
subroutine, public mesh_init_mesh_aux(mesh)
Initialise a pointer to the grid/mesh, that is globally exposed, such that low level mesh operations ...
real(real64) function, public dmf_nrm2_aux(ff)
calculate norm2 of a vector (mesh function)
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
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
This module defines non-local operators.
subroutine, public dnl_operator_operate_diag(op, fo)
subroutine, public nl_operator_end(op)
This module is an helper to perform ring-pattern communications among all states.
This module is intended to contain "only mathematical" functions and procedures.
subroutine, public dqmr_sym_gen_dotu(np, x, b, op, dotu, nrm2, prec, iter, userdata, residue, threshold, showprogress, converged, use_initial_guess)
for complex symmetric matrices W Chen and B Poirier, J Comput Phys 219, 198-209 (2006)
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.
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, gr, st, ex, vxc, fxc)
subroutine solve_sturm_liouville(namespace, gr, st, space, fxc, vxc)
Solve the Sturm-Liouville equation On entry, vxc is the adiabatic one, on exit, it is the solution of...
subroutine sl_operator(x, hx, userdata)
Computes Ax = \nabla\cdot(\rho\nabla x) = 1/2(\nabla^2 (\rho x) - x \nabla^2 \rho + \rho \nabla^2 x) ...
subroutine zx_fbe_calc(namespace, psolver, gr, st, ex, vxc, fxc)
subroutine, public x_fbe_calc(id, namespace, psolver, gr, st, space, ex, vxc)
Interface to X(x_fbe_calc) Two possible run modes possible: adiabatic and Sturm-Liouville....
subroutine, public fbe_c_lda_sl(namespace, gr, st, space, ec, vxc)
Sturm-Liouville version of the FBE local-density correlation functional.
subroutine preconditioner(x, hx, userdata)
Simple preconditioner Here we need to approximate P^-1 We use the Jacobi approximation and that \nabl...
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.
Description of the grid, containing information on derivatives, stencil, and symmetries.