22#include "fcs_fconfig.h"
35 use,
intrinsic :: iso_fortran_env
68 integer,
parameter :: fcs_integer_kind_isoc = 4
73 real(real64) :: delta_E_fmm
74 real(real64) :: alpha_fmm
75 type(mpi_grp_t) :: all_nodes_grp
76 type(mpi_grp_t) :: perp_grp
77 integer(kind = fcs_integer_kind_isoc) :: nlocalcharges
80 integer,
allocatable :: disps(:)
81 integer,
allocatable :: dsize(:)
82 type(nl_operator_t) :: corrector
83 type(derivatives_t),
pointer :: der
93 type(poisson_fmm_t),
intent(out) :: this
94 class(space_t),
intent(in) :: space
95 type(derivatives_t),
target,
intent(in) :: der
96 type(MPI_Comm),
intent(in) :: all_nodes_comm
100 logical,
allocatable :: remains(:)
101 integer,
allocatable :: dend(:)
102 integer :: subcomm, cdim
103 character(len = 8) :: method
105 type(mesh_t),
pointer :: mesh
107 logical :: short_range_flag
108 real(kind = fcs_real_kind_isoc),
dimension(3) :: box_a
109 real(kind = fcs_real_kind_isoc),
dimension(3) :: box_b
110 real(kind = fcs_real_kind_isoc),
dimension(3) :: box_c
111 real(kind = fcs_real_kind_isoc),
dimension(3) :: offset
112 logical,
dimension(3) :: periodicity
113 integer(kind = fcs_integer_kind_isoc) :: total_particles
115 integer(kind = fcs_integer_kind_isoc) :: local_particle_count
116 real(kind = fcs_real_kind_isoc),
dimension(8) :: local_charges
117 real(kind = fcs_real_kind_isoc),
dimension(24) :: local_coordinates
121 short_range_flag = .
true.
123 periodicity = (/.false.,.false.,.false./)
124 local_particle_count = -1
145 call parse_variable(parser,
'DeltaEFMM', 1e-4_real64, this%delta_E_fmm)
181 call parse_variable(parser,
'AlphaFMM', 0.291262136_real64, this%alpha_fmm)
196 safe_allocate(this%disps(1))
197 safe_allocate(dend(1))
198 safe_allocate(this%dsize(1))
202 this%ep = der%mesh%np
203 this%dsize(1) = der%mesh%np
205 this%nlocalcharges = this%dsize(1)
207 subcomm = this%all_nodes_grp%comm
211 call mpi_cartdim_get(this%all_nodes_grp%comm, cdim,
mpi_err)
213 safe_allocate(remains(1:cdim))
218 call mpi_cart_sub(this%all_nodes_grp%comm, remains(1), subcomm,
mpi_err)
221 safe_allocate(this%disps(1:this%perp_grp%size))
222 safe_allocate(dend(1:this%perp_grp%size))
223 safe_allocate(this%dsize(1:this%perp_grp%size))
227 this%sp = this%disps(this%perp_grp%rank + 1)
228 this%ep = dend(this%perp_grp%rank + 1)
229 this%nlocalcharges = this%dsize(this%perp_grp%rank + 1)
230 this%nlocalcharges = der%mesh%np
231 this%disps = this%disps - 1
238 if (space%is_periodic())
then
239 select type (box => mesh%box)
241 if (.not. all(box%half_length == box%half_length(1)))
then
249 total_particles = mesh%np_global
250 ret = fcs_init(this%handle, trim(adjustl(method)) // c_null_char, subcomm)
252 box_a = (/mesh%box%bounding_box_l(1)*2+1,
m_zero,
m_zero/)
253 box_b = (/
m_zero,mesh%box%bounding_box_l(2)*2+1,
m_zero/)
254 box_c = (/
m_zero,
m_zero,mesh%box%bounding_box_l(3)*2+1/)
256 ret = fcs_common_set(this%handle, short_range_flag, box_a, box_b, box_c, offset, periodicity, total_particles)
259 ret = fcs_fmm_set_tolerance_energy(this%handle, this%delta_E_fmm)
263 call nl_operator_build(this%der%mesh, this%corrector, der%mesh%np, const_w = .not. this%der%mesh%use_curvilinear)
265 do is = 1, this%corrector%stencil%size
267 select case (sum(abs(this%corrector%stencil%points(1:der%dim, is))))
269 this%corrector%w_re(is, 1) = 27.0_real64/32.0_real64 + &
272 this%corrector%w_re(is, 1) = 0.0625_real64
274 this%corrector%w_re(is, 1) = -0.0625_real64*0.25_real64
277 this%corrector%w_re(is, 1) = this%corrector%w_re(is, 1)*der%mesh%spacing(1)*der%mesh%spacing(2)
298 safe_deallocate_a(this%disps)
299 safe_deallocate_a(this%dsize)
300 ret = fcs_destroy(this%handle)
315 real(real64),
intent(inout) :: pot(:)
316 real(real64),
intent(in) :: rho(:)
319 integer(int64) :: totalcharges
321 real(kind = fcs_real_kind_isoc),
allocatable :: q(:)
322 real(kind = fcs_real_kind_isoc),
allocatable :: pot_lib_fmm(:)
323 real(kind = fcs_real_kind_isoc),
allocatable :: xyz(:)
324 real(kind = fcs_real_kind_isoc),
allocatable :: fields(:)
325 integer(kind = fcs_integer_kind_isoc) :: index
326 real(real64),
allocatable :: rho_tmp(:), pot_tmp(:)
328 integer :: ii, jj, ip, gip
330 integer,
allocatable :: ix(:)
331 type(
mesh_t),
pointer :: mesh
341 safe_allocate(q(this%sp:this%ep))
342 safe_allocate(xyz(1:3 * (this%nlocalcharges)))
343 safe_allocate(pot_lib_fmm(this%sp:this%ep))
344 safe_allocate(fields(1:3 * (this%nlocalcharges)))
346 totalcharges = mesh%np_global
348 if (.not. mesh%use_curvilinear)
then
349 do ii = this%sp, this%ep
350 q(ii) = rho(ii) * mesh%vol_pp(1)
353 do ii = this%sp, this%ep
354 q(ii) = rho(ii) * mesh%vol_pp(ii)
360 do ii = this%sp, this%ep
363 xyz(index) = mesh%x(ii, jj)
371 ret = fcs_tune(this%handle, this%nlocalcharges, this%nlocalcharges, xyz(1), q(this%sp))
372 ret = fcs_run(this%handle, this%nlocalcharges, this%nlocalcharges, xyz(1), q(this%sp), fields(1), &
373 pot_lib_fmm(this%sp))
379 call this%perp_grp%allgatherv(pot_lib_fmm(this%sp:), this%nlocalcharges, mpi_double_precision, &
380 pot, this%dsize, this%disps, mpi_double_precision)
387 if (mesh%box%dim == 2)
then
390 pot(ii) = pot(ii) + aux*rho(ii)
395 safe_deallocate_a(xyz)
396 safe_deallocate_a(pot_lib_fmm)
401 safe_allocate(ix(1:mesh%box%dim))
402 safe_allocate(rho_tmp(1:mesh%np_part))
403 safe_allocate(pot_tmp(1:mesh%np))
412 if (mesh%box%dim == 3)
then
413 if (.not. mesh%use_curvilinear .and. (mesh%spacing(1) == mesh%spacing(2)) .and. &
414 (mesh%spacing(2) == mesh%spacing(3)) .and. &
415 (mesh%spacing(1) == mesh%spacing(3)))
then
420 pot(ip) = pot(ip) + pot_tmp(ip)
426 pot(ii) = pot(ii) + aux*rho_tmp(ii)
431 safe_deallocate_a(ix)
432 safe_deallocate_a(rho_tmp)
433 safe_deallocate_a(pot_tmp)
Copies a vector x, to a vector y.
Module implementing boundary conditions in Octopus.
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
subroutine, public dderivatives_perform(op, der, ff, op_ff, ghost_update, set_bc, factor)
apply a nl_operator to a mesh function
Fast Fourier Transform module. This module provides a single interface that works with different FFT ...
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_one
real(real64), parameter, public m_three
This module implements the index, used for the mesh points.
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.
subroutine, public messages_not_implemented(feature, namespace)
type(mpi_grp_t), public mpi_world
subroutine mpi_grp_init(grp, comm)
Initialize MPI group instance.
integer, public mpi_err
used to store return values of mpi calls
This module handles the communicators for the various parallelization strategies.
subroutine, public multicomm_divide_range(nobjs, nprocs, istart, ifinal, lsize, scalapack_compat)
Divide the range of numbers [1, nobjs] between nprocs processors.
This module defines non-local operators.
subroutine, public nl_operator_init(op, label)
initialize an instance of a non-local operator by setting the label
subroutine, public nl_operator_output_weights(this)
subroutine, public nl_operator_end(op)
subroutine, public nl_operator_build(space, mesh, op, np, const_w, regenerate)
Some general things and nomenclature:
subroutine, public poisson_fmm_init(this, space, der, all_nodes_comm)
Initialises the FMM parameters and vectors. Also it calls to the library initialisation.
subroutine, public poisson_fmm_solve(this, der, pot, rho)
Both direct solvers and FMM calculate the Hartree potential via direct additions, without solving the...
subroutine, public poisson_fmm_end(this)
Release memory and call to end the library.
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.
This module defines routines, generating operators for a star stencil.
subroutine, public stencil_star_get_lapl(this, dim, order)
Class implementing a parallelepiped box. Currently this is restricted to a rectangular cuboid (all th...
class representing derivatives
Describes mesh distribution to nodes.