OpenFPM  5.2.0
Project that contain the implementation of distributed structures
vector_dist_operators_apply_kernel.hpp
1 /*
2  * vector_dist_operators_apply_kernel.hpp
3  *
4  * Created on: Jun 19, 2016
5  * Author: i-bird
6  */
7 
8 #ifndef OPENFPM_NUMERICS_SRC_OPERATORS_VECTOR_VECTOR_DIST_OPERATORS_APPLY_KERNEL_HPP_
9 #define OPENFPM_NUMERICS_SRC_OPERATORS_VECTOR_VECTOR_DIST_OPERATORS_APPLY_KERNEL_HPP_
10 
12 
13 #define DEFINE_INTERACTION_3D(name) struct name \
14 {\
15 \
16  Point<3,double> value(const Point<3,double> & xp, const Point<3,double> xq)\
17  {
18 
19 #define END_INTERACTION }\
20  };
21 
28 template<typename ObjType, typename Sfinae = void>
29 struct is_expression: std::false_type {};
30 
31 template<typename ObjType>
32 struct is_expression<ObjType, typename Void<typename ObjType::is_expression>::type> : std::true_type
33 {};
34 
36 template<typename exp, bool is_exp = is_expression<exp>::value>
38 {
40  typedef typename exp::return_type rtype;
41 };
42 
44 template<typename exp>
45 struct apply_kernel_rtype<exp,false>
46 {
48  typedef exp rtype;
49 };
50 
51 
56 template<typename rtype>
57 struct set_zero
58 {
60  __device__ __host__ static rtype create()
61  {
62  return 0.0;
63  }
64 };
65 
67 template<unsigned int dim, typename T>
68 struct set_zero<Point<dim,T>>
69 {
71  __device__ __host__ static Point<dim,T> create()
72  {
73  Point<dim,T> ret;
74 
75  ret.zero();
76  return ret;
77  }
78 };
79 
84 template<typename T, typename vector, typename exp,typename NN_type, typename Kernel, typename rtype, bool is_exp=is_expression<T>::value>
86 {
98  inline __host__ __device__ static typename std::remove_reference<rtype>::type apply(const vector & vd, NN_type & cl, const exp & v_exp, const vect_dist_key_dx & key, Kernel & lker)
99  {
100  // accumulator
101  typename std::remove_reference<rtype>::type pse = set_zero<typename std::remove_reference<rtype>::type>::create();
102 
103  // position of particle p
105 
106  // property of the particle x
107  rtype prp_p = v_exp.value(key);
108 
109  // Get the neighborhood of the particle
110  auto NN = cl.getNNIteratorBox(cl.getCell(p));
111  while(NN.isNext())
112  {
113  auto nnp = NN.get();
114 
115  // Calculate contribution given by the kernel value at position p,
116  // given by the Near particle, exclude itself
117  if (nnp != key.getKey())
118  {
119  vect_dist_key_dx nnp_k;
120  nnp_k.setKey(nnp);
121 
122  // property of the particle x
123  rtype prp_q = v_exp.value(nnp_k);
124 
125  // position of the particle q
127 
128  pse += lker.value(p,q,prp_p,prp_q);
129  }
130 
131  // Next particle
132  ++NN;
133  }
134 
135  return pse;
136  }
137 };
138 
139 
144 template<typename vector, typename exp,typename NN_type, typename Kernel, typename rtype>
146 {
157  __device__ __host__ inline static typename std::remove_reference<rtype>::type apply(const vector & vd, NN_type & cl, const vect_dist_key_dx & key, Kernel & lker)
158  {
159  // accumulator
160  typename std::remove_reference<rtype>::type pse = set_zero<typename std::remove_reference<rtype>::type>::create();
161 
162  // position of particle p
164 
165  // Get the neighborhood of the particle
166  auto NN = cl.getNNIteratorBox(cl.getCell(p));
167  while(NN.isNext())
168  {
169  auto nnp = NN.get();
170 
171  // Calculate contribution given by the kernel value at position p,
172  // given by the Near particle, exclude itself
173  if (nnp != key.getKey())
174  {
175  // position of the particle q
177 
178  pse += lker.value(p,q);
179  }
180 
181  // Next particle
182  ++NN;
183  }
184 
185  return pse;
186  }
187 };
188 
189 
190 
195 template<typename T, typename vector, typename exp,typename NN_type, typename Kernel, typename rtype, bool is_exp=is_expression<T>::value>
197 {
209  __device__ __host__ inline static typename std::remove_reference<rtype>::type apply(const vector & vd, NN_type & cl, const exp & v_exp, const vect_dist_key_dx & key, Kernel & lker)
210  {
211  // accumulator
212  typename std::remove_reference<rtype>::type pse = set_zero<typename std::remove_reference<rtype>::type>::create();
213 
214  // property of the particle x
215  rtype prp_p = v_exp.value(key);
216 
217  // position of particle p
219 
220  // Get the neighborhood of the particle
221  auto NN = cl.getNNIteratorBox(cl.getCell(p));
222  while(NN.isNext())
223  {
224  auto nnp = NN.get();
225 
226  // Calculate contribution given by the kernel value at position p,
227  // given by the Near particle, exclude itself
228  if (nnp != key.getKey())
229  {
230  vect_dist_key_dx nnp_k;
231  nnp_k.setKey(nnp);
232 
233  // property of the particle x
234  rtype prp_q = v_exp.value(nnp_k);
235 
236  pse += lker.value(key.getKey(),nnp,prp_p,prp_q,vd);
237  }
238 
239  // Next particle
240  ++NN;
241  }
242 
243  return pse;
244  }
245 };
246 
247 template<typename T, bool mm>
249 {
250  T obj;
251 
252  mutable_or_not(const T & obj)
253  :obj(obj)
254  {}
255 };
256 
257 template<typename T>
258 struct mutable_or_not<T,true>
259 {
260  mutable T obj;
261 
262  mutable_or_not(const T & obj)
263  :obj(obj)
264  {}
265 };
266 
267 template<typename T, bool is_reference = std::is_reference<T>::value>
269 {
270  typedef const T type;
271 };
272 
273 template<typename T>
274 struct add_const_reference<T,true>
275 {
276  typedef typename std::remove_reference<T>::type const & type;
277 };
278 
285 template <typename exp1,typename vector_type>
286 class vector_dist_expression_op<exp1,vector_type,VECT_APPLYKER_IN>
287 {
289  typedef typename boost::mpl::at<vector_type,boost::mpl::int_<0>>::type NN;
291  typedef typename boost::mpl::at<vector_type,boost::mpl::int_<1>>::type Kernel;
293  typedef typename boost::mpl::at<vector_type,boost::mpl::int_<2>>::type vector_orig;
294 
296  typedef typename std::remove_reference<NN>::type NN_nr;
298  typedef typename std::remove_reference<Kernel>::type Kernel_nr;
300  typedef typename std::remove_reference<vector_orig>::type vector_orig_nr;
301 
303  const exp1 o1;
304 
307 
310 
313 
315  typedef typename apply_kernel_rtype<decltype(o1.value(vect_dist_key_dx()))>::rtype rtype;
316 
317 public:
318 
321 
324 
326  typedef NN_nr NN_type;
327 
333  inline NN_nr * getNN() const
334  {
335  return &cl.obj;
336  }
337 
343  inline const vtype & getVector() const
344  {
345  return vd;
346  }
347 
353  inline void init() const
354  {
355  o1.init();
356  }
357 
367  vector_dist_expression_op(const exp1 & o1, const NN& cl, Kernel & ker, const vector_orig_nr & vd)
368  :o1(o1),cl(cl),ker(ker),vd(vd)
369  {}
370 
378  __device__ __host__ inline typename std::remove_reference<rtype>::type value(const vect_dist_key_dx & key) const
379  {
380  return apply_kernel_is_number_or_expression<decltype(o1.value(key)),
382  exp1,
383  NN_nr,
384  Kernel_nr,
385  rtype>::apply(vd,cl.obj,o1,key,ker.obj);
386  }
387 };
388 
395 template <typename exp1,typename vector_type>
396 class vector_dist_expression_op<exp1,vector_type,VECT_APPLYKER_IN_SIM>
397 {
399  typedef typename boost::mpl::at<vector_type,boost::mpl::int_<0>>::type NN;
401  typedef typename boost::mpl::at<vector_type,boost::mpl::int_<1>>::type Kernel;
403  typedef typename boost::mpl::at<vector_type,boost::mpl::int_<2>>::type vector_orig;
404 
406  typedef typename std::remove_reference<NN>::type NN_nr;
408  typedef typename std::remove_reference<Kernel>::type Kernel_nr;
410  typedef typename std::remove_reference<vector_orig>::type vector_orig_nr;
411 
414 
417 
420 
423 
424 
425 public:
426 
429 
432 
434  typedef NN_nr NN_type;
435 
441  inline NN_nr * getNN() const
442  {
443  return &cl.obj;
444  }
445 
451  inline const vtype & getVector() const
452  {
453  return vd;
454  }
455 
461  inline void init() const
462  {
463  }
464 
472  vector_dist_expression_op(const NN & cl, Kernel & ker, const vector_orig & vd)
473  :cl(cl),ker(ker),vd(vd)
474  {}
475 
483  __device__ __host__ inline typename std::remove_reference<rtype>::type value(const vect_dist_key_dx & key) const
484  {
486  exp1,
487  NN_nr,
488  Kernel_nr,
489  rtype>::apply(vd,cl.obj,key,ker.obj);
490  }
491 };
492 
499 template <typename exp1,typename vector_type>
500 class vector_dist_expression_op<exp1,vector_type,VECT_APPLYKER_IN_GEN>
501 {
503  typedef typename boost::mpl::at<vector_type,boost::mpl::int_<0>>::type NN;
505  typedef typename boost::mpl::at<vector_type,boost::mpl::int_<1>>::type Kernel;
506 
508  typedef typename boost::mpl::at<vector_type,boost::mpl::int_<2>>::type vector_orig;
509 
511  typedef typename std::remove_reference<NN>::type NN_nr;
513  typedef typename std::remove_reference<Kernel>::type Kernel_nr;
515  typedef typename std::remove_reference<vector_orig>::type vector_orig_nr;
516 
518  const exp1 o1;
519 
522 
525 
528 
530  typedef typename apply_kernel_rtype<decltype(o1.value(vect_dist_key_dx()))>::rtype rtype;
531 
532 public:
533 
536 
539 
541  typedef NN_nr NN_type;
542 
548  inline NN_nr * getNN() const
549  {
550  return &cl.obj;
551  }
552 
558  inline const vtype & getVector() const
559  {
560  return vd;
561  }
562 
568  inline void init() const
569  {
570  o1.init();
571  }
572 
581  vector_dist_expression_op(const exp1 & o1, const NN & cl, Kernel & ker, const vector_orig & vd)
582  :o1(o1),cl(cl),ker(ker),vd(vd)
583  {}
584 
592  __device__ __host__ inline typename std::remove_reference<rtype>::type value(const vect_dist_key_dx & key) const
593  {
595  decltype(o1.value(key)),
597  exp1,
598  NN_nr,
599  Kernel_nr,
600  rtype
601  >::apply(vd,cl.obj,o1,key,ker.obj);
602  }
603 };
604 
605 template<typename cl_type, int impl=2*is_gpu_celllist<cl_type>::type::value + is_gpu_ker_celllist<cl_type>::type::value >
607 {
608  typedef cl_type& ctype;
609 
610  static ctype & get(cl_type & cl)
611  {
612  return cl;
613  }
614 };
615 
616 template<typename cl_type>
617 struct cl_selector_impl<cl_type,2>
618 {
619  typedef decltype(std::declval<cl_type>().toKernel()) ctype;
620 
621  static ctype get(cl_type & cl)
622  {
623  return cl.toKernel();
624  }
625 };
626 
627 template<typename cl_type>
628 struct cl_selector_impl<cl_type,1>
629 {
630  typedef cl_type ctype;
631 
632  static ctype & get(cl_type & cl)
633  {
634  return cl;
635  }
636 };
637 
638 template<typename kl_type, typename cl_type, int impl=2*is_gpu_celllist<cl_type>::type::value + is_gpu_ker_celllist<cl_type>::type::value >
640 {
641  typedef kl_type& ktype;
642 };
643 
644 template<typename kl_type, typename cl_type>
645 struct kl_selector_impl<kl_type,cl_type,2>
646 {
647  typedef kl_type ktype;
648 };
649 
650 template<typename kl_type, typename cl_type>
651 struct kl_selector_impl<kl_type,cl_type,1>
652 {
653  typedef kl_type ktype;
654 };
655 
656 template<bool uwk, typename T>
658 {
659  typedef T type;
660 
661  static T & get(T & v)
662  {
663  return v;
664  }
665 };
666 
667 template<typename T>
668 struct unroll_with_to_kernel<true,T>
669 {
670  typedef decltype(std::declval<T>().toKernel()) type;
671 
672  static type get(T & v)
673  {
674  return v.toKernel();
675  }
676 };
677 
678 template<typename vl_type, typename cl_type, int impl=2*is_gpu_celllist<cl_type>::type::value + is_gpu_ker_celllist<cl_type>::type::value>
680 {
681  typedef vl_type& vtype;
682 
683  static vtype & get(vl_type & v)
684  {
685  return v;
686  }
687 };
688 
689 template<typename vl_type, typename cl_type>
690 struct vl_selector_impl<vl_type,cl_type,2>
691 {
692  typedef decltype(std::declval<vl_type>().toKernel()) vtype;
693 
694  static vtype get(vl_type & v)
695  {
696  return v.toKernel();
697  }
698 };
699 
700 template<typename vl_type, typename cl_type>
701 struct vl_selector_impl<vl_type,cl_type,1>
702 {
703  typedef typename unroll_with_to_kernel<has_toKernel<vl_type>::type::value,vl_type>::type vtype;
704 
705  static vtype get(vl_type & v)
706  {
708  }
709 };
710 
711 
714 
715 /* \brief Apply kernel expression
716  *
717  * \param va vector expression one
718  * \param vb vector expression two
719  *
720  * \return an object that encapsulate the expression
721  *
722  */
723 template<typename exp1, typename exp2, unsigned int op1, typename NN, typename Kernel, typename vector_type>
725  boost::mpl::vector<typename cl_selector_impl<NN>::ctype,
726  typename kl_selector_impl<Kernel,NN>::ktype,
728  VECT_APPLYKER_IN>
729 applyKernel_in(const vector_dist_expression_op<exp1,exp2,op1> & va, vector_type & vd, NN & cl, Kernel & ker)
730 {
733  boost::mpl::vector<typename cl_selector_impl<NN>::ctype,
734  typename kl_selector_impl<Kernel,NN>::ktype,
736  VECT_APPLYKER_IN
737  > exp_sum(va,
738  cl_selector_impl<NN>::get(cl), ker,
740  );
741 
742  return exp_sum;
743 }
744 
745 
748 
749 /* \brief Apply kernel expression
750  *
751  * \param va vector expression one
752  * \param vb vector expression two
753  *
754  * \return an object that encapsulate the expression
755  *
756  */
757 template<typename exp1, typename exp2, unsigned int op1, typename NN, typename Kernel, typename vector_type>
759  boost::mpl::vector<typename cl_selector_impl<NN>::ctype,
760  typename kl_selector_impl<Kernel,NN>::ktype,
762  VECT_APPLYKER_IN_GEN>
763 applyKernel_in_gen(const vector_dist_expression_op<exp1,exp2,op1> & va, vector_type & vd, NN & cl, Kernel & ker)
764 {
767  boost::mpl::vector<typename cl_selector_impl<NN>::ctype,
768  typename kl_selector_impl<Kernel,NN>::ktype,
770  VECT_APPLYKER_IN_GEN
771  > exp_sum(va,
773  ker,
775  );
776 
777  return exp_sum;
778 }
779 
781 
782 /* \brief Apply kernel expression
783  *
784  * \param va vector expression one
785  * \param vb vector expression two
786  *
787  * \return an object that encapsulate the expression
788  *
789  */
790 template<unsigned int prp, typename NN, typename Kernel, typename vector_type, typename vector_type_ker>
792  boost::mpl::vector<typename cl_selector_impl<NN>::ctype,
793  typename kl_selector_impl<Kernel,NN>::ktype,
795  VECT_APPLYKER_IN>
796 applyKernel_in(const vector_dist_expression<prp,vector_type_ker> & va, vector_type & vd, NN & cl, Kernel & ker)
797 {
800  boost::mpl::vector<typename cl_selector_impl<NN>::ctype,
801  typename kl_selector_impl<Kernel,NN>::ktype,
803  VECT_APPLYKER_IN
804  > exp_sum(va,
806  ker,
808  );
809 
810  return exp_sum;
811 }
812 
813 /* \brief Apply kernel expression
814  *
815  * \param va vector expression one
816  * \param vb vector expression two
817  *
818  * \return an object that encapsulate the expression
819  *
820  */
821 template<unsigned int prp, typename NN, typename Kernel, typename vector_type, typename vector_type_ker>
823  boost::mpl::vector<typename cl_selector_impl<NN>::ctype,
824  typename kl_selector_impl<Kernel,NN>::ktype,
826  VECT_APPLYKER_IN_GEN>
827 applyKernel_in_gen(const vector_dist_expression<prp,vector_type_ker> & va, vector_type & vd, NN & cl, Kernel & ker)
828 {
831  boost::mpl::vector<typename cl_selector_impl<NN>::ctype,
832  typename kl_selector_impl<Kernel,NN>::ktype,
834  VECT_APPLYKER_IN_GEN
835  > exp_sum(va,
837  ker,
839  );
840 
841  return exp_sum;
842 }
843 
844 /* \brief Apply kernel expression
845  *
846  * \param va vector expression one
847  * \param vb vector expression two
848  *
849  * \return an object that encapsulate the expression
850  *
851  */
852 template<typename NN, typename Kernel, typename vector_type>
853 inline vector_dist_expression_op<void,
854  boost::mpl::vector<typename cl_selector_impl<NN>::ctype,
855  typename kl_selector_impl<Kernel,NN>::ktype,
857  VECT_APPLYKER_IN_SIM>
858 applyKernel_in_sim(vector_type & vd, NN & cl, Kernel & ker)
859 {
861  void,
862  boost::mpl::vector<typename cl_selector_impl<NN>::ctype,
863  typename kl_selector_impl<Kernel,NN>::ktype,
865  VECT_APPLYKER_IN_SIM
866  > exp_sum(cl_selector_impl<NN>::get(cl),
867  ker,
869  );
870 
871  return exp_sum;
872 }
873 
874 #endif /* OPENFPM_NUMERICS_SRC_OPERATORS_VECTOR_VECTOR_DIST_OPERATORS_APPLY_KERNEL_HPP_ */
This class implement the point shape in an N-dimensional space.
Definition: Point.hpp:28
__device__ __host__ T & value(size_t i)
Return the reference to the value at coordinate i.
Definition: Point.hpp:434
__device__ __host__ void zero()
Set to zero the point coordinate.
Definition: Point.hpp:299
Grid key for a distributed grid.
__device__ __host__ size_t getKey() const
Get the key.
__device__ __host__ void setKey(size_t key)
set the key
std::remove_reference< vector_orig >::type vector_orig_nr
Return the vector containing the position of the particles.
boost::mpl::at< vector_type, boost::mpl::int_< 0 > >::type NN
Get the type of the Cell-list.
boost::mpl::at< vector_type, boost::mpl::int_< 2 > >::type vector_orig
Get the type that contain the particle positions.
has_vector_kernel< vector_orig_nr >::type is_ker
indicate if this expression operate on kernel expression
vector_dist_expression_op(const exp1 &o1, const NN &cl, Kernel &ker, const vector_orig_nr &vd)
Constructor.
boost::mpl::at< vector_type, boost::mpl::int_< 1 > >::type Kernel
Get the type of the kernel.
add_const_reference< vector_orig >::type vd
The vector that contain the particles.
mutable_or_not< Kernel, is_gpu_celllist< NN >::type::value||is_gpu_ker_celllist< NN >::type::value > ker
kernel
__device__ __host__ std::remove_reference< rtype >::type value(const vect_dist_key_dx &key) const
Evaluate the expression.
apply_kernel_rtype< decltype(o1.value(vect_dist_key_dx()))>::rtype rtype
Get the return type of applying the kernel to a particle.
mutable_or_not< NN, is_gpu_celllist< NN >::type::value||is_gpu_ker_celllist< NN >::type::value > cl
Cell-list.
std::remove_reference< Kernel >::type Kernel_nr
Return the type of the kernel.
std::remove_reference< NN >::type NN_nr
Return the type of the Cell-list.
mutable_or_not< NN, is_gpu_celllist< NN >::type::value||is_gpu_ker_celllist< NN >::type::value > cl
Cell-list.
boost::mpl::at< vector_type, boost::mpl::int_< 2 > >::type vector_orig
Get the type of the vector containing the set of particles.
std::remove_reference< vector_orig >::type vector_orig_nr
Return the vector containing the position of the particles.
boost::mpl::at< vector_type, boost::mpl::int_< 1 > >::type Kernel
Get the type of the kernel.
std::remove_reference< NN >::type NN_nr
Return the type of the Cell-list.
boost::mpl::at< vector_type, boost::mpl::int_< 0 > >::type NN
Get the type of the Cell-list.
__device__ __host__ std::remove_reference< rtype >::type value(const vect_dist_key_dx &key) const
Evaluate the expression.
vector_dist_expression_op(const exp1 &o1, const NN &cl, Kernel &ker, const vector_orig &vd)
Constructor.
has_vector_kernel< vector_orig_nr >::type is_ker
indicate if this expression operate on kernel expression
std::remove_reference< Kernel >::type Kernel_nr
Return the type of the kernel.
apply_kernel_rtype< decltype(o1.value(vect_dist_key_dx()))>::rtype rtype
Return type of the expression.
mutable_or_not< Kernel, is_gpu_celllist< NN >::type::value||is_gpu_ker_celllist< NN >::type::value > ker
kernel
apply_kernel_rtype< decltype(std::declval< Kernel_nr >).value(Point< vector_orig_nr::dims, typename vector_orig_nr::stype >0.0), Point< vector_orig_nr::dims, typename vector_orig_nr::stype >0.0)))>::rtype rtype
Get the return type of the expression.
vector_dist_expression_op(const NN &cl, Kernel &ker, const vector_orig &vd)
Constructor.
has_vector_kernel< vector_orig_nr >::type is_ker
indicate if this expression operate on kernel expression
__device__ __host__ std::remove_reference< rtype >::type value(const vect_dist_key_dx &key) const
Evaluate the expression.
boost::mpl::at< vector_type, boost::mpl::int_< 0 > >::type NN
Return the type of the Cell-list.
std::remove_reference< Kernel >::type Kernel_nr
Return the type of the kernel.
boost::mpl::at< vector_type, boost::mpl::int_< 2 > >::type vector_orig
Return the vector containing the position of the particles.
std::remove_reference< vector_orig >::type vector_orig_nr
Return the vector containing the position of the particles.
boost::mpl::at< vector_type, boost::mpl::int_< 1 > >::type Kernel
Return the type of the kernel.
std::remove_reference< NN >::type NN_nr
Return the type of the Cell-list.
mutable_or_not< Kernel, is_gpu_celllist< NN >::type::value||is_gpu_ker_celllist< NN >::type::value > ker
kernel
mutable_or_not< NN, is_gpu_celllist< NN >::type::value||is_gpu_ker_celllist< NN >::type::value > cl
Cell-list.
Unknown operation specialization.
Main class that encapsulate a vector properties operand to be used for expressions construction.
Distributed vector.
Void structure.
Definition: common.hpp:74
Apply the kernel to particle differently that is a number or is an expression.
__device__ static __host__ std::remove_reference< rtype >::type apply(const vector &vd, NN_type &cl, const exp &v_exp, const vect_dist_key_dx &key, Kernel &lker)
Apply the kernel expression to a particle.
Apply the kernel to particle differently that is a number or is an expression.
__device__ static __host__ std::remove_reference< rtype >::type apply(const vector &vd, NN_type &cl, const vect_dist_key_dx &key, Kernel &lker)
Apply the kernel expression to a particle.
Apply the kernel to particle differently that is a number or is an expression.
__host__ static __device__ std::remove_reference< rtype >::type apply(const vector &vd, NN_type &cl, const exp &v_exp, const vect_dist_key_dx &key, Kernel &lker)
Apply the kernel expression to a particle.
exp rtype
indicate the return type of the expression exp
It give the return type of the expression if applicable.
exp::return_type rtype
indicate the return type of the expression exp
is_expression check if a type is simple a type or is just an encapsulation of an expression
Check this is a gpu or cpu type cell-list.
Definition: util.hpp:87
__device__ static __host__ Point< dim, T > create()
return a point with all the coordinates set to zero
Meta-function to return a compatible zero-element.
__device__ static __host__ rtype create()
return 0