52 real(real64),
parameter :: alpha_ =
m_five
58 real(real64),
allocatable :: phi(:, :)
59 real(real64),
allocatable :: aux(:, :)
60 real(real64),
allocatable :: gaussian(:)
63 type(derivatives_t),
pointer :: der_pointer
64 type(mesh_t),
pointer :: mesh_pointer
66 integer,
parameter :: &
74 type(poisson_corr_t),
intent(out) :: this
75 type(namespace_t),
intent(in) :: namespace
76 class(space_t),
intent(in) :: space
77 integer,
intent(in) :: ml
78 type(mesh_t),
intent(in) :: mesh
80 real(real64) :: alpha, gamma, ylm, rr, xx(space%dim)
81 integer :: ip, ll, add_lm, lldfac, jj, mm
85 assert(space%dim == 3)
87 if (space%is_periodic())
then
106 call parse_variable(namespace,
'PoissonSolverBoundaries', corr_multipole, this%method)
108 select case (this%method)
109 case (corr_multipole)
119 safe_allocate(this%phi(1:mesh%np, 1:add_lm))
120 safe_allocate(this%aux(1:mesh%np, 1:add_lm))
121 safe_allocate(this%gaussian(1:mesh%np))
123 alpha = alpha_ * mesh%spacing(1)
125 call mesh_r(mesh, ip, rr, coords = xx)
126 this%gaussian(ip) =
exp(-(rr/alpha)**2)
133 gamma =
sqrt(
m_pi)*2**(ll+3) / lldfac
137 this%phi(ip, add_lm) = gamma*
isubl(ll, rr/alpha)*ylm/rr**(ll+1)
138 this%aux(ip, add_lm) = rr**ll*ylm
140 this%phi(ip, add_lm) = gamma*ylm / alpha
142 this%aux(ip, add_lm) = ylm
144 this%aux(ip, add_lm) =
m_zero
163 real(real64) function
isubl( ll, xx)
164 integer,
intent(in) :: ll
165 real(real64),
intent(in) :: xx
181 select case (this%method)
183 safe_deallocate_a(this%phi)
184 safe_deallocate_a(this%aux)
185 safe_deallocate_a(this%gaussian)
194 subroutine correct_rho(this, der, rho, rho_corrected, vh_correction)
196 type(derivatives_t),
intent(in) :: der
197 real(real64),
contiguous,
intent(in) :: rho(:)
198 real(real64),
contiguous,
intent(out) :: rho_corrected(:)
199 real(real64),
contiguous,
intent(out) :: vh_correction(:)
201 integer :: ip, add_lm, ll, mm, lldfac, jj, ip2
202 real(real64) :: alpha, vv, rr
203 real(real64),
allocatable :: mult(:)
204 real(real64),
allocatable :: betal(:)
207 call profiling_in(
"POISSON_CORRECT")
209 assert(ubound(vh_correction, dim = 1) == der%mesh%np_part)
211 select case (this%method)
214 safe_allocate(mult(1:(this%maxl+1)**2))
217 alpha =
alpha_ * der%mesh%spacing(1)
219 safe_allocate(betal(1:(this%maxl+1)**2))
227 betal(add_lm) = (2**(ll + 2)) / (alpha**(2*ll+3) *
sqrt(m_pi) * lldfac)
232 call lalg_copy(der%mesh%np, rho, rho_corrected)
233 vh_correction = m_zero
237 do ip = 1, der%mesh%np
238 rho_corrected(ip) = rho_corrected(ip) - mult(add_lm)*betal(add_lm)*this%aux(ip, add_lm)*this%gaussian(ip)
240 call lalg_axpy(der%mesh%np, mult(add_lm), this%phi(:, add_lm), vh_correction)
245 safe_deallocate_a(mult)
246 safe_deallocate_a(betal)
250 do ip = 1, der%mesh%np
251 vh_correction(ip) = m_zero
254 do ip = der%mesh%np + 1, der%mesh%np_part
256 do ip2 = 1, der%mesh%np
257 rr = norm2((der%mesh%x(ip, 1:der%dim) - der%mesh%x(ip2, 1:der%dim)))
258 vv = vv + rho(ip2)/rr
260 vh_correction(ip) = der%mesh%volume_element*vv
263 call dderivatives_lapl(der, vh_correction, rho_corrected, set_bc = .false.)
265 do ip = 1, der%mesh%np
266 rho_corrected(ip) = rho(ip) + m_one/(m_four*m_pi)*rho_corrected(ip)
271 call profiling_out(
"POISSON_CORRECT")
279 type(mesh_t),
intent(in) :: mesh
280 real(real64),
intent(in) :: rho(:)
281 integer,
intent(in) :: ml
282 real(real64),
intent(out) :: mult((ml+1)**2)
284 integer :: add_lm, ll, mm
292 mult(add_lm) = dmf_dotp(mesh, rho, this%aux(:, add_lm))
302 real(real64),
contiguous,
intent(in) :: xx(:)
303 real(real64),
contiguous,
intent(out) :: yy(:)
304 type(c_ptr),
intent(in) :: userdata(:)
306 real(real64),
allocatable :: xx_tmp(:)
312 call dderivatives_lapl(
der_pointer, xx_tmp, yy, factor=-m_one)
314 safe_deallocate_a(xx_tmp)
322 real(real64),
intent(in) :: xx(:)
323 real(real64),
intent(in) :: yy(:)
335 type(mesh_t),
intent(in) :: mesh
336 real(real64),
intent(in) :: rho(:)
337 real(real64),
intent(inout) :: pot(:)
339 integer :: ip, add_lm, ll, mm, bp_lower
340 real(real64) :: xx(mesh%box%dim), rr, s1, sa
341 real(real64),
allocatable :: mult(:)
345 assert(mesh%box%dim == 3)
347 safe_allocate(mult(1:(this%maxl+1)**2))
351 bp_lower = mesh%np + 1
352 if (mesh%parallel_in_domains)
then
353 bp_lower = bp_lower + mesh%pv%np_ghost
356 pot(bp_lower:mesh%np_part) = m_zero
357 do ip = bp_lower, mesh%np_part
358 call mesh_r(mesh, ip, rr, coords = xx)
361 s1 = m_four*m_pi/((m_two*ll + m_one)*rr**(ll + 1))
363 call ylmr_real(xx, ll, mm, sa)
364 pot(ip) = pot(ip) + sa * mult(add_lm) * s1
370 safe_deallocate_a(mult)
Define which routines can be seen from the outside.
double exp(double __x) __attribute__((__nothrow__
double sqrt(double __x) __attribute__((__nothrow__
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
real(real64), parameter, public m_zero
real(real64), parameter, public m_pi
some mathematical constants
real(real64), parameter, public m_epsilon
real(real64), parameter, public m_half
real(real64), parameter, public m_one
real(real64), parameter, public m_five
This module is intended to contain "only mathematical" functions and procedures.
subroutine, public ylmr_real(xx, li, mi, ylm)
This is a Numerical Recipes-based subroutine computes real spherical harmonics ylm at position (x,...
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
subroutine, public messages_not_implemented(feature, namespace)
subroutine, public messages_experimental(name, namespace)
This module defines non-local operators.
integer, parameter corr_multipole
subroutine get_multipoles(this, mesh, rho, ml, mult)
subroutine, public poisson_corrections_end(this)
subroutine, public internal_laplacian_op(xx, yy, userdata)
real(real64) function, public internal_dotp(xx, yy)
subroutine, public poisson_boundary_conditions(this, mesh, rho, pot)
subroutine, public poisson_corrections_init(this, namespace, space, ml, mesh)
integer, parameter corr_exact
real(real64), parameter alpha_
type(mesh_t), pointer, public mesh_pointer
subroutine, public correct_rho(this, der, rho, rho_corrected, vh_correction)
type(derivatives_t), pointer, public der_pointer
real(real64) function isubl(ll, xx)