63 type(finufft_t) :: finufft
65 real(real64),
allocatable :: kernel(:,:,:)
72 type(poisson_nfft_t),
intent(out) :: this
73 type(namespace_t),
intent(in) :: namespace
74 class(space_t),
intent(in) :: space
75 class(mesh_t),
intent(in) :: mesh
76 real(real64),
intent(in) :: threshold
78 type(finufft_t) :: options
79 real(real64) :: bounds(2, space%dim), aa(3), spacing, spacing_min, r_c, ll(3)
85 message(1) =
'PoissonSolver = nfft requires FINUFFT but that library was not linked.'
89 assert(space%dim == 3)
93 if (mesh%parallel_in_domains)
then
99 bounds = mesh%box%bounds()
101 do idir = 1, space%dim
102 aa(idir) = maxval(abs(bounds(:, idir)))
107 if (mesh%use_curvilinear)
then
108 spacing = maxval(mesh%vol_pp(1:mesh%np))**(
m_one/
m_three)
109 spacing_min = minval(mesh%vol_pp(1:mesh%np))**(
m_one/
m_three)
112 spacing_min = spacing
120 r_c =
m_two*norm2(aa)
122 this%nn = 2*ceiling(
m_half*ll/spacing)
128 call finufft_init(this%finufft, options, this%nn, space%dim, [mesh%np, 1, 1])
129 call finufft_set_nodes(this%finufft, mesh%x_t(1:mesh%np, 1), mesh%x_t(1:mesh%np, 2), &
130 mesh%x_t(1:mesh%np, 3), ll)
162 real(real64),
intent(in) :: ll(3)
163 real(real64),
intent(in) :: r_c
165 real(real64) :: dg(3), gg(3), gmod2
166 integer :: i1, i2, i3
172 safe_allocate(this%kernel(1:this%nn(1), 1:this%nn(2), 1:this%nn(3)))
176 do i3 = 1, this%nn(3)
177 gg(3) = (i3 - this%nn(3)/2 - 1)*dg(3)
178 do i2 = 1, this%nn(2)
179 gg(2) = (i2 - this%nn(2)/2 - 1)*dg(2)
180 do i1 = 1, this%nn(1)
181 gg(1) = (i1 - this%nn(1)/2 - 1)*dg(1)
187 this%kernel(i1, i2, i3) =
m_half*r_c**2
196 this%kernel(1, :, :) =
m_zero
197 this%kernel(:, 1, :) =
m_zero
198 this%kernel(:, :, 1) =
m_zero
208 class(
mesh_t),
intent(in) :: mesh
209 real(real64),
contiguous,
intent(out) :: pot(:)
210 real(real64),
contiguous,
intent(in) :: rho(:)
212 complex(real64),
allocatable :: values(:)
217 safe_allocate(values(1:mesh%np))
219 if (mesh%use_curvilinear)
then
222 values(ip) = mesh%vol_pp(ip)*rho(ip)
231 call lalg_scal(mesh%np, mesh%vol_pp(1), values)
238 pot(ip) = real(values(ip), real64)
242 safe_deallocate_a(values)
252 class(
mesh_t),
intent(in) :: mesh
253 complex(real64),
contiguous,
intent(out) :: pot(:)
254 complex(real64),
contiguous,
intent(in) :: rho(:)
256 complex(real64),
allocatable :: values(:)
261 safe_allocate(values(1:mesh%np))
263 if (mesh%use_curvilinear)
then
266 values(ip) = mesh%vol_pp(ip)*rho(ip)
271 call lalg_scal(mesh%np, mesh%vol_pp(1), values)
278 safe_deallocate_a(values)
287 complex(real64),
contiguous,
intent(inout) :: values(:)
289 complex(real64),
allocatable :: modes(:,:,:)
290 integer :: i1, i2, i3
296 safe_allocate(modes(1:this%nn(1), 1:this%nn(2), 1:this%nn(3)))
301 do i3 = 1, this%nn(3)
302 do i2 = 1, this%nn(2)
303 do i1 = 1, this%nn(1)
304 modes(i1, i2, i3) = this%kernel(i1, i2, i3)*modes(i1, i2, i3)
312 safe_deallocate_a(modes)
326 safe_deallocate_a(this%kernel)
Copies a vector x, to a vector y.
scales a vector by a constant
Non-equispaced FFTs through the C interface of the FINUFFT library.
subroutine, public finufft_set_nodes(finufft, xj, yj, zj, period)
Hand scattered nodes to FINUFFT, mapping one period of the mode grid onto the [-1/2,...
subroutine, public finufft_init(finufft, finufft_options, N, dim, M, nthreads)
subroutine, public finufft_end(finufft)
subroutine, public finufft_nodes_to_modes(finufft, values, modes)
Project the scattered nodes onto the Fourier modes.
subroutine, public finufft_modes_to_nodes(finufft, modes, values)
Evaluate the Fourier modes on the scattered nodes.
subroutine, public finufft_set_tolerance(finufft, tol)
Set the requested tolerance directly, for callers that take it from an input variable of their own ra...
real(real64), parameter, public m_two
real(real64), parameter, public m_zero
real(real64), parameter, public m_four
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_three
This module defines the meshes, which are used in Octopus.
subroutine, public messages_not_implemented(feature, namespace)
subroutine, public messages_new_line()
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
real(real64) function, public poisson_cutoff_3d_0d(x, r)
Poisson solver on the mesh points themselves, through non-equispaced FFTs.
subroutine poisson_nfft_build_3d_0d(this, ll, r_c)
The Coulomb kernel of a finite system on the mode grid.
subroutine, public dpoisson_nfft_solve(this, mesh, pot, rho)
subroutine, public poisson_nfft_end(this)
subroutine, public zpoisson_nfft_solve(this, mesh, pot, rho)
The transform is complex either way, so a complex density costs the same as a real one and needs no s...
subroutine, public poisson_nfft_init(this, namespace, space, mesh, threshold)
subroutine poisson_nfft_convolve(this, values)
Convolve the weighted density on the nodes with the kernel, in place.
subroutine, public profiling_out(label)
Increment out counter and sum up difference between entry and exit time.
subroutine, public profiling_in(label, exclude)
Increment in counter and save entry time.
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
character(len=20) pure function, public units_abbrev(this)
This module defines the unit system, used for input and output.
type(unit_system_t), public units_out
Describes mesh distribution to nodes.