OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
 
Loading...
Searching...
No Matches
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
21enum statuses
22{
23 CLEAN,
24 DIRTY,
25 UNINITIALIZED
26};
27
28enum sync
29{
30 SYNC,
31 NOTSYNC
32};
33
34enum ptype
35{
36 HALO,
37 GHOST,
38 INSIDE
39};
40
42template<typename T>
44{
46 static const int init = UNINITIALIZED;
47};
48
50template<typename T>
51struct is_initialized<openfpm::vector<T>>
52{
54 static const int init = CLEAN;
55};
56
57
59
71template<unsigned int Np, typename vector>
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
104template<typename tcheck, bool foundamental>
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
133template<typename tcheck>
134struct 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
162template<typename tcheck, bool foundamental, unsigned int N1>
163struct 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
207template<typename tcheck, bool foundamental, unsigned int N1, unsigned int N2>
208struct 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
265template<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
315template<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
361static 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
373template<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
396template<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
426template<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
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
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_ */
This class represent an N-dimensional box.
Definition Box.hpp:61
__host__ __device__ bool isInside(const Point< dim, T > &p) const
Check if the point is inside the box.
Definition Box.hpp:1004
This class define the domain decomposition interface.
This class implement the point shape in an N-dimensional space.
Definition Point.hpp:28
Implementation of 1-D std::vector like structure.
size_t size()
Stub size.
This class check for inconsistency access.
void map_post()
Operation to do after map.
size_t isGhostSync()
return the status of the ghosts
std::string getPrpName(size_t i) const
Get property name.
Decomposition & dec
Domain decomposition object.
bool isLocalHalo(const Point< dim, T > &p)
It check if the particle is in the internal ghost area.
size_t getParticleType(const Point< dim, T > &p, const size_t &id, vector &vd)
Given the position it return the particle type.
void Initialize()
Initialize the se_class2 structure.
openfpm::vector< size_t > non_NP
temporal buffer
vector & vd
Reference to the distributed object.
static const size_t Np_real
number of real properties + POSITION
void create_NNP(const size_t(&gg)[sizeof...(prp)+1])
Fill non_NP with the properties that are not synchronized.
size_t l_wrt
last write
se_class3_vector< Np, dim, T, Decomposition, vector > & operator=(const se_class3_vector< Np, dim, T, Decomposition, vector > &se3)
Copy operator.
se_class3_vector(Decomposition &dec, vector &vd)
int sync[2][Np]
status of the properties
convert a type into constant type
this class is a functor for "for_each" algorithm
size_t(& prp_init)[Np]
vector for prop initialization
void operator()(T &t) const
It call the copy function for each property.
init_prop(size_t(&prp_init)[Np])
constructor
is initialized
static const int init
it indicate the property is not initialized
this class is a functor for "for_each" algorithm
const vector & data
Data to check.
void operator()(T &t) const
It call the copy function for each property.
propCheckINF(const vector &data, size_t id)
constructor
this class is a functor for "for_each" algorithm
void operator()(T &t) const
It call the copy function for each property.
const vector & data
Data to check.
propCheckNAN(const vector &data, size_t id)
constructor
size_t id
Element to check.
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.
static bool isNan(tcheck(&data)[N1])
It check if the type is Nan, data type to check.
static bool isInf(tcheck(&data)[N1])
It check if the type is Infinity, data type to check.
static bool isInf(tcheck(&data)[N1][N2])
It check if the type is Infinity, data type to check.
static bool isNan(tcheck(&data)[N1][N2])
It check if the type is Nan, data type to check.
Type check in case of unknown type.
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.