OpenPFC  0.1.4
Phase Field Crystal simulation framework
Loading...
Searching...
No Matches
decomposition_neighbors.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2025 VTT Technical Research Centre of Finland Ltd
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
32#pragma once
33
34#include <map>
37#include <optional>
38
39namespace pfc {
40namespace decomposition {
41
66inline int get_neighbor_rank(const Decomposition &decomp, int rank,
67 const Int3 &direction) {
68 const auto &grid = get_grid(decomp);
69 int num_domains = get_num_domains(decomp);
70
71 if (rank < 0 || rank >= num_domains) {
72 return -1; // Invalid rank
73 }
74
75 // Convert rank to 3D grid coordinates
76 int rank_z = rank / (grid[0] * grid[1]);
77 int rank_y = (rank % (grid[0] * grid[1])) / grid[0];
78 int rank_x = rank % grid[0];
79
80 // Calculate neighbor coordinates
81 int neighbor_x = rank_x + direction[0];
82 int neighbor_y = rank_y + direction[1];
83 int neighbor_z = rank_z + direction[2];
84
85 // Wrap around for periodic boundary conditions
86 // This ensures every rank has neighbors in all directions
87 neighbor_x = (neighbor_x + grid[0]) % grid[0];
88 neighbor_y = (neighbor_y + grid[1]) % grid[1];
89 neighbor_z = (neighbor_z + grid[2]) % grid[2];
90
91 // Convert neighbor coordinates back to rank
92 int neighbor_rank =
93 neighbor_z * (grid[0] * grid[1]) + neighbor_y * grid[0] + neighbor_x;
94
95 return neighbor_rank;
96}
97
121inline std::map<Int3, int> find_face_neighbors(const Decomposition &decomp,
122 int rank) {
123 std::map<Int3, int> neighbors;
124
125 // 6 face directions: ±X, ±Y, ±Z
126 std::vector<Int3> directions = {{1, 0, 0}, {-1, 0, 0}, {0, 1, 0},
127 {0, -1, 0}, {0, 0, 1}, {0, 0, -1}};
128
129 for (const auto &dir : directions) {
130 int neighbor_rank = get_neighbor_rank(decomp, rank, dir);
131 // With periodic boundaries, neighbor_rank is always valid (>= 0)
132 neighbors[dir] = neighbor_rank;
133 }
134
135 return neighbors;
136}
137
160inline std::map<Int3, int> find_all_neighbors(const Decomposition &decomp,
161 int rank) {
162 std::map<Int3, int> neighbors;
163
164 // All 26 directions in 3D: {-1,0,1} × {-1,0,1} × {-1,0,1} excluding {0,0,0}
165 for (int dx = -1; dx <= 1; ++dx) {
166 for (int dy = -1; dy <= 1; ++dy) {
167 for (int dz = -1; dz <= 1; ++dz) {
168 if (dx == 0 && dy == 0 && dz == 0) {
169 continue; // Skip self
170 }
171
172 Int3 direction{dx, dy, dz};
173 int neighbor_rank = get_neighbor_rank(decomp, rank, direction);
174 // With periodic boundaries, neighbor_rank is always valid (>= 0)
175 neighbors[direction] = neighbor_rank;
176 }
177 }
178 }
179
180 return neighbors;
181}
182
183} // namespace decomposition
184} // namespace pfc
Core type definitions for World parameters.
Domain decomposition for parallel MPI simulations.