22 template <
typename Field>
27 template <
typename Field>
35 template <
typename Field>
40 unsigned int face = this->
face_m;
41 unsigned d = face / 2;
45 const auto& domain = layout.getDomain();
48 bool isBoundary = (lDomains[myRank][d].max() == domain[d].
max())
49 || (lDomains[myRank][d].min() == domain[d].
min());
67 throw IpplException(
"ExtrapolateFace::apply",
"nghost > 1 not supported");
71 throw IpplException(
"ExtrapolateFace::apply",
"face number wrong");
76 src = view.extent(d) - 2;
85 Kokkos::Array<index_type, Dim> begin, end;
86 for (
unsigned i = 0; i <
Dim; i++) {
88 end[i] = view.extent(i) - nghost;
95 KOKKOS_CLASS_LAMBDA(index_array_type & args) {
99 T value =
apply(view, args);
107 template <
typename Field>
109 out <<
"Constant Extrapolation Face"
110 <<
", Face = " << this->
face_m;
113 template <
typename Field>
116 <<
", Face = " << this->
face_m;
119 template <
typename Field>
121 out <<
"ConstantFace"
122 <<
", Face = " << this->
face_m <<
", Constant = " << this->
offset_m;
125 template <
typename Field>
128 <<
", Face = " << this->
face_m;
131 template <
typename Field>
133 out <<
"PeriodicFace"
134 <<
", Face = " << this->
face_m;
137 template <
typename Field>
141 unsigned int face = this->
face_m;
142 unsigned int d = face / 2;
144 int myRank = comm.rank();
147 const auto& domain = layout.getDomain();
153 if (lDomains[myRank][d].length() < domain[d].length()) {
156 bool isBoundary = (lDomains[myRank][d].max() == domain[d].
max())
157 || (lDomains[myRank][d].min() == domain[d].
min());
162 auto& nd = lDomains[myRank];
165 auto gnd = nd.grow(nghost, d);
170 offset = -domain[d].length();
173 offset = domain[d].length();
176 gnd[d] = gnd[d] + offset;
179 for (
int rank = 0; rank < comm.size(); ++rank) {
180 if (rank == myRank) {
184 if (gnd.touches(lDomains[rank])) {
192 template <
typename Field>
195 unsigned int face = this->
face_m;
196 unsigned int d = face / 2;
200 int myRank = comm.rank();
201 const auto& lDomains = layout.getHostLocalDomains();
202 const auto& domain = layout.getDomain();
208 if (lDomains[myRank][d].length() < domain[d].length()) {
211 bool isBoundary = (lDomains[myRank][d].max() == domain[d].
max())
212 || (lDomains[myRank][d].min() == domain[d].
min());
217 auto& nd = lDomains[myRank];
219 int offset, offsetRecv, matchtag;
222 offset = -domain[d].length();
227 offset = domain[d].length();
228 offsetRecv = -nghost;
236 std::vector<MPI_Request> requests(neighbors.size());
239 using range_t =
typename HaloCells_t::bound_type;
240 HaloCells_t& halo = field.
getHalo();
241 std::vector<range_t> rangeNeighbors;
243 for (
size_t i = 0; i < neighbors.size(); ++i) {
244 int rank = neighbors[i];
246 auto ndNeighbor = lDomains[rank];
247 ndNeighbor[d] = ndNeighbor[d] - offset;
255 for (
size_t j = 0; j <
Dim; ++j) {
256 range.lo[j] = overlap[j].
first() - nd[j].first() + nghost;
257 range.hi[j] = overlap[j].
last() - nd[j].first() + nghost + 1;
260 rangeNeighbors.push_back(range);
265 buffer_type buf = comm.template getBuffer<memory_space, T>(nSends);
267 comm.isend(rank, tag,
haloData_m, *buf, requests[i], nSends);
268 buf->resetWritePos();
271 for (
size_t i = 0; i < neighbors.size(); ++i) {
272 int rank = neighbors[i];
274 range_t range = rangeNeighbors[i];
276 range.lo[d] = range.lo[d] + offsetRecv;
277 range.hi[d] = range.hi[d] + offsetRecv;
281 buffer_type buf = comm.template getBuffer<memory_space, T>(nRecvs);
282 comm.recv(rank, matchtag,
haloData_m, *buf, nRecvs *
sizeof(
T), nRecvs);
285 using assign_t =
typename HaloCells_t::assign;
288 if (!requests.empty()) {
289 MPI_Waitall(requests.size(), requests.data(), MPI_STATUSES_IGNORE);
291 comm.freeAllBuffers();
296 throw IpplException(
"PeriodicFace::apply",
"face number wrong");
299 auto N = view.extent(d) - 1;
303 Kokkos::Array<index_type, Dim> begin, end;
308 for (
size_t i = 0; i <
Dim; ++i) {
309 end[i] = view.extent(i) - nghost;
318 KOKKOS_CLASS_LAMBDA(index_array_type & coords) {
328 auto&& left =
apply(view, coords);
331 coords[d] = N - coords[d];
332 auto&& right =
apply(view, coords);
335 coords[d] += 2 * nghost - 1 - N;
336 apply(view, coords) = right;
340 coords[d] = N - coords[d];
341 apply(view, coords) = left;
346 template <
typename Field>
348 unsigned int face = this->
face_m;
349 unsigned int d = face / 2;
353 const auto& ldom = layout.getLocalNDIndex();
354 const auto& domain = layout.getDomain();
357 throw IpplException(
"PeriodicFace::apply",
"face number wrong");
360 bool upperFace = (face & 1);
361 bool isBoundary = ((ldom[d].max() == domain[d].
max()) && upperFace)
362 || ((ldom[d].min() == domain[d].
min()) && !(upperFace));
366 auto N = view.extent(d) - 1;
370 Kokkos::Array<index_type, Dim> begin, end;
375 bool isCorner = (d != 0);
376 for (
size_t i = 0; i <
Dim; ++i) {
377 bool upperFace_i = (ldom[i].max() == domain[i].
max());
378 bool lowerFace_i = (ldom[i].min() == domain[i].
min());
379 end[i] = view.extent(i) - nghost - (upperFace_i)*(isCorner);
380 begin[i] = nghost + (lowerFace_i)*(isCorner);
382 begin[d] = ((0 + nghost - 1) * (1 - upperFace)) + (N * upperFace);
383 end[d] = begin[d] + 1;
388 KOKKOS_CLASS_LAMBDA(index_array_type & coords) {
396 auto&& right =
apply(view, coords);
399 int shift = 1 - (2 * upperFace);
402 apply(view, coords) += right;
407 template <
typename Field>
409 unsigned int face = this->
face_m;
410 unsigned int d = face / 2;
414 const auto& ldom = layout.getLocalNDIndex();
415 const auto& domain = layout.getDomain();
418 throw IpplException(
"ExtrapolateFace::apply",
"face number wrong");
421 bool upperFace = (face & 1);
422 bool isBoundary = ((ldom[d].max() == domain[d].
max()) && upperFace)
423 || ((ldom[d].min() == domain[d].
min()) && !(upperFace));
426 auto N = view.extent(d) - 1;
430 Kokkos::Array<index_type, Dim> begin, end;
435 for (
size_t i = 0; i <
Dim; ++i) {
436 end[i] = view.extent(i) - nghost;
439 begin[d] = ((0 + nghost - 1) * (1 - upperFace)) + (N * upperFace);
440 end[d] = begin[d] + 1;
445 KOKKOS_CLASS_LAMBDA(index_array_type & coords) {
453 auto&& right =
apply(view, coords);
456 int shift = 1 - (2 * upperFace);
460 apply(view, coords) = right;
void unpack(const ippl::NDIndex< 3 > intersect, const Kokkos::View< Tf *** > &view, ippl::detail::FieldBufferData< Tb > &fd, int nghost, const ippl::NDIndex< 3 > ldom, bool x=false, bool y=false, bool z=false)
KOKKOS_INLINE_FUNCTION constexpr decltype(auto) apply(const View &view, const Coords &coords)
RangePolicy< Dim, PolicyArgs... >::policy_type createRangePolicy(const Kokkos::Array< typename RangePolicy< Dim, PolicyArgs... >::index_type, Dim > &begin, const Kokkos::Array< typename RangePolicy< Dim, PolicyArgs... >::index_type, Dim > &end)
KOKKOS_INLINE_FUNCTION Vector< T, Dim > min(const Vector< T, Dim > &a, const Vector< T, Dim > &b)
void parallel_for(const std::string &name, const ExecPolicy &policy, const FunctorType &functor)
std::ostream & operator<<(std::ostream &, const BCondBase< Field > &)
std::shared_ptr< archive_type< MemorySpace > > buffer_type
Layout_t & getLayout() const
view_type::memory_space memory_space
auto & getCommunicator() const
detail::HaloCells< T, Dim, ViewArgs... > halo_type
view_type::execution_space execution_space
BCondBase(unsigned int face)
virtual void write(std::ostream &) const =0
typename detail::BCondBase< Field >::Layout_t Layout_t
virtual void assignGhostToPhysical(Field &field)
typename Field::value_type T
virtual void write(std::ostream &out) const
virtual void apply(Field &field)
static constexpr unsigned Dim
virtual void write(std::ostream &out) const
virtual void write(std::ostream &out) const
virtual void write(std::ostream &out) const
virtual void findBCNeighbors(Field &field)
face_neighbor_type faceNeighbors_m
typename Field::value_type T
virtual void write(std::ostream &out) const
Field::halo_type::databuffer_type haloData_m
virtual void apply(Field &field)
typename detail::BCondBase< Field >::Layout_t Layout_t
virtual void assignGhostToPhysical(Field &field)
static constexpr unsigned Dim
typename BareField_t::view_type view_type
const host_mirror_type getHostLocalDomains() const
KOKKOS_INLINE_FUNCTION Vector< int, Dim > last() const
KOKKOS_INLINE_FUNCTION Vector< int, Dim > first() const
KOKKOS_INLINE_FUNCTION NDIndex< Dim > intersect(const NDIndex< Dim > &) const
KOKKOS_INLINE_FUNCTION NDIndex< Dim > grow(int ncells) const
::ippl::Vector< index_type, Dim > index_array_type
typename policy_type::array_index_type index_type