22 template <
typename Field>
25 , changePhysical_m(false) {}
27 template <
typename Field>
35 template <
typename Field>
40 unsigned int face = this->face_m;
41 unsigned d = face / 2;
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;
94 "Assign extrapolate BC", createRangePolicy<Dim, exec_space>(
begin,
end),
95 KOKKOS_CLASS_LAMBDA(index_array_type & args) {
99 T value =
apply(view, args);
103 apply(view, args) = slope_m * value + offset_m;
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();
149 for (
auto& neighbors : faceNeighbors_m) {
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])) {
185 faceNeighbors_m[face].push_back(rank);
192 template <
typename Field>
195 unsigned int face = this->face_m;
196 unsigned int d = face / 2;
200 int myRank = comm.rank();
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;
232 auto& neighbors = faceNeighbors_m[face];
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);
263 halo.pack(range, view, haloData_m, nSends);
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;
286 halo.template unpack<assign_t>(range, view, haloData_m);
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;
317 "Assign periodic field BC", createRangePolicy<Dim, exec_space>(
begin,
end),
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;
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);
387 "Assign periodic field BC", createRangePolicy<Dim, exec_space>(
begin,
end),
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;
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);
444 "Assign field BC", createRangePolicy<Dim, exec_space>(
begin,
end),
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;
PartBunch< T, Dim >::ConstIterator end(PartBunch< T, Dim > const &bunch)
PartBunch< T, Dim >::ConstIterator begin(PartBunch< T, Dim > const &bunch)
Implementations for FFT constructor/destructor and transforms.
KOKKOS_INLINE_FUNCTION constexpr decltype(auto) apply(const View &view, const Coords &coords)
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)
typename policy_type::array_index_type index_type
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
virtual void assignGhostToPhysical(Field &field)
typename Field::value_type T
virtual void write(std::ostream &out) const
virtual void apply(Field &field)
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)
typename Field::value_type T
virtual void write(std::ostream &out) const
virtual void apply(Field &field)
virtual void assignGhostToPhysical(Field &field)
typename BareField_t::view_type view_type
const host_mirror_type getHostLocalDomains() const
const NDIndex< Dim > & getDomain() const
const NDIndex_t & getLocalNDIndex() 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