OpenFPM_pdata  1.1.0
Project that contain the implementation of distributed structures
 All Data Structures Namespaces Functions Variables Typedefs Enumerations Friends Pages
se_class3_vector.hpp
1 /*
2  * se_class3_vector.hpp
3  *
4  * Created on: Feb 11, 2017
5  * Author: i-bird
6  */
7 
8 #ifndef SRC_VECTOR_SE_CLASS3_VECTOR_HPP_
9 #define SRC_VECTOR_SE_CLASS3_VECTOR_HPP_
10 
11 #include <iostream>
12 #include <Space/Shape/Point.hpp>
13 #include <Vector/map_vector.hpp>
14 #include <Vector/vector_dist_comm.hpp>
15 #include <list>
16 
17 #define SE3_STATUS -2
18 #define SE3_TYPE -1
19 #define SE3_SIZE 2
20 
21 enum statuses
22 {
23  CLEAN,
24  DIRTY,
25  UNINITIALIZED
26 };
27 
28 enum sync
29 {
30  SYNC,
31  NOTSYNC
32 };
33 
34 enum ptype
35 {
36  HALO,
37  GHOST,
38  INSIDE
39 };
40 
42 template<typename T>
44 {
46  static const int init = UNINITIALIZED;
47 };
48 
50 template<typename T>
51 struct is_initialized<openfpm::vector<T>>
52 {
54  static const int init = CLEAN;
55 };
56 
57 
59 
71 template<unsigned int Np, typename vector>
72 struct init_prop
73 {
75  size_t (& prp_init)[Np];
76 
83  inline init_prop(size_t ( & prp_init)[Np])
85  {
86  };
87 
88 
94  template<typename T>
95  inline void operator()(T& t) const
96  {
97  typedef typename boost::mpl::at<vector,boost::mpl::int_<T::value>>::type tc;
98 
100  }
101 };
102 
104 template<typename tcheck, bool foundamental>
105 struct typeCheck
106 {
114  static bool isNan(const tcheck & data)
115  {
116  return false;
117  }
118 
126  static bool isInf(const tcheck & data)
127  {
128  return false;
129  }
130 };
131 
133 template<typename tcheck>
134 struct typeCheck<tcheck,true>
135 {
143  static bool isNan(const tcheck & data)
144  {
145  return std::isnan(data);
146  }
147 
155  static bool isInf(const tcheck & data)
156  {
157  return std::isinf(data);
158  }
159 };
160 
162 template<typename tcheck, bool foundamental, unsigned int N1>
163 struct typeCheck<tcheck[N1], foundamental>
164 {
172  static bool isNan(tcheck (& data)[N1])
173  {
174  bool nn = false;
175 
176  for (size_t i = 0 ; i < N1; i++)
177  {
178  if (std::isnan(data[i]))
179  nn = true;
180  }
181 
182  return nn;
183  }
184 
192  static bool isInf(tcheck (& data)[N1])
193  {
194  bool nn = false;
195 
196  for (size_t i = 0 ; i < N1; i++)
197  {
198  if (std::isinf(data[i]))
199  nn = true;
200  }
201 
202  return nn;
203  }
204 };
205 
207 template<typename tcheck, bool foundamental, unsigned int N1, unsigned int N2>
208 struct typeCheck<tcheck[N1][N2], foundamental>
209 {
217  static bool isNan(tcheck (& data)[N1][N2])
218  {
219  bool nn = false;
220 
221  for (size_t i = 0 ; i < N1; i++)
222  {
223  for (size_t j = 0 ; j < N2; j++)
224  {
225  if (std::isnan(data[i][j]))
226  nn = true;
227  }
228  }
229 
230  return nn;
231  }
232 
240  static bool isInf(tcheck (& data)[N1][N2])
241  {
242  bool nn = false;
243 
244  for (size_t i = 0 ; i < N1; i++)
245  {
246  for (size_t j = 0 ; j < N2; j++)
247  {
248  if (std::isinf(data[i][j]))
249  nn = true;
250  }
251  }
252 
253  return nn;
254  }
255 };
256 
265 template<typename vector>
267 {
269  const vector & data;
270 
272  size_t id;
273 
280  inline propCheckNAN(const vector & data, size_t id)
281  :data(data),id(id)
282  {};
283 
284 
290  template<typename T>
291  inline void operator()(T& t) const
292  {
293  typedef typename boost::mpl::at<typename vector::value_type::type,typename boost::mpl::int_<T::value> >::type type_to_check;
294 
295  bool snn = typeCheck<type_to_check,std::is_fundamental<type_to_check>::value>::isNan(data.template getPropNC<T::value>(id));
296 
297  if (snn == true)
298  {
299  std::cerr << __FILE__ << ":" << __LINE__ << " error detected NAN in property " << T::value << std::endl;
300 
301  ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
302  }
303  }
304 };
305 
306 
315 template<typename vector>
317 {
319  const vector & data;
320 
322  size_t id;
323 
324 
331  inline propCheckINF(const vector & data, size_t id)
332  :data(data),id(id)
333  {};
334 
335 
341  template<typename T>
342  inline void operator()(T& t) const
343  {
344  typedef typename boost::mpl::at<typename vector::value_type::type,boost::mpl::int_<T::value> >::type type_to_check;
345 
346  bool snn = typeCheck<type_to_check,std::is_fundamental<type_to_check>::value>::isInf(data.template getPropNC<T::value>(id));
347 
348  if (snn == true)
349  {
350  std::cerr << __FILE__ << ":" << __LINE__ << " error detected INF in property " << T::value << std::endl;
351  ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
352  }
353  }
354 };
355 
361 static inline std::string getParticleTypeString(size_t type)
362 {
363  if (type == INSIDE)
364  return std::string("INSIDE");
365  else if (type == HALO)
366  return std::string("HALO");
367  else if (type == GHOST)
368  return std::string("GHOST");
369 
370  return std::string();
371 }
372 
373 template<unsigned int prp, unsigned int Np, typename vector> void check_for_pos_nan_inf(const vector & vd, size_t p)
374 {
375 #ifdef CHECKFOR_POSINF
376 
377  if ( std::isinf(vd.getPosNC(p)[0]) || std::isinf(vd.getPosNC(p)[1]) || std::isinf(vd.getPosNC(p)[2]) )
378  {
379  std::cerr << __FILE__ << ":" << __LINE__ << " error detected INF in position for particle p=" << p << " of type=" << getParticleTypeString(vd.template getPropNC<Np+SE3_TYPE>(p)) << std::endl;
380  ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
381  }
382 
383 #endif
384 
385 #ifdef CHECKFOR_POSNAN
386 
387  if ( std::isnan(vd.getPosNC(p)[0]) || std::isnan(vd.getPosNC(p)[1]) || std::isnan(vd.getPosNC(p)[2]) )
388  {
389  std::cerr << __FILE__ << ":" << __LINE__ << " error detected NAN in position for particle p=" << p << " of type=" << getParticleTypeString(vd.template getPropNC<Np+SE3_TYPE>(p)) << std::endl;
390  ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
391  }
392 
393 #endif
394 }
395 
396 template<unsigned int prp, unsigned int Np_real, typename vector> void check_for_prop_nan_inf(const vector & vd, size_t p)
397 {
398 #ifdef CHECKFOR_PROPINF
399 
400  {
401  propCheckINF<vector> checker(vd,p);
402 
403  boost::mpl::for_each_ref< boost::mpl::range_c<int,0, Np_real > > (checker);
404  }
405 
406 #endif
407 
408 #ifdef CHECKFOR_PROPNAN
409 
410  {
411  propCheckNAN<vector> checker(vd,p);
412 
413  boost::mpl::for_each_ref< boost::mpl::range_c<int,0, Np_real > >(checker);
414  }
415 
416 #endif
417 }
418 
419 
420 
426 template<unsigned int Np, unsigned int dim, typename T, typename Decomposition, typename vector>
428 {
430  int sync[2][Np];
431 
433  static const size_t Np_real = Np+SE3_STATUS;
434 
437 
439  vector & vd;
440 
443 
445  size_t l_wrt;
446 
454  bool isLocalHalo(const Point<dim,T> & p)
455  {
456  for (size_t i = 0; i < dec.getNLocalSub(); i++)
457  {
458  size_t Nl = dec.getLocalNIGhost(i);
459 
460  for (size_t j = 0; j < Nl; j++)
461  {
462  Box<dim,T> box = dec.getLocalIGhostBox(i, j);
463 
464  if (box.isInside(p) == true)
465  {
466  return true;
467  }
468  }
469  }
470 
471  return false;
472  }
473 
483  size_t getParticleType(const Point<dim,T> & p, const size_t & id, vector & vd)
484  {
485  size_t type;
486 
487  // first we distinguish what is this particle
488 
489  if (id > vd.size_local())
490  type = GHOST;
491  else
492  {
493  // Use cart decomposition to understand if it is in the halo
494 
495  const openfpm::vector<size_t> & vp_id = dec.template ghost_processorID<typename Decomposition::lc_processor_id>(p);
496 
497  if (vp_id.size() != 0)
498  type = HALO;
499  else
500  {
501  // Check if it is in the HALO inner ghost
502 
503  if (isLocalHalo(p) == true)
504  type = HALO;
505  else
506  type = INSIDE;
507  }
508  }
509 
510  return type;
511  }
512 
518  template<unsigned int ... prp>
519  void create_NNP( const size_t (& gg)[sizeof...(prp)+1] )
520  {
521  non_NP.clear();
522 
523  for (size_t i = 0 ; i < Np_real ; i++)
524  {
525  bool found = false;
526  for (size_t j = 0 ; j < sizeof...(prp) ; j++)
527  {
528  if (i == gg[j])
529  {
530  found = true;
531  break;
532  }
533  }
534 
535  if (found == false)
536  non_NP.add(i);
537  }
538  }
539 
540 
548  std::string getPrpName(size_t i) const
549  {
550  if (i == Np_real)
551  return std::string("POSITION");
552 
553  return std::to_string(i);
554  }
555 
556  public:
557 
565  :dec(dec),vd(vd),l_wrt(-1)
566  {
567  }
568 
574  template<unsigned int prp> size_t isGhostSync()
575  {
576  return sync[GHOST][prp];
577  }
578 
582  void Initialize()
583  {
584  auto it = vd.getDomainIterator_no_se3();
585 
586  while (it.isNext())
587  {
588  auto p = it.get();
589 
590  init_prop<Np_real+1,typename vector::value_type::type> np_r(vd.template getPropNC<Np+SE3_STATUS>(p));
591 
592  boost::mpl::for_each_ref< boost::mpl::range_c<int,0,Np_real+1> >(np_r);
593 
594  vd.template getPropNC<Np+SE3_TYPE>(p) = INSIDE;
595 
596  ++it;
597  }
598 
599  for (size_t i = 0 ; i < Np_real ; i++)
600  {
601  sync[GHOST][i] = NOTSYNC;
602  sync[HALO][i] = SYNC;
603  }
604  }
605 
606  template <unsigned int ... prp> void ghost_get_pre(size_t opt)
607  {
608  const size_t gg[sizeof...(prp)+1] = {prp...};
609 
610  create_NNP<prp...>(gg);
611 
612  // First check that the ghost are not dirty
613  // if they are dirty we are dostroyign information
614 
615  auto it = vd.getGhostIterator_no_se3();
616 
617  while(it.isNext())
618  {
619  auto p = it.get();
620 
621  for (size_t i = 0 ; i < sizeof...(prp) ; i++)
622  {
623  if (vd.template getPropNC<Np+SE3_STATUS>(p)[gg[i]] == DIRTY)
624  {
625  std::cerr << __FILE__ << ":" << __LINE__ << " Error the ghost has been written and ghost_get will overwrite your changes" << std::endl;
626  ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
627  }
628  }
629 
630  if (!(opt & KEEP_PROPERTIES))
631  {
632  for (size_t i = 0 ; i < non_NP.size() ; i++)
633  {
634  if (vd.template getPropNC<Np+SE3_STATUS>(p)[non_NP.get(i)] == DIRTY)
635  {
636  std::cerr << __FILE__ << ":" << __LINE__ << " Error the it seem that the property=" << getPrpName(non_NP.get(i)) << " has been written and ghost_get will destroy such changes" << std::endl;
637  ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
638  }
639  }
640  }
641 
642  ++it;
643  }
644  }
645 
646  template <unsigned int ... prp> void ghost_get_post(size_t opt)
647  {
648  const size_t gg[sizeof...(prp)+1] = {prp...};
649 
650  create_NNP<prp...>(gg);
651 
652  auto it2 = vd.getGhostIterator_no_se3();
653 
654  while(it2.isNext())
655  {
656  auto p = it2.get();
657 
658  for (size_t i = 0 ; i < sizeof...(prp) ; i++)
659  {
660  if (vd.template getPropNC<Np+SE3_STATUS>(p)[gg[i]] == DIRTY)
661  {vd.template getPropNC<Np+SE3_STATUS>(p)[gg[i]] = CLEAN;}
662  }
663 
664  if (vd.template getPropNC<Np+SE3_STATUS>(p)[Np_real] == DIRTY)
665  {vd.template getPropNC<Np+SE3_STATUS>(p)[Np_real] = CLEAN;}
666 
667  vd.template getPropNC<Np+SE3_TYPE>(p) = GHOST;
668 
669  ++it2;
670  }
671 
672  if (!(opt & KEEP_PROPERTIES))
673  {
674  for (size_t i = 0 ; i < non_NP.size() ; i++)
675  sync[GHOST][non_NP.get(i)] = NOTSYNC;
676 
677  auto it = vd.getGhostIterator_no_se3();
678 
679  while (it.isNext() == true)
680  {
681  auto p = it.get();
682 
683  for (size_t i = 0 ; i < non_NP.size() ; i++)
684  vd.template getPropNC<Np+SE3_STATUS>(p)[non_NP.get(i)] = UNINITIALIZED;
685 
686  ++it;
687  }
688  }
689 
690  // We notify that the ghost are in sync
691 
692  for (size_t i = 0 ; i < sizeof...(prp) ; i++)
693  sync[GHOST][gg[i]] = SYNC;
694 
695  if (!(opt & NO_POSITION))
696  {
697  sync[GHOST][Np_real] = SYNC;
698  }
699 
700  if (!(opt & KEEP_PROPERTIES))
701  {
702  for (size_t i = 0 ; i < non_NP.size() ; i++)
703  sync[GHOST][non_NP.get(i)] = NOTSYNC;
704  }
705  }
706 
707  template <unsigned int ... prp> void ghost_put()
708  {
709  const size_t gg[sizeof...(prp)] = {prp...};
710 
711  auto it = vd.getDomainIterator_no_se3();
712 
713  while(it.isNext())
714  {
715  auto p = it.get();
716 
717  if (vd.template getProp<Np+SE3_TYPE>(p) == INSIDE)
718  {
719  ++it;
720  continue;
721  }
722 
723  for (size_t i = 0 ; i < sizeof...(prp) ; i++)
724  {
725  if (vd.template getProp<Np+SE3_STATUS>(p)[gg[i]] == UNINITIALIZED)
726  {
727  std::cerr << __FILE__ << ":" << __LINE__ << " error it seem that you are sending at least in part uninitialized data with ghost put " << std::endl;
728  ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
729  }
730  }
731 
732  ++it;
733  }
734 
735  for (size_t i = 0 ; i < sizeof...(prp) ; i++)
736  {
737  sync[HALO][gg[i]] = SYNC;
738  sync[HALO][gg[i]] = CLEAN;
739  }
740 
741  // Ghost has been merged make ghost clean
742  auto it2 = vd.getGhostIterator_no_se3();
743 
744  while(it2.isNext())
745  {
746  auto p = it2.get();
747 
748  for (size_t i = 0 ; i < sizeof...(prp) ; i++)
749  vd.template getProp<Np+SE3_STATUS>(p)[gg[i]] = CLEAN;
750 
751  ++it2;
752  }
753  }
754 
755  void getIterator() const
756  {
757  auto it = vd.getDomainIterator_no_se3();
758 
759  while(it.isNext())
760  {
761  auto p = it.get();
762 
763  for (size_t j = 0 ; j < Np_real + 1 ; j++)
764  {
765  if (vd.template getPropNC<Np+SE3_STATUS>(p)[j] == DIRTY)
766  vd.template getPropNC<Np+SE3_STATUS>(p)[j] = CLEAN;
767  }
768 
769  ++it;
770  }
771  }
772 
773  void map_pre()
774  {
775  auto it = vd.getGhostIterator_no_se3();
776 
777  while (it.isNext() == true)
778  {
779  auto p = it.get();
780 
781  for (size_t j = 0 ; j < Np_real + 1 ; j++)
782  {
783  if (vd.template getPropNC<Np+SE3_STATUS>(p)[j] == DIRTY)
784  {
785  std::cerr << __FILE__ << ":" << __LINE__ << " error it seem that ghost has been filled with information that we are going to destroy with the map call " << std::endl;
786  }
787  }
788 
789  ++it;
790  }
791  }
792 
797  void map_post()
798  {
799  for (size_t j = 0 ; j < Np_real + 1 ; j++)
800  {
801 
802  sync[GHOST][j] = NOTSYNC;
803  }
804 
805  auto it = vd.getDomainIterator_no_se3();
806 
807  while (it.isNext() == true)
808  {
809  auto p = it.get();
810 
811  Point<vector::dims,typename vector::stype> xp = vd.getPosNC(p);
812 
813  vd.template getPropNC<Np+SE3_TYPE>(p) = getParticleType(xp,p.getKey(),vd);
814 
815  ++it;
816  }
817  }
818 
819  template<unsigned int prp> void read(const vector & vd, size_t p) const
820  {
821  if (vd.template getPropNC<Np+SE3_STATUS>(p)[prp] == UNINITIALIZED)
822  {
823  std::stringstream str;
824  std::string type_str = getParticleTypeString(vd.template getPropNC<Np+SE3_TYPE>(p));
825 
826  if (prp == Np_real)
827  str << __FILE__ << ":" << __LINE__ << " Error you are reading the particle " << p << " of type " << type_str << " the position. But it result to be uninitialized" << std::endl;
828  else
829  str << __FILE__ << ":" << __LINE__ << " Error you are reading from the particle " << p << " of type " << type_str << " the property=" << getPrpName(prp) << ". But it result to be uninitialized" << std::endl;
830 
831  // It is an error read from an uninitialized property
832  std::cerr << str.str() << std::endl;
833  ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
834  }
835 
836  if (vd.template getPropNC<Np+SE3_STATUS>(p)[prp] == DIRTY && p != l_wrt)
837  {
838  std::cerr << __FILE__ << ":" << __LINE__ << " Warning you are reading from a particle that has been changed already in the same cycle" << std::endl;
839  ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
840  }
841 
842  if (vd.template getPropNC<Np+SE3_TYPE>(p) == GHOST)
843  {
844  // if we read from the ghost we have to ensure that the ghost is in
845  // sync in particular that the state of the halo is CLEAN
846 
847  if (sync[vd.template getPropNC<Np+SE3_TYPE>(p)][prp] != SYNC)
848  {
849  std::cerr << __FILE__ << ":" << __LINE__ << " Error it seem that you are reading from a ghost the property=" << getPrpName(prp) << " but it seem it is changed from the last ghost_get. It seems that is missing a ghost_get" << std::endl;
850  ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
851  }
852  }
853 
854  check_for_pos_nan_inf<prp>(vd,p);
855  check_for_prop_nan_inf<prp,Np_real>(vd,p);
856  }
857 
858  template<unsigned int prp> void write(vector & vd, size_t p)
859  {
860  vd.template getPropNC<Np+SE3_STATUS>(p)[prp] = DIRTY;
861  if (p >= vd.size_local())
862  vd.get_se_class3().template setHaloOutSync<prp>();
863  else
864  {
865  if (vd.template getPropNC<Np+SE3_TYPE>(p) == HALO)
866  vd.get_se_class3().template setGhostOutSync<prp>();
867  }
868 
869  l_wrt = p;
870  }
871 
874  {
875  for (size_t i = 0 ; i < Np_real + 1 ; i++)
876  {
877  sync[0][i] = se3.sync[0][i];
878  sync[1][i] = se3.sync[1][i];
879  }
880 
881  return *this;
882  }
883 
884  template<unsigned int prp> void setHaloOutSync()
885  {
886  sync[HALO][prp] = NOTSYNC;
887  }
888 
889  template<unsigned int prp> void setGhostOutSync()
890  {
891  sync[GHOST][prp] = NOTSYNC;
892  }
893 
894  void getNN()
895  {
896  if (sync[GHOST][Np_real] == NOTSYNC)
897  {
898  std::cerr << __FILE__ << ":" << __LINE__ << " Error you are trying to get a Cell-list or Verlet-list without having the ghost synchronized in position please use ghost_get before" << std::endl;
899  ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
900  }
901  }
902 };
903 
904 
905 #endif /* SRC_VECTOR_SE_CLASS3_VECTOR_HPP_ */
std::string getPrpName(size_t i) const
Get property name.
static bool isInf(tcheck(&data)[N1])
It check if the type is Infinity, data type to check.
int sync[2][Np]
status of the properties
static bool isNan(tcheck(&data)[N1])
It check if the type is Nan, data type to check.
this class is a functor for "for_each" algorithm
this class is a functor for "for_each" algorithm
Decomposition & dec
Domain decomposition object.
void operator()(T &t) const
It call the copy function for each property.
openfpm::vector< size_t > non_NP
temporal buffer
void operator()(T &t) const
It call the copy function for each property.
bool isInside(const Point< dim, T > &p) const
Check if the point is inside the box.
Definition: Box.hpp:880
init_prop(size_t(&prp_init)[Np])
constructor
Type check in case of unknown type.
static const int init
it indicate the property is not initialized
this class is a functor for "for_each" algorithm
static bool isInf(tcheck(&data)[N1][N2])
It check if the type is Infinity, data type to check.
vector & vd
Reference to the distributed object.
size_t isGhostSync()
return the status of the ghosts
size_t size()
Stub size.
Definition: map_vector.hpp:70
const vector & data
Data to check.
This class implement the point shape in an N-dimensional space.
Definition: Point.hpp:22
is initialized
propCheckNAN(const vector &data, size_t id)
constructor
const vector & data
Data to check.
void map_post()
Operation to do after map.
This class define the domain decomposition interface.
se_class3_vector< Np, dim, T, Decomposition, vector > & operator=(const se_class3_vector< Np, dim, T, Decomposition, vector > &se3)
Copy operator.
static bool isInf(const tcheck &data)
It check if the type is Infinity, data type to check.
static bool isNan(const tcheck &data)
It check if the type is Nan, data type to check.
propCheckINF(const vector &data, size_t id)
constructor
static bool isInf(const tcheck &data)
It check if the type is Infinity, data type to check.
void Initialize()
Initialize the se_class2 structure.
bool isLocalHalo(const Point< dim, T > &p)
It check if the particle is in the internal ghost area.
static const size_t Np_real
number of real properties + POSITION
size_t id
Element to check.
This class check for inconsistency access.
static bool isNan(const tcheck &data)
It check if the type is Nan, data type to check.
size_t(& prp_init)[Np]
vector for prop initialization
This class represent an N-dimensional box.
Definition: Box.hpp:56
static bool isNan(tcheck(&data)[N1][N2])
It check if the type is Nan, data type to check.
void create_NNP(const size_t(&gg)[sizeof...(prp)+1])
Fill non_NP with the properties that are not synchronized.
size_t getParticleType(const Point< dim, T > &p, const size_t &id, vector &vd)
Given the position it return the particle type.
size_t l_wrt
last write
se_class3_vector(Decomposition &dec, vector &vd)
void operator()(T &t) const
It call the copy function for each property.