8#ifndef IPPL_FIELD_LAYOUT_H
9#define IPPL_FIELD_LAYOUT_H
18#include "Communicate/Communicator.h"
20#include "Partition/Partitioner.h"
24 template <
unsigned Dim>
27 template <
unsigned Dim>
28 std::ostream& operator<<(std::ostream&,
const FieldLayout<Dim>&);
44 KOKKOS_INLINE_FUNCTION
constexpr unsigned int countHypercubes(
unsigned int dim) {
46 for (
unsigned int d = 0; d < dim; d++) {
57 constexpr unsigned int factorial(
unsigned x) {
58 return x == 0 ? 1 : x * factorial(x - 1);
68 constexpr unsigned int binomialCoefficient(
unsigned a,
unsigned b) {
69 return factorial(a) / (factorial(b) * factorial(a - b));
79 template <
unsigned Dim>
80 constexpr unsigned int countCubes(
unsigned m) {
81 return (1 << (Dim - m)) * binomialCoefficient(Dim, m);
92 bool isUpper(
unsigned int face);
101 unsigned int getFaceDim(
unsigned int face);
109 template <
unsigned Dim>
110 unsigned int indexToFace(
unsigned int index) {
112 unsigned int axis = index / 2;
116 unsigned int toRemove = (2 - index % 2) * countHypercubes(axis);
118 return countHypercubes(Dim) - 1 - toRemove;
129 unsigned Dim,
typename... CubeTags,
130 typename = std::enable_if_t<
sizeof...(CubeTags) == Dim - 1>,
131 typename = std::enable_if_t<std::conjunction_v<std::is_same<e_cube_tag, CubeTags>...>>>
132 unsigned int getCube(e_cube_tag tag, CubeTags... tags) {
133 if constexpr (Dim == 1) {
136 return tag + 3 * getCube<Dim - 1>(tags...);
143 template <
size_t... Idx>
144 unsigned int getFace_impl(
const std::array<e_cube_tag,
sizeof...(Idx)>& args,
145 const std::index_sequence<Idx...>&) {
146 return getCube<
sizeof...(Idx)>(args[Idx]...);
156 template <
unsigned Dim>
157 unsigned int getFace(
unsigned int axis, e_cube_tag side) {
158 std::array<e_cube_tag, Dim> args;
159 args.fill(IS_PARALLEL);
161 return getFace_impl(args, std::make_index_sequence<Dim>{});
165 template <
unsigned Dim>
169 using view_type =
typename detail::ViewType<NDIndex_t, 1>::view_type;
170 using host_mirror_type =
typename view_type::host_mirror_type;
174 std::array<long, Dim> lo;
176 std::array<long, Dim> hi;
184 for (
unsigned d = 0; d < Dim; d++) {
185 total *= hi[d] - lo[d];
191 using rank_list = std::vector<int>;
192 using bounds_list = std::vector<bound_type>;
194 using neighbor_list = std::array<rank_list, detail::countHypercubes(Dim) - 1>;
195 using neighbor_range_list = std::array<bounds_list, detail::countHypercubes(Dim) - 1>;
204 bool isAllPeriodic =
false);
215 void initialize(
const NDIndex<Dim>& domain, std::array<bool, Dim> decomp,
216 bool isAllPeriodic =
false);
224 template <
unsigned Dim2>
225 bool operator==(
const FieldLayout<Dim2>& x)
const {
229 throw std::runtime_error(
"FieldLayout: only FieldLayouts with the same global domain should be compared");
235 bool operator==(
const FieldLayout<Dim>& x)
const {
239 throw std::runtime_error(
"FieldLayout: only FieldLayouts with the same global domain should be compared");
242 for (
unsigned int i = 0; i < Dim; ++i) {
252 bool getDistribution(
unsigned int d)
const {
253 return minWidth_m[d] == (
unsigned int)
gDomain_m[d].length();
258 std::array<bool, Dim> isParallel()
const {
return isParallelDim_m; }
261 const NDIndex_t& getLocalNDIndex()
const;
264 const NDIndex_t& getLocalNDIndex(
int rank)
const;
266 const host_mirror_type getHostLocalDomains()
const;
268 const view_type getDeviceLocalDomains()
const;
325 NDIndex<Dim>& grown, NDIndex<Dim>& neighborDomain,
326 const int rank, std::map<unsigned int, int>& offsets,
327 unsigned d0 = 0,
unsigned codim = 0);
344 void addNeighbors(
const NDIndex_t& gnd,
const NDIndex_t& nd,
const NDIndex_t& ndNeighbor,
345 const NDIndex_t& intersect,
int nghost,
int rank);
347 void write(std::ostream& = std::cout)
const;
349 void updateLayout(
const std::vector<NDIndex_t>& domains);
351 bool isAllPeriodic_m;
353 mpi::Communicator comm;
365 bound_type getBounds(
const NDIndex_t& nd1,
const NDIndex_t& nd2,
const NDIndex_t& offset,
368 int getPeriodicOffset(
const NDIndex_t& nd,
const unsigned int d,
const int k);
371 neighbor_list neighbors_m;
375 neighbor_range_list neighborsSendRange_m, neighborsRecvRange_m;
387 std::array<bool, Dim> isParallelDim_m;
390 unsigned int minWidth_m[Dim];
395 template <
unsigned Dim>
396 inline std::ostream& operator<<(std::ostream& out,
const FieldLayout<Dim>& f) {
402#include "FieldLayout/FieldLayout.hpp"
Definition FieldLayout.h:166
void findNeighbors(int nghost=1)
Definition FieldLayout.hpp:228
const neighbor_list & getNeighbors() const
Definition FieldLayout.hpp:140
void addNeighbors(const NDIndex_t &gnd, const NDIndex_t &nd, const NDIndex_t &ndNeighbor, const NDIndex_t &intersect, int nghost, int rank)
Definition FieldLayout.hpp:275
void findPeriodicNeighbors(const int nghost, const NDIndex< Dim > &localDomain, NDIndex< Dim > &grown, NDIndex< Dim > &neighborDomain, const int rank, std::map< unsigned int, int > &offsets, unsigned d0=0, unsigned codim=0)
Definition FieldLayout.hpp:190
view_type dLocalDomains_m
Local domains (device view)
Definition FieldLayout.h:382
host_mirror_type hLocalDomains_m
Local domains (host mirror view)
Definition FieldLayout.h:385
const neighbor_range_list & getNeighborsSendRange() const
Definition FieldLayout.hpp:145
const neighbor_range_list & getNeighborsRecvRange() const
Definition FieldLayout.hpp:151
NDIndex_t gDomain_m
Global domain.
Definition FieldLayout.h:379
static int getMatchingIndex(int index)
Definition FieldLayout.hpp:22
Definition Communicator.h:31
Definition FieldLayout.h:172
long size() const
Definition FieldLayout.h:182