1/*
2 * staggered_grid_dist_copy.hpp
3 *
4 * Created on: Apr 9, 2016
5 * Author: i-bird
6 */
7
8#ifndef SRC_GRID_STAGGERED_DIST_GRID_COPY_HPP_
9#define SRC_GRID_STAGGERED_DIST_GRID_COPY_HPP_
10
11/*! \brief Add scalar elements
12 *
13 * \tparam copy_type Type that should be copied
14 * \tparam T property id to copy
15 * \tparam Grid_src Staggered source Grid
16 * \tparam sa dimensionality of the array 0 is a scalar
17 *
18 */
19template<typename copy_type, typename Tsrc, typename Tdst, typename Grid_src, typename Grid_dst, int sa>
20struct interp_ele_sca_array
21{
22 inline static void interp(Grid_dst & grid_dst, const grid_dist_key_dx<Grid_dst::dims> & key_dst ,const Grid_src & x, const grid_dist_key_dx<Grid_src::dims> & key_src, const openfpm::vector<std::vector<comb<Grid_src::dims>>> & interp_pos)
23 {
24 typedef typename boost::mpl::at<Tdst,Tsrc>::type Tdst_ele;
25
26 copy_type division = 0.0;
27
28 for (size_t i = 0 ; i < interp_pos.get(0).size() ; i++)
29 {
30 auto key_m = key_src.move(interp_pos.get(0)[i]);
31
32 grid_dst.template get<Tdst_ele::value>(key_dst) += x.template get<Tsrc::value>(key_m);
33
34 division += 1.0;
35 }
36 grid_dst.template get<Tdst_ele::value>(key_dst) /= division;
37 }
38};
39
40/*! \brief Add 1D array elements
41 *
42 * spacialization in case of 1D array
43 *
44 * \tparam copy_type Type that should be copied
45 * \tparam T property id to copy
46 * \tparam Ev Type of source the Vector
47 *
48 */
49template<typename copy_type, typename Tsrc, typename Tdst, typename Grid_src, typename Grid_dst>
50struct interp_ele_sca_array<copy_type,Tsrc,Tdst,Grid_src,Grid_dst,1>
51{
52 inline static void interp(Grid_dst & grid_dst,
53 const grid_dist_key_dx<Grid_dst::dims> & key_dst ,
54 const Grid_src & x,
55 const grid_dist_key_dx<Grid_src::dims> & key_src,
56 const openfpm::vector<std::vector<comb<Grid_src::dims>>> & interp_pos)
57 {
58 typename std::remove_all_extents<copy_type>::type division;
59 typedef typename boost::mpl::at<Tdst,Tsrc>::type Tdst_ele;
60
61 for (size_t j = 0 ; j < std::extent<copy_type>::value ; j++)
62 {
63 division = 0.0;
64 for (size_t i = 0 ; i < interp_pos.get(j).size() ; i++)
65 {
66 auto key_m = key_src.move(interp_pos.get(j)[i]);
67
68 grid_dst.template get<Tdst_ele::value>(key_dst)[j] += x.template get<Tsrc::value>(key_m)[j];
69
70 division += 1.0;
71 }
72 grid_dst.template get<Tsrc::value>(key_dst)[j] /= division;
73 }
74 }
75};
76
77/*! \brief this class is a functor for "for_each" algorithm
78 *
79 * This class is a functor for "for_each" algorithm. For each
80 * element of the boost::vector the operator() is called.
81 * Is mainly used to interpolate from the staggered grid to the normal target grid
82 *
83 * \tparam Tdst destination property of the normal grid
84 * \tparam Type of the destination grid
85 * \tparam Type of the source grid
86 *
87 */
88template<typename Tdst, typename Grid_dst, typename Grid_src, unsigned int nst_pos>
89struct interp_ele
90{
91 //! destination point
92 const grid_dist_key_dx<Grid_dst::dims> key_dst;
93
94 //! destination grid
95 Grid_dst & grid_dst;
96
97 //! source point
98 grid_dist_key_dx<Grid_dst::dims> key_src;
99
100 //! For each properties [] for each components (openfpm::vector) interpolants points positions (std::vector<comb>)
101 openfpm::vector<std::vector<comb<Grid_dst::dims>>> (&interp_pos)[nst_pos];
102
103 //! source grid
104 const Grid_src & x;
105
106 /*! \brief constructor
107 *
108 * It define the interpolation parameters.
109 *
110 * \param key_dst destination point
111 * \param grid_dst Destination grid
112 * \param x source grid
113 * \param key_src source point
114 * \param interp_pos interpolation points
115 *
116 */
117 inline interp_ele(const grid_dist_key_dx<Grid_dst::dims> & key_dst,
118 Grid_dst & grid_dst,
119 const Grid_src & x,
120 const grid_dist_key_dx<Grid_src::dims> & key_src,
121 openfpm::vector<std::vector<comb<Grid_src::dims>>> (&interp_pos)[nst_pos])
122 :key_dst(key_dst),grid_dst(grid_dst),key_src(key_src),interp_pos(interp_pos),x(x){};
123
124
125#ifdef SE_CLASS1
126 /*! \brief Constructor
127 *
128 * Calling this constructor produce an error. This class store the reference of the object,
129 * this mean that the object passed must not be a temporal object
130 *
131 */
132 inline interp_ele(const grid_dist_key_dx<Grid_dst::dims> & key_dst, Grid_dst && grid_dst, const Grid_src & x, const grid_dist_key_dx<Grid_src::dims> & key_src, openfpm::vector<std::vector<comb<Grid_src::dims>>> (&interp_pos)[nst_pos])
133 :key_dst(key_dst),grid_dst(grid_dst),key_src(key_src),interp_pos(interp_pos),x(x)
134 {std::cerr << "Error: " <<__FILE__ << ":" << __LINE__ << " Passing a temporal object";};
135#endif
136
137 /*! \brief Interpolate each point in the destination grid for each property
138 *
139 * \param t property id
140 *
141 */
142 template<typename Tsrc>
143 inline void operator()(Tsrc& t)
144 {
145 // This is the type of the object we have to copy
146 typedef typename boost::mpl::at_c<typename Grid_dst::value_type::type,Tsrc::value>::type copy_type;
147
148 interp_ele_sca_array<copy_type,Tsrc,Tdst,Grid_src,Grid_dst,std::rank<copy_type>::value>::interp(grid_dst,key_dst,x,key_src,interp_pos[Tsrc::value]);
149 }
150};
151
152
153#endif /* SRC_GRID_STAGGERED_DIST_GRID_COPY_HPP_ */
154