66 logical :: periodic = .false.
67 logical :: fully_periodic = .false.
69 integer,
allocatable :: per_points(:, :)
70 integer,
allocatable :: per_send(:, :)
71 integer,
allocatable :: per_recv(:, :)
72 logical :: per_contiguous
73 integer,
allocatable :: nsend(:)
74 integer,
allocatable :: nrecv(:)
75 type(accel_mem_t) :: buff_per_points
76 type(accel_mem_t) :: buff_per_send
77 type(accel_mem_t) :: buff_per_recv
78 type(accel_mem_t) :: buff_nsend
79 type(accel_mem_t) :: buff_nrecv
80 logical,
public :: spiralBC = .false.
81 logical,
public :: spiral = .false.
82 real(real64),
allocatable,
public :: spiral_q(:)
100 integer,
parameter,
public :: &
101 POINT_BOUNDARY = 1, &
110 type(batch_t) :: ghost_send
111 type(MPI_Request),
allocatable :: requests(:)
114 real(real64),
pointer :: drecv_buffer(:)
115 complex(real64),
pointer :: zrecv_buffer(:)
116 real(real64),
pointer :: dsend_buffer(:)
117 complex(real64),
pointer :: zsend_buffer(:)
118 type(batch_t),
pointer :: v_local
119 type(par_vec_t),
pointer :: pv
134 type(boundaries_t),
intent(inout) :: this
135 type(namespace_t),
intent(in) :: namespace
136 class(space_t),
intent(in) :: space
137 type(mesh_t),
target,
intent(in) :: mesh
138 real(real64),
optional,
intent(in) :: qvector(:)
140 integer :: sp, ip, ip_inner, iper, ip_bnd
141 integer(int64) :: ip_inner_global
143 integer(int64),
allocatable :: recv_rem_points(:, :), points(:), per_send(:, :)
144 integer,
allocatable :: part(:), points_local(:)
145 integer :: nper_recv, iper_recv
146 integer,
allocatable :: rdispls(:), sdispls(:)
151 this%periodic = space%is_periodic()
152 this%fully_periodic = space%periodic_dim == space%dim
154 if (space%is_periodic())
then
165 call parse_variable(namespace,
'SpiralBoundaryCondition', .false., this%spiralBC)
166 if (this%spiralBC)
then
168 if(.not.
present(qvector))
then
169 message(1) =
"TDMomentumTransfer or TDReducedMomentumTransfer must be defined if SpiralBoundaryCondition=yes"
172 safe_allocate(this%spiral_q(1:space%dim))
173 this%spiral_q(1:space%dim) = qvector(1:space%dim)
177 if (mesh%parallel_in_domains) sp = mesh%np + mesh%pv%np_ghost
182 do ip = sp + 1, mesh%np_part
187 if (ip == ip_inner) cycle
191 if (ip_inner_global > mesh%np_global) cycle
193 if (ip_inner /= 0 .and. ip_inner <= mesh%np)
then
194 this%nper = this%nper + 1
196 nper_recv = nper_recv + 1
199 if (.not. mesh%parallel_in_domains)
then
200 assert(nper_recv == 0)
203 safe_allocate(this%per_points(1:2, 1:max(this%nper, 1)))
206 this%per_points(1:2, ip) = -1
209 if (mesh%parallel_in_domains)
then
210 safe_allocate(this%per_recv(1:max(nper_recv, 1), 1:max(mesh%pv%npart, 1)))
211 safe_allocate(this%nrecv(1:mesh%pv%npart))
212 safe_allocate(recv_rem_points(1:nper_recv, 1:mesh%pv%npart))
213 safe_allocate(points(1:nper_recv))
214 safe_allocate(points_local(1:nper_recv))
215 safe_allocate(part(1:nper_recv))
221 do ip = sp + 1, mesh%np_part
226 if (ip == ip_inner) cycle
229 if (ip_inner_global > mesh%np_global) cycle
231 if (ip_inner /= 0 .and. ip_inner <= mesh%np)
then
233 this%per_points(point_boundary, iper) = ip
238 iper_recv = iper_recv + 1
239 points(iper_recv) = ip_inner_global
240 points_local(iper_recv) = ip
243 if (mesh%parallel_in_domains)
then
246 do iper_recv = 1, nper_recv
247 ipart = part(iper_recv)
248 assert(this%nrecv(ipart) + 1 < huge(0_int32))
250 this%nrecv(ipart) = this%nrecv(ipart) + 1
252 this%per_recv(this%nrecv(ipart), ipart) = points_local(iper_recv)
254 recv_rem_points(this%nrecv(ipart), ipart) = points(iper_recv)
258 if (mesh%parallel_in_domains)
then
260 safe_allocate(this%nsend(1:mesh%pv%npart))
261 call mesh%mpi_grp%alltoall(this%nrecv, 1, mpi_integer, this%nsend, 1, mpi_integer)
263 safe_allocate(sdispls(1:mesh%pv%npart))
264 safe_allocate(rdispls(1:mesh%pv%npart))
265 safe_allocate(this%per_send(1:max(maxval(this%nsend), 1), 1:mesh%pv%npart))
266 safe_allocate(per_send(1:maxval(this%nsend), 1:mesh%pv%npart))
268 assert(int(nper_recv, int64)*mesh%pv%npart < huge(0_int32))
269 do ipart = 1, mesh%pv%npart
270 rdispls(ipart) = nper_recv * (ipart - 1)
271 sdispls(ipart) = maxval(this%nsend) * (ipart - 1)
275 call mesh%mpi_grp%alltoallv(recv_rem_points, this%nrecv, rdispls, mpi_integer8, &
276 per_send, this%nsend, sdispls, mpi_integer8)
278 do ipart = 1, mesh%pv%npart
280 do ip = 1, this%nsend(ipart)
283 assert(this%per_send(ip, ipart) > 0)
284 assert(this%per_send(ip, ipart) <= mesh%np)
288 safe_deallocate_a(per_send)
289 safe_deallocate_a(sdispls)
290 safe_deallocate_a(rdispls)
291 safe_deallocate_a(recv_rem_points)
292 safe_deallocate_a(points)
293 safe_deallocate_a(points_local)
294 safe_deallocate_a(part)
299 this%per_contiguous = .
true.
300 do ip = 1, this%nper-1
301 ip_bnd = this%per_points(point_boundary, ip)
302 if (ip_bnd + 1 /= this%per_points(point_boundary, ip+1))
then
303 this%per_contiguous = .false.
312 if (mesh%parallel_in_domains)
then
314 call accel_write_buffer(this%buff_per_send, product(ubound(this%per_send)), this%per_send)
317 call accel_write_buffer(this%buff_per_recv, product(ubound(this%per_recv)), this%per_recv)
339 if (this%periodic)
then
340 safe_deallocate_a(this%spiral_q)
342 safe_deallocate_a(this%per_send)
343 safe_deallocate_a(this%per_recv)
344 safe_deallocate_a(this%nsend)
345 safe_deallocate_a(this%nrecv)
356 safe_deallocate_a(this%per_points)
364 subroutine boundaries_set_batch(this, mesh, ffb, phase_correction, buff_phase_corr, offset, async)
366 class(
mesh_t),
intent(in) :: mesh
367 class(
batch_t),
intent(inout) :: ffb
368 complex(real64),
optional,
intent(in) :: phase_correction(:)
369 type(
accel_mem_t),
optional,
intent(in) :: buff_phase_corr
370 integer,
optional,
intent(in) :: offset
371 logical,
optional,
intent(in) :: async
388#include "complex.F90"
389#include "boundaries_inc.F90"
393#include "boundaries_inc.F90"
subroutine, public accel_release_buffer(this)
pure logical function, public accel_is_enabled()
integer, parameter, public accel_mem_read_only
This module implements batches of mesh functions.
This module implements common operations on batches of mesh functions.
Module implementing boundary conditions in Octopus.
subroutine dboundaries_set_batch(boundaries, mesh, ffb, phase_correction, buff_phase_corr, offset, async)
Set all boundary points in ffb.
subroutine, public dpar_vec_ghost_update(pv, v_local)
Updates ghost points of every node.
integer, parameter, public point_inner
subroutine, public zghost_update_batch_start(pv, v_local, handle)
subroutine zboundaries_set_batch(boundaries, mesh, ffb, phase_correction, buff_phase_corr, offset, async)
Set all boundary points in ffb.
subroutine, public boundaries_end(this)
subroutine, public zpar_vec_ghost_update(pv, v_local)
Updates ghost points of every node.
subroutine, public zghost_update_batch_finish(handle)
subroutine, public dghost_update_batch_finish(handle)
subroutine zboundaries_set_single(boundaries, mesh, ff, phase_correction, buff_phase_corr, offset)
set boundary conditions for a single mesh function
subroutine, public dghost_update_batch_start(pv, v_local, handle)
subroutine dboundaries_set_single(boundaries, mesh, ff, phase_correction, buff_phase_corr, offset)
set boundary conditions for a single mesh function
subroutine, public boundaries_init(this, namespace, space, mesh, qvector)
initialize the boundary contitions
subroutine boundaries_set_batch(this, mesh, ffb, phase_correction, buff_phase_corr, offset, async)
This module implements the index, used for the mesh points.
This module is intended to contain "only mathematical" functions and procedures.
This module defines the meshes, which are used in Octopus.
integer(int64) function, public mesh_periodic_point(mesh, space, ip)
This function returns the point inside the grid corresponding to a boundary point when PBCs are used....
integer function, public mesh_global2local(mesh, ipg)
This function returns the local mesh index for a given global index.
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_experimental(name, namespace)
Some general things and nomenclature:
type(type_t), public type_float
type(type_t), public type_cmplx
type(type_t), public type_integer
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
This module defines the unit system, used for input and output.
Class defining batches of mesh functions.
This class contains information about the boundary conditions.
auxiliary handle for ghost updates
Describes mesh distribution to nodes.