49static void p3m_add_block(
double const *in,
double *out,
int const start[3],
50 int const size[3],
int const dim[3]) {
54 int li_in = 0, li_out = 0;
56 int m_out_offset, s_out_offset;
58 li_out = start[2] + (dim[2] * (start[1] + (dim[1] * start[0])));
59 m_out_offset = dim[2] - size[2];
60 s_out_offset = (dim[2] * (dim[1] - size[1]));
62 for (s = 0; s < size[0]; s++) {
63 for (m = 0; m < size[1]; m++) {
64 for (
f = 0;
f < size[2];
f++) {
65 out[li_out++] += in[li_in++];
67 li_out += m_out_offset;
69 li_out += s_out_offset;
75 int done[3] = {0, 0, 0};
77 for (
int i = 0; i < 3; i++) {
78 for (
int j = 0; j < 3; j++) {
80 s_ld[i * 2][j] = 0 + done[j] * local_mesh.
margin[j * 2];
82 s_ur[i * 2][j] = local_mesh.
margin[j * 2];
85 local_mesh.
dim[j] - done[j] * local_mesh.
margin[(j * 2) + 1];
88 s_ld[(i * 2) + 1][j] = local_mesh.
in_ur[j];
90 s_ld[(i * 2) + 1][j] = 0 + done[j] * local_mesh.
margin[j * 2];
91 s_ur[(i * 2) + 1][j] =
92 local_mesh.
dim[j] - done[j] * local_mesh.
margin[(j * 2) + 1];
97 for (
int i = 0; i < 6; i++) {
99 for (
int j = 0; j < 3; j++) {
100 s_dim[i][j] = s_ur[i][j] - s_ld[i][j];
101 s_size[i] *= s_dim[i][j];
107 auto const node_neighbors = Utils::Mpi::cart_neighbors<3>(comm);
110 for (
int i = 0; i < 6; i++) {
111 auto const j = (i % 2 == 0) ? i + 1 : i - 1;
113 if (node_neighbors[i] != comm.rank()) {
114 MPI_Sendrecv(&(local_mesh.
margin[i]), 1, MPI_INT, node_neighbors[i],
115 REQ_P3M_INIT, &(r_margin[j]), 1, MPI_INT, node_neighbors[j],
116 REQ_P3M_INIT, comm, MPI_STATUS_IGNORE);
118 r_margin[j] = local_mesh.
margin[i];
122 for (
int i = 0; i < 3; i++)
123 for (
int j = 0; j < 3; j++) {
125 r_ld[i * 2][j] = s_ld[i * 2][j] + local_mesh.
margin[2 * j];
126 r_ur[i * 2][j] = s_ur[i * 2][j] + r_margin[2 * j];
127 r_ld[(i * 2) + 1][j] = s_ld[(i * 2) + 1][j] - r_margin[(2 * j) + 1];
128 r_ur[(i * 2) + 1][j] =
129 s_ur[(i * 2) + 1][j] - local_mesh.
margin[(2 * j) + 1];
131 r_ld[i * 2][j] = s_ld[i * 2][j];
132 r_ur[i * 2][j] = s_ur[i * 2][j];
133 r_ld[(i * 2) + 1][j] = s_ld[(i * 2) + 1][j];
134 r_ur[(i * 2) + 1][j] = s_ur[(i * 2) + 1][j];
137 for (
int i = 0; i < 6; i++) {
139 for (
int j = 0; j < 3; j++) {
140 r_dim[i][j] = r_ur[i][j] - r_ld[i][j];
141 r_size[i] *= r_dim[i][j];
149 const boost::mpi::communicator &comm,
151 auto const node_neighbors = Utils::Mpi::cart_neighbors<3>(comm);
152 send_grid.resize(max * meshes.
size());
153 recv_grid.resize(max * meshes.
size());
156 for (
int s_dir = 0; s_dir < 6; s_dir++) {
157 auto const r_dir = (s_dir % 2 == 0) ? s_dir + 1 : s_dir - 1;
160 if (s_size[s_dir] > 0)
161 for (std::size_t i = 0; i < meshes.
size(); i++) {
163 s_ld[s_dir], s_dim[s_dir], dim.
data(), 1);
167 if (node_neighbors[s_dir] != comm.rank()) {
169 send_grid.data(),
static_cast<int>(meshes.
size()) * s_size[s_dir],
170 MPI_DOUBLE, node_neighbors[s_dir], REQ_P3M_GATHER, recv_grid.data(),
171 static_cast<int>(meshes.
size()) * r_size[r_dir], MPI_DOUBLE,
172 node_neighbors[r_dir], REQ_P3M_GATHER, comm, MPI_STATUS_IGNORE);
174 std::swap(send_grid, recv_grid);
177 if (r_size[r_dir] > 0) {
178 for (std::size_t i = 0; i < meshes.
size(); i++) {
179 p3m_add_block(recv_grid.data() + i * r_size[r_dir], meshes[i],
180 r_ld[r_dir], r_dim[r_dir], dim.
data());
187 const boost::mpi::communicator &comm,
189 auto const node_neighbors = Utils::Mpi::cart_neighbors<3>(comm);
190 send_grid.resize(max * meshes.
size());
191 recv_grid.resize(max * meshes.
size());
194 for (
int s_dir = 5; s_dir >= 0; s_dir--) {
195 auto const r_dir = (s_dir % 2 == 0) ? s_dir + 1 : s_dir - 1;
198 if (r_size[r_dir] > 0)
199 for (std::size_t i = 0; i < meshes.
size(); i++) {
201 r_ld[r_dir], r_dim[r_dir], dim.
data(), 1);
204 if (node_neighbors[r_dir] != comm.rank()) {
206 send_grid.data(), r_size[r_dir] *
static_cast<int>(meshes.
size()),
207 MPI_DOUBLE, node_neighbors[r_dir], REQ_P3M_SPREAD, recv_grid.data(),
208 s_size[s_dir] *
static_cast<int>(meshes.
size()), MPI_DOUBLE,
209 node_neighbors[s_dir], REQ_P3M_SPREAD, comm, MPI_STATUS_IGNORE);
211 std::swap(send_grid, recv_grid);
214 if (s_size[s_dir] > 0) {
215 for (std::size_t i = 0; i < meshes.
size(); i++) {
217 s_ld[s_dir], s_dim[s_dir], dim.
data(), 1);
void fft_unpack_block(double const *const in, double *const out, int const start[3], int const size[3], int const dim[3], int element)
Unpack a 3d-grid input block (size[3]) into an output 3d-grid with dimension dim[3] at start position...
void fft_pack_block(double const *const in, double *const out, int const start[3], int const size[3], int const dim[3], int element)
Pack a block (size[3] starting at start[3]) of an input 3d-grid with dimension dim[3] into an output ...
static void p3m_add_block(double const *in, double *out, int const start[3], int const size[3], int const dim[3])
Add values of a 3d-grid input block (size[3]) to values of 3d-grid output array with dimension dim[3]...