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 assert(.not. nl_operator_compact_boundaries())
265 call dderivatives_lapl(der, vh_correction, rho_corrected, set_bc = .false.)
267 do ip = 1, der%mesh%np
268 rho_corrected(ip) = rho(ip) + m_one/(m_four*m_pi)*rho_corrected(ip)
273 call profiling_out(
"POISSON_CORRECT")
281 type(mesh_t),
intent(in) :: mesh
282 real(real64),
intent(in) :: rho(:)
283 integer,
intent(in) :: ml
284 real(real64),
intent(out) :: mult((ml+1)**2)
286 integer :: add_lm, ll, mm
294 mult(add_lm) = dmf_dotp(mesh, rho, this%aux(:, add_lm))
304 real(real64),
contiguous,
intent(in) :: xx(:)
305 real(real64),
contiguous,
intent(out) :: yy(:)
306 type(c_ptr),
intent(in) :: userdata(:)
308 real(real64),
allocatable :: xx_tmp(:)
316 safe_deallocate_a(xx_tmp)
324 real(real64),
intent(in) :: xx(:)
325 real(real64),
intent(in) :: yy(:)
337 type(mesh_t),
intent(in) :: mesh
338 real(real64),
intent(in) :: rho(:)
339 real(real64),
intent(inout) :: pot(:)
341 integer :: ip, add_lm, ll, mm, bp_lower
342 real(real64) :: xx(mesh%box%dim), rr, s1, sa
343 real(real64),
allocatable :: mult(:)
347 assert(mesh%box%dim == 3)
349 safe_allocate(mult(1:(this%maxl+1)**2))
353 bp_lower = mesh%np + 1
354 if (mesh%parallel_in_domains)
then
355 bp_lower = bp_lower + mesh%pv%np_ghost
358 pot(bp_lower:mesh%np_part) = m_zero
359 do ip = bp_lower, mesh%np_part
360 call mesh_r(mesh, ip, rr, coords = xx)
363 s1 = m_four*m_pi/((m_two*ll + m_one)*rr**(ll + 1))
365 call ylmr_real(xx, ll, mm, sa)
366 pot(ip) = pot(ip) + sa * mult(add_lm) * s1
372 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)