www.cemf.ir
pointFlagKernels.hpp
Go to the documentation of this file.
1 /*------------------------------- phasicFlow ---------------------------------
2  O C enter of
3  O O E ngineering and
4  O O M ultiscale modeling of
5  OOOOOOO F luid flow
6 ------------------------------------------------------------------------------
7  Copyright (C): www.cemf.ir
8  email: hamid.r.norouzi AT gmail.com
9 ------------------------------------------------------------------------------
10 Licence:
11  This file is part of phasicFlow code. It is a free software for simulating
12  granular and multiphase flows. You can redistribute it and/or modify it under
13  the terms of GNU General Public License v3 or any other later versions.
14 
15  phasicFlow is distributed to help others in their research in the field of
16  granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
17  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 
19 -----------------------------------------------------------------------------*/
20 #ifndef __pointFlagKernels_hpp__
21 #define __pointFlagKernels_hpp__
22 
23 template<typename ExecutionSpace>
26 {
27  using rpAPoints = Kokkos::RangePolicy<execution_space,
28  Kokkos::IndexType<uint32>>;
29 
31  aPoints("activePoints", activeRange_.end()+1);
32 
33 
34  Kokkos::parallel_for(
35  "pFlow::pointFlag<ExecutionSpace>::getActivePoints",
36  rpAPoints(0,activeRange_.end()),
38  {
39  if( isActive(i))
40  {
41  aPoints[i] = 1;
42  }
43  else
44  {
45  aPoints[i] = 0;
46  }
47  }
48  );
49  Kokkos::fence();
50  return aPoints;
51 }
52 
53 template<typename ExecutionSpace>
56 {
57 
58  uint32 cap = capacity();
59  using rpAPoints = Kokkos::RangePolicy<execution_space,
60  Kokkos::IndexType<uint32>>;
61 
62  ViewType1D<uint32,memory_space> indices("indices", cap+1);
63 
64  ViewType1D<uint32,memory_space> emptyPoints("emptyPoints", numToGet);
65 
66  auto flags = flags_;
67 
68  Kokkos::parallel_for(
69  "getEmptyPoints",
70  rPolicy(0, cap),
71  LAMBDA_HD(uint32 i){
72  indices(i) = flags[i] == DELETED;
73  });
74  Kokkos::fence();
75 
76  exclusiveScan(indices, 0u, cap, indices, 0u);
77  uint32 numFound = 0;
78  Kokkos::parallel_reduce(
79  "fillEmptyPoints",
80  rpAPoints(0, cap-1),
81  LAMBDA_HD(uint32 i, uint32& numFoundUpdate){
82  if(indices(i)!= indices(i+1) && indices(i)< numToGet)
83  {
84  emptyPoints(indices(i)) = i;
85  numFoundUpdate++;
86  }
87  },
88  numFound
89  );
90 
91  if(numFound < numToGet)
92  {
93  return Kokkos::subview(emptyPoints, Kokkos::make_pair(0u, numFound));
94  }
95  return emptyPoints;
96 
97 }
98 
99 
100 template<typename ExecutionSpace>
102 (
103  const box& validBox,
105 )
106 {
107  using rpScanFlag = Kokkos::RangePolicy<execution_space,
108  Kokkos::IndexType<uint32>>;
109 
110  uint32 numDeleted = 0;
111 
112  uint32 start = activeRange().start();
113  uint32 end = activeRange().end();
114 
115  uint32 minRange = end;
116  uint32 maxRange = start;
117 
118  if(start<end)
119  {
120  Kokkos::parallel_reduce(
121  "pointFlagKernels::markOutOfBox",
122  rpScanFlag(start, end),
124  uint32 i,
125  uint32& minUpdate,
126  uint32& maxUpdate,
127  uint32& delToUpdate)
128  {
129  if(isActive(i))
130  {
131  if(validBox.isInside(points[i]))
132  {
133 
134  minUpdate = min(minUpdate,i);
135  maxUpdate = max(maxUpdate,i);
136  }
137  else
138  {
139  flags_[i] = DELETED;
140  delToUpdate++;
141  }
142 
143  }
144 
145  },
146  Kokkos::Min<uint32>(minRange),
147  Kokkos::Max<uint32>(maxRange),
148  numDeleted);
149  }
150 
151  if(numDeleted >= numActive_)
152  {
153  minRange = 0;
154  maxRange = 0;
155  numDeleted = numActive_;
156  }
157  else
158  {
159  // add one to maxRange to make it half-open
160  maxRange ++;
161  }
162 
163  activeRange_ = {minRange, maxRange};
164  numActive_ = numActive_ - numDeleted;
165  isAllActive_ =
166  (activeRange_.numElements() == numActive_)&& numActive_>0;
167 
168  return numDeleted;
169 }
170 
171 template<typename ExecutionSpace>
174 (
176 )
177 {
178  if(points.extent(0)==0u)return 0;
179 
180  uint32 minRange;
181  uint32 maxRange;
182  uint32 numAdded = 0;
183 
184  const auto& flag = flags_;
185 
186  Kokkos::parallel_reduce(
187  "pointFlagKernels::addInternalPoints",
188  deviceRPolicyStatic(0, points.extent(0)),
189  LAMBDA_HD(
190  uint32 i,
191  uint32& minUpdate,
192  uint32& maxUpdate,
193  uint32& addToUpdate)
194  {
195  uint32 idx = points(i);
196  if( flag[idx] <= DELETED) addToUpdate ++;
197  minUpdate = min(minUpdate,idx);
198  maxUpdate = max(maxUpdate,idx);
199  flag[idx] = INTERNAL;
200  },
201  Kokkos::Min<uint32>(minRange),
202  Kokkos::Max<uint32>(maxRange),
203  numAdded);
204 
205  // add one to max range to make range it half open
206  maxRange++;
207 
208  minRange = min(activeRange_.start(), minRange);
209  maxRange = max(activeRange_.end(), maxRange);
210 
211  activeRange_ = {minRange, maxRange};
212  numActive_ = numActive_ + numAdded;
213 
214  isAllActive_ = activeRange_.numElements() == numActive_;
215 
216  return numAdded;
217 }
218 
219 template<typename ExecutionSpace>
221 (
223 )
224 {
225  if(points.empty())return true;
226 
227 
228  using policy = Kokkos::RangePolicy<
230  Kokkos::IndexType<uint32>>;
231 
232  uint32 numDeleted = 0;
233  Kokkos::parallel_reduce
234  (
235  "pointFlagKernels::deletePoints",
236  policy(0u, points.size()),
237  CLASS_LAMBDA_HD(uint32 i, uint32& valDelUpdate)
238  {
239  uint32 n = points(i);
240  if(isActive(n))
241  {
242  valDelUpdate++;
243  flags_[n] = Flag::DELETED;
244  }
245  },
246  numDeleted
247  );
248 
249  if(numDeleted >= numActive_)
250  {
251  activeRange_ = {0, 0};
252  numDeleted = numActive_;
253  }
254 
255  numActive_ = numActive_ - numDeleted;
256  isAllActive_ =
257  (activeRange_.numElements() == numActive_)&& numActive_>0;
258 
259  return true;
260 }
261 template<typename ExecutionSpace>
263 (
265 )
266 {
267 
268  uint32 s = points.size();
269  if(s==0u)return true;
270 
271  using policy = Kokkos::RangePolicy<
273  Kokkos::IndexType<uint32>>;
274 
275  uint32 numDeleted = 0;
276  Kokkos::parallel_reduce
277  (
278  "pointFlagKernels::deletePoints",
279  policy(0u, points.size()),
280  CLASS_LAMBDA_HD(uint32 i, uint32& valDelUpdate)
281  {
282  uint32 n = points(i);
283  if(isActive(n))
284  {
285  valDelUpdate++;
286  flags_[n] = Flag::DELETED;
287  }
288  },
289  numDeleted
290  );
291 
292  if(numDeleted >= numActive_)
293  {
294  activeRange_ = {0, 0};
295  numDeleted = numActive_;
296  }
297 
298  numActive_ = numActive_ - numDeleted;
299  isAllActive_ =
300  (activeRange_.numElements() == numActive_)&& numActive_>0;
301 
302  return true;
303 }
304 
305 
306 template<typename ExecutionSpace>
308 (
309  ViewType1D<uint32, memory_space> changePoints,
310  uint32 boundaryIndex
311 )
312 {
313  auto flg = getBoundaryFlag(boundaryIndex);
314  const auto& flags = flags_;
315  Kokkos::parallel_for
316  (
317  "pointFlag::changeFlags",
318  rPolicy(0, changePoints.size()),
319  LAMBDA_HD(uint32 i)
320  {
321  flags[changePoints(i)] = flg;
322  }
323  );
324  Kokkos::fence();
325  return true;
326 }
327 
328 template<typename ExecutionSpace>
330 (
331  domain dm,
333  real leftLength,
334  real rightLength,
335  real bottomLength,
336  real topLength,
337  real rearLength,
338  real frontLength)
339 {
340 
341  using rpMark = Kokkos::RangePolicy<execution_space,
342  Kokkos::IndexType<uint32>>;
343 
344  uint32 start = activeRange().start();
345  uint32 end = activeRange().end();
346 
347  uint32 minRange = end;
348  uint32 maxRange = start;
349 
350  uint32 numMarkedDelete = 0;
351  uint32 nLeft = 0, nRight = 0;
352  uint32 nBottom = 0, nTop = 0;
353  uint32 nRear = 0, nFront = 0;
354 
355  if(start<end)
356  {
357 
358  Kokkos::parallel_reduce(
359  "pointFlagKernels::markDeleteInDomain",
360  rpMark(start,end),
362  uint32 i,
363  uint32& minUpdate,
364  uint32& maxUpdate,
365  uint32& valDelete,
366  uint32& valLeft,
367  uint32& valRight,
368  uint32& valBottom,
369  uint32& valTop,
370  uint32& valRear,
371  uint32& valFront){
372  if(this->isActive(i))
373  {
374  realx3 p = points[i];
375  if( !dm.domainBox().isInside(p) )
376  {
377  flags_[i] = DELETED;
378  valDelete++;
379  }
380  else
381  {
382 
383  uint8 flg = 0;
384  minUpdate = min(minUpdate,i);
385  maxUpdate = max(maxUpdate,i);
386 
387  if(dm.left().inPositiveDistance(p, leftLength))
388  {
389  flg += LEFT;
390  valLeft++;
391  }
392 
393  if(dm.right().inPositiveDistance(p, rightLength))
394  {
395  flg += RIGHT;
396  valRight++;
397  }
398 
399  if(dm.bottom().inPositiveDistance(p, bottomLength))
400  {
401  flg += BOTTOM;
402  valBottom++;
403  }
404 
405  if(dm.top().inPositiveDistance(p, topLength))
406  {
407  flg += TOP;
408  valTop++;
409  }
410 
411  if(dm.rear().inPositiveDistance(p, rearLength))
412  {
413  flg += REAR;
414  valRear++;
415  }
416 
417  if(dm.front().inPositiveDistance(p, frontLength))
418  {
419  flg += FRONT;
420  valFront++;
421  }
422 
423  flags_[i] = flg>static_cast<uint8>(0)? flg: INTERNAL;
424  }
425  }
426  },
427  Kokkos::Min<uint32>(minRange),
428  Kokkos::Max<uint32>(maxRange),
429  numMarkedDelete,
430  nLeft,
431  nRight,
432  nBottom,
433  nTop,
434  nRear,
435  nFront);
436 
437  }
438 
439  // means either range was empty or all points have been deleted.
440  if(numMarkedDelete>= numActive_)
441  {
442  minRange = 0;
443  maxRange = 0;
444  numMarkedDelete = numActive_;
445  }
446  else
447  {
448  maxRange++; // add one to make it half
449  }
450 
451  activeRange_ = {minRange, maxRange};
452  numActive_ -= numMarkedDelete;
453  isAllActive_ = (activeRange_.numElements() == numActive_)&& numActive_>0;
454 
455  nLeft_ = nLeft;
456  nRight_ = nRight;
457  nBottom_= nBottom;
458  nTop_ = nTop;
459  nRear_ = nRear;
460  nFront_ = nFront;
461 
462  return numMarkedDelete;
463 }
464 
465 template<typename ExecutionSpace>
467 (
474 )
475 {
476  using rpMark = Kokkos::RangePolicy<execution_space,
477  Kokkos::IndexType<uint32>>;
478 
479  uint32 start = activeRange().start();
480  uint32 end = activeRange().end();
481 
482  ViewType1D<uint32, memory_space> nElems("nElems",6);
483 
484  fill(nElems, 0, 6, static_cast<uint32>(0));
485 
486  if(start<end)
487  {
488  Kokkos::parallel_for(
489  "pointFlagKernels::markDeleteInDomain",
490  rpMark(start,end),
492 
493  uint8 flg = flags_(i);
494  if(this->isBoundary(flg))
495  {
496  if(this->isLeft(flg)) leftList[Kokkos::atomic_fetch_add(&nElems[0],1)] = i;
497  if(this->isRight(flg))rightList[Kokkos::atomic_fetch_add(&nElems[1],1)] = i;
498  if(this->isBottom(flg))bottomList[Kokkos::atomic_fetch_add(&nElems[2],1)] = i;
499  if(this->isTop(flg))topList[Kokkos::atomic_fetch_add(&nElems[3],1)] = i;
500  if(this->isRear(flg))rearList[Kokkos::atomic_fetch_add(&nElems[4],1)] = i;
501  if(this->isFront(flg))frontList[Kokkos::atomic_fetch_add(&nElems[5],1)] = i;
502  }
503  });
504  Kokkos::fence();
505  }
506 }
507 
508 template<typename ExecutionSpace>
510 (
511  const plane& pln,
515 )
516 {
517  // if it is empty, do nothing
518  if(indices.size() == 0 )return 0;
519 
520  using rpMark = Kokkos::RangePolicy<execution_space,
521  Kokkos::IndexType<uint32>>;
522 
523  uint32 start = activeRange().start();
524  uint32 end = activeRange().end();
525 
526  uint32 minRange = end;
527  uint32 maxRange = start;
528 
529  uint32 numMarked = 0;
530 
531  if(start<end)
532  {
533  Kokkos::parallel_reduce(
534  "pointFlagKernels::markDelete",
535  rpScanFlag(0, indices.size()),
537  uint32 i,
538  uint32& minUpdate,
539  uint32& maxUpdate,
540  uint32& sumToUpdate)
541  {
542  auto indx = indices(i);
543 
544  if( pln.pointInNegativeSide(points(indx)))
545  {
546  flags_[indx] = DELETED;
547  sumToUpdate++;
548  onOff[i] = 0;
549  }
550  else
551  {
552  minUpdate = min(minUpdate,i);
553  maxUpdate = max(maxUpdate,i);
554  onOff[i] = 1;
555  }
556  },
557  Kokkos::Min<uint32>(minRange),
558  Kokkos::Max<uint32>(maxRange),
559  numMarked);
560  }
561 
562  // means either range was empty or all points have been deleted.
563  if(minRange<start || maxRange>end)
564  {
565  minRange = 0;
566  maxRange = 0;
567  }
568  else
569  {
570  maxRange++; // add one to make it half
571  }
572 
573  activeRange_ = {minRange, maxRange};
574  isAllActive_ = isAllActive_ && numMarked == 0;
575  numActive_ -= numMarked;
576 
577  return numMarked;
578 }
579 
580 template<typename ExecutionSpace>
582 (
583  uint32 reqEmptySpots
584 )
585 {
586 
587  uint32 oldCap = capacity();
589  uint32 emptySpots = newCap - numActive_;
590 
591  while( emptySpots < reqEmptySpots )
592  {
593  newCap = newCap*pFlow::gSettings::vectorGrowthFactor__+1;
594  emptySpots = newCap - numActive_;
595  }
596 
597  viewType newFlags(flags_.label(), newCap);
598  // copy contnent
599  copy(newFlags, 0u, flags_, 0u, oldCap);
600  fill(newFlags, oldCap, newCap, static_cast<uint8>(DELETED));
601 
602  // reference replacement
603  flags_ = newFlags;
604 
605  return newCap;
606 }
607 
608 #endif // __pointFlagKernels_hpp__
609 
610 
611 
612 
613 /*template<typename ExecutionSpace>
614 pFlow::uint32 pFlow::pointFlag<ExecutionSpace>::scanPointFlag()
615 {
616 
617  using rpScanFlag = Kokkos::RangePolicy<execution_space,
618  Kokkos::IndexType<uint32>>;
619 
620  uint32 numActive = 0;
621 
622 
623  uint32 start = activeRange().start();
624  uint32 end = activeRange().end();
625 
626  uint32 minRange = end;
627  uint32 maxRange = start;
628 
629  if(start<end)
630  {
631  Kokkos::parallel_reduce(
632  "pointFlagKernels::scanPointFlag",
633  rpScanFlag(start, end),
634  CLASS_LAMBDA_HD(
635  uint32 i,
636  uint32& minUpdate,
637  uint32& maxUpdate,
638  uint32& sumToUpdate)
639  {
640  if(this->isActive(i))
641  {
642  sumToUpdate++;
643  minUpdate = min(minUpdate,i);
644  maxUpdate = max(maxUpdate,i);
645  }
646  },
647  Kokkos::Min<uint32>(minRange),
648  Kokkos::Max<uint32>(maxRange),
649  numActive);
650  }
651 
652  if(numActive==0)
653  {
654  minRange = 0;
655  maxRange = 0;
656  }
657  else
658  {
659  // add one to maxRange to make it half-open
660  maxRange ++;
661  }
662 
663  activeRange_ = {minRange, maxRange};
664  numActive_ = numActive;
665  isAllActive_ = activeRange_.numElements() == numActive_;
666 
667  return numActive;
668 }*/
pFlow::scatteredFieldAccess
Definition: scatteredFieldAccess.hpp:32
pFlow::real
float real
Definition: builtinTypes.hpp:45
pFlow::infinitePlane::pointInNegativeSide
INLINE_FUNCTION_HD bool pointInNegativeSide(const realx3 &p) const
Definition: infinitePlane.hpp:107
pFlow::plane
Definition: plane.hpp:30
pFlow::scatteredFieldAccess::size
INLINE_FUNCTION_HD uint32 size() const
Definition: scatteredFieldAccess.hpp:134
pFlow::pointFlag::changeFlags
bool changeFlags(ViewType1D< uint32, memory_space > changePoints, uint32 boundaryIndex)
Definition: pointFlagKernels.hpp:308
pFlow::pointFlag::getActivePoints
ViewType1D< uint32, memory_space > getActivePoints()
Definition: pointFlagKernels.hpp:25
pFlow::pointFlag::markOutOfBoxDelete
uint32 markOutOfBoxDelete(const box &validBox, ViewType1D< realx3, memory_space > points)
Loop over the active points and mark those out of the box and return number of deleted points.
Definition: pointFlagKernels.hpp:102
pFlow::domain::domainBox
const INLINE_FUNCTION_HD auto & domainBox() const
Definition: domain.hpp:86
pFlow::algorithms::KOKKOS::max
INLINE_FUNCTION_H Type max(const Type *first, uint32 numElems)
Definition: kokkosAlgorithms.hpp:104
pFlow::copy
INLINE_FUNCTION_H void copy(const ViewType1D< dType, dProperties... > &dst, const ViewType1D< sType, sProperties... > &src)
Definition: ViewAlgorithms.hpp:234
pFlow::algorithms::KOKKOS::min
INLINE_FUNCTION_H Type min(const Type *first, int32 numElems)
Definition: kokkosAlgorithms.hpp:124
pFlow::uint32
unsigned int uint32
Definition: builtinTypes.hpp:56
pFlow::pointFlag< DefaultHostExecutionSpace >::execution_space
DefaultHostExecutionSpace execution_space
Definition: pointFlag.hpp:46
pFlow::domain::bottom
const INLINE_FUNCTION_HD auto & bottom() const
Definition: domain.hpp:104
policy
Kokkos::RangePolicy< pFlow::DefaultExecutionSpace, Kokkos::Schedule< Kokkos::Static >, Kokkos::IndexType< pFlow::uint32 > > policy
Definition: grainParticlesKernels.cpp:25
pFlow::pointFlag< DefaultHostExecutionSpace >::viewType
ViewType1D< uint8, memory_space > viewType
Definition: pointFlag.hpp:50
pFlow::domain::rear
const INLINE_FUNCTION_HD auto & rear() const
Definition: domain.hpp:116
pFlow::pointFlag< DefaultHostExecutionSpace >::rPolicy
Kokkos::RangePolicy< execution_space, Kokkos::IndexType< uint32 > > rPolicy
Definition: pointFlag.hpp:56
pFlow::pointFlag::markDelete
uint32 markDelete(const plane &pln, ViewType1D< realx3, memory_space > points, ViewType1D< uint32, memory_space > indices, ViewType1D< uint32, memory_space > onOff)
Definition: pointFlagKernels.hpp:510
pFlow::domain::front
const INLINE_FUNCTION_HD auto & front() const
Definition: domain.hpp:122
CLASS_LAMBDA_HD
#define CLASS_LAMBDA_HD
Definition: pFlowMacros.hpp:60
pFlow::pointFlag::markPointRegions
uint32 markPointRegions(domain dm, ViewType1D< realx3, memory_space > points, real leftLength, real rightLength, real bottomLength, real topLength, real rearLength, real frontLength)
mark points based on their position in the domain.
Definition: pointFlagKernels.hpp:330
pFlow::pointFlag::addInternalPoints
uint32 addInternalPoints(const ViewType1D< uint32, memory_space > &points)
Definition: pointFlagKernels.hpp:174
pFlow::domain::right
const INLINE_FUNCTION_HD auto & right() const
Definition: domain.hpp:98
pFlow::pointFlag::fillNeighborsLists
void fillNeighborsLists(ViewType1D< uint32, memory_space > leftList, ViewType1D< uint32, memory_space > rightList, ViewType1D< uint32, memory_space > bottomList, ViewType1D< uint32, memory_space > topList, ViewType1D< uint32, memory_space > rearList, ViewType1D< uint32, memory_space > frontList)
fill the lists for boundary faces.
Definition: pointFlagKernels.hpp:467
pFlow::gSettings::vectorGrowthFactor__
const double vectorGrowthFactor__
Definition: globalSettings.cpp:9
fill
void fill(Vector< T, Allocator > &vec, const T &val)
pFlow::algorithms::KOKKOS::exclusiveScan
void exclusiveScan(Type *first, Type *dFirst, uint32 numElems)
Definition: kokkosAlgorithms.hpp:148
pFlow::ViewType1D
Kokkos::View< T *, properties... > ViewType1D
1D veiw as a vector
Definition: KokkosTypes.hpp:93
n
uint32 n
Definition: NBSLoop.hpp:24
pFlow::box
Definition: box.hpp:32
pFlow::pointFlag::getEmptyPoints
ViewType1D< uint32, memory_space > getEmptyPoints(uint32 numToGet) const
Definition: pointFlagKernels.hpp:55
LAMBDA_HD
#define LAMBDA_HD
Definition: pFlowMacros.hpp:58
pFlow::deviceRPolicyStatic
Kokkos::RangePolicy< Kokkos::DefaultExecutionSpace, Kokkos::Schedule< Kokkos::Static >, Kokkos::IndexType< pFlow::uint32 > > deviceRPolicyStatic
Definition: KokkosTypes.hpp:66
pFlow::pointFlag::changeCapacity
uint32 changeCapacity(uint32 reqEmptySpots)
Definition: pointFlagKernels.hpp:582
pFlow::scatteredFieldAccess::empty
INLINE_FUNCTION_HD bool empty() const
Definition: scatteredFieldAccess.hpp:140
pFlow::domain
Definition: domain.hpp:31
pFlow::triple< real >
pFlow::box::isInside
INLINE_FUNCTION_HD bool isInside(const realx3 &point) const
Definition: box.hpp:84
pFlow::uint8
unsigned char uint8
Definition: builtinTypes.hpp:54
pFlow::pointFlag::deletePoints
bool deletePoints(scatteredFieldAccess< uint32, memory_space > points)
Definition: pointFlagKernels.hpp:221
pFlow::domain::top
const INLINE_FUNCTION_HD auto & top() const
Definition: domain.hpp:110