From 6274ea12ff26d87573f361a2b1b801cb1883e38c Mon Sep 17 00:00:00 2001
From: Pietro Incardona <i-bird@localhost.localdomain>
Date: Sun, 26 Jun 2016 21:38:55 +0200
Subject: [PATCH] Adding missing files

---
 .../vector_dist_operators_apply_kernel.hpp    | 382 ++++++++++++++++++
 ...dist_operators_apply_kernel_unit_tests.hpp | 304 ++++++++++++++
 2 files changed, 686 insertions(+)
 create mode 100644 src/Operators/Vector/vector_dist_operators_apply_kernel.hpp
 create mode 100644 src/Operators/Vector/vector_dist_operators_apply_kernel_unit_tests.hpp

diff --git a/src/Operators/Vector/vector_dist_operators_apply_kernel.hpp b/src/Operators/Vector/vector_dist_operators_apply_kernel.hpp
new file mode 100644
index 00000000..bd10cd81
--- /dev/null
+++ b/src/Operators/Vector/vector_dist_operators_apply_kernel.hpp
@@ -0,0 +1,382 @@
+/*
+ * vector_dist_operators_apply_kernel.hpp
+ *
+ *  Created on: Jun 19, 2016
+ *      Author: i-bird
+ */
+
+#ifndef OPENFPM_NUMERICS_SRC_OPERATORS_VECTOR_VECTOR_DIST_OPERATORS_APPLY_KERNEL_HPP_
+#define OPENFPM_NUMERICS_SRC_OPERATORS_VECTOR_VECTOR_DIST_OPERATORS_APPLY_KERNEL_HPP_
+
+
+/*! \brief is_expression check if a type is simple a type or is just an encapsulation of an expression
+ *
+ * return true if T::is_expression is a valid expression
+ *
+ */
+
+template<typename ObjType, typename Sfinae = void>
+struct is_expression: std::false_type {};
+
+template<typename ObjType>
+struct is_expression<ObjType, typename Void<typename ObjType::is_expression>::type> : std::true_type
+{};
+
+template<typename exp, bool is_exp = is_expression<exp>::value>
+struct apply_kernel_rtype
+{
+	typedef typename exp::return_type rtype;
+};
+
+template<typename exp>
+struct apply_kernel_rtype<exp,false>
+{
+	typedef exp rtype;
+};
+
+
+/*! \brief Apply the kernel to particle differently that is a number or is an expression
+ *
+ *
+ */
+template<typename T, typename vector, typename exp,typename NN_type, typename Kernel, typename rtype, bool is_exp=is_expression<T>::value>
+struct apply_kernel_is_number_or_expression
+{
+	inline static rtype apply(const vector & vd, NN_type & cl, const exp & v_exp, const vect_dist_key_dx & key, Kernel & lker)
+	{
+	    // accumulator
+	    rtype pse = static_cast<rtype>(0.0);
+
+	    // position of particle p
+	    Point<vector::dims,typename vector::stype> p = vd.getPos(key);
+
+	    // property of the particle x
+	    rtype prp_p = v_exp.value(key);
+
+	    // Get the neighborhood of the particle
+	    auto NN = cl.template getNNIterator<NO_CHECK>(cl.getCell(p));
+	    while(NN.isNext())
+	    {
+	    	auto nnp = NN.get();
+
+	    	// Calculate contribution given by the kernel value at position p,
+	    	// given by the Near particle, exclude itself
+	    	if (nnp != key.getKey())
+	    	{
+	    	    // property of the particle x
+	    		rtype prp_q = v_exp.value(nnp);
+
+	    	    // position of the particle q
+	    		Point<vector::dims,typename vector::stype> q = vd.getPos(nnp);
+
+	    	    pse += lker.value(p,q,prp_p,prp_q);
+	    	}
+
+	    	// Next particle
+	    	++NN;
+	    }
+
+	    return pse;
+	}
+};
+
+template<typename T, typename vector, typename exp,typename NN_type, typename Kernel, typename rtype>
+struct apply_kernel_is_number_or_expression<T,vector,exp,NN_type,Kernel,rtype,false>
+{
+
+	/*! \brief Apply the kernel
+	 *
+	 * \param cl Neighborhood of particles
+	 * \param v_exp vector expression
+	 * \param key particle id
+	 * \param lker kernel function
+	 *
+	 */
+	inline static rtype apply(const vector & vd, NN_type & cl, const exp & v_exp, const vect_dist_key_dx & key, Kernel & lker)
+	{
+	    // accumulator
+	    rtype pse = 0;
+
+	    // Get f(x) at the position of the particle p
+	    const rtype & prp_p = v_exp.value(key);
+
+	    // position of particle p
+	    auto & p = vd.getPos(key);
+
+	    // Get the neighborhood of the particle
+	    auto NN = cl.template getNNIterator<NO_CHECK>(cl.getCell(p));
+	    while(NN.isNext())
+	    {
+	    	auto nnp = NN.get();
+
+	    	// Calculate contribution given by the kernel value at position p,
+	    	// given by the Near particle, exclude itself
+	    	if (nnp != key.getKey())
+	    	{
+	    	    // Get f(x) at the position of the particle p
+	    	    const rtype & prp_q = v_exp.value(nnp);
+
+	    	    // Get f(x) at the position of the particle
+	    	    auto & q = vd.getPos(nnp);
+
+	    		// W(x-y)
+	    		auto ker = lker.value(p,q,prp_p,prp_q);
+
+	    		pse += ker;
+	    	}
+
+	    	// Next particle
+	    	++NN;
+	    }
+
+	    return pse;
+	}
+};
+
+
+/*! \brief Apply the kernel to particle differently that is a number or is an expression
+ *
+ *
+ */
+template<typename T, typename vector, typename exp,typename NN_type, typename Kernel, typename rtype, bool is_exp=is_expression<T>::value>
+struct apply_kernel_is_number_or_expression_gen
+{
+	inline static rtype apply(const vector & vd, NN_type & cl, const exp & v_exp, const vect_dist_key_dx & key, Kernel & lker)
+	{
+	    // accumulator
+	    rtype pse = static_cast<rtype>(0.0);
+
+	    // position of particle p
+	    Point<vector::dims,typename vector::stype> p = vd.getPos(key);
+
+	    // property of the particle x
+	    rtype prp_p = v_exp.value(key);
+
+	    // Get the neighborhood of the particle
+	    auto NN = cl.template getNNIterator<NO_CHECK>(cl.getCell(p));
+	    while(NN.isNext())
+	    {
+	    	auto nnp = NN.get();
+
+	    	// Calculate contribution given by the kernel value at position p,
+	    	// given by the Near particle, exclude itself
+	    	if (nnp != key.getKey())
+	    	{
+	    	    // property of the particle x
+	    		rtype prp_q = v_exp.value(nnp);
+
+	    	    // position of the particle q
+	    		Point<vector::dims,typename vector::stype> q = vd.getPos(nnp);
+
+	    	    pse += lker.value(p,q,prp_p,prp_q);
+	    	}
+
+	    	// Next particle
+	    	++NN;
+	    }
+
+	    return pse;
+	}
+};
+
+template<typename T, typename vector, typename exp,typename NN_type, typename Kernel, typename rtype>
+struct apply_kernel_is_number_or_expression_gen<T,vector,exp,NN_type,Kernel,rtype,false>
+{
+
+	/*! \brief Apply the kernel
+	 *
+	 * \param cl Neighborhood of particles
+	 * \param v_exp vector expression
+	 * \param key particle id
+	 * \param lker kernel function
+	 *
+	 */
+	inline static rtype apply(const vector & vd, NN_type & cl, const exp & v_exp, const vect_dist_key_dx & key, Kernel & lker)
+	{
+	    // accumulator
+	    rtype pse = 0;
+
+	    // Get f(x) at the position of the particle p
+	    const rtype & prp_p = v_exp.value(key);
+
+	    // position of particle p
+	    auto & p = vd.getPos(key);
+
+	    // Get the neighborhood of the particle
+	    auto NN = cl.template getNNIterator<NO_CHECK>(cl.getCell(p));
+	    while(NN.isNext())
+	    {
+	    	auto nnp = NN.get();
+
+	    	// Calculate contribution given by the kernel value at position p,
+	    	// given by the Near particle, exclude itself
+	    	if (nnp != key.getKey())
+	    	{
+	    	    // Get f(x) at the position of the particle p
+	    	    const rtype & prp_q = v_exp.value(nnp);
+
+	    	    // Get f(x) at the position of the particle
+	    	    auto & q = vd.getPos(nnp);
+
+	    		// W(x-y)
+	    		auto ker = lker.value(vd,p,q,prp_p,prp_q);
+
+	    		pse += ker;
+	    	}
+
+	    	// Next particle
+	    	++NN;
+	    }
+
+	    return pse;
+	}
+};
+
+/*! \brief Apply kernel operation
+ *
+ * \tparam exp1 expression1
+ * \tparam NN list
+ *
+ */
+template <typename exp1,typename vector_type>
+class vector_dist_expression_op<exp1,vector_type,VECT_APPLYKER_IN>
+{
+	typedef typename boost::mpl::at<vector_type,boost::mpl::int_<0>>::type NN;
+	typedef typename boost::mpl::at<vector_type,boost::mpl::int_<1>>::type Kernel;
+	typedef typename boost::mpl::at<vector_type,boost::mpl::int_<2>>::type vector_orig;
+
+	const exp1 o1;
+	NN & cl;
+	Kernel & ker;
+	const vector_orig & vd;
+
+	typedef typename apply_kernel_rtype<decltype(o1.value(vect_dist_key_dx(0)))>::rtype rtype;
+
+public:
+
+	/*! \brief This function must be called before value
+	 *
+	 * it initialize the expression if needed
+	 *
+	 */
+	inline void init() const
+	{
+		o1.init();
+	}
+
+	vector_dist_expression_op(const exp1 & o1, NN & cl, Kernel & ker, const vector_orig & vd)
+	:o1(o1),cl(cl),ker(ker),vd(vd)
+	{}
+
+	/*! \brief Evaluate the expression
+	 *
+	 * \param key where to evaluate the expression
+	 *
+	 */
+	inline rtype value(const vect_dist_key_dx & key) const
+	{
+		return apply_kernel_is_number_or_expression<decltype(o1.value(key)),vector_orig,exp1,NN,Kernel,rtype>::apply(vd,cl,o1,key,ker);
+	}
+};
+
+
+/*! \brief Apply kernel operation
+ *
+ * \tparam exp1 expression1
+ * \tparam NN list
+ *
+ */
+template <typename exp1,typename vector_type>
+class vector_dist_expression_op<exp1,vector_type,VECT_APPLYKER_REDUCE>
+{
+	typedef typename boost::mpl::at<vector_type,boost::mpl::int_<0>>::type NN;
+	typedef typename boost::mpl::at<vector_type,boost::mpl::int_<1>>::type Kernel;
+	typedef typename boost::mpl::at<vector_type,boost::mpl::int_<2>>::type vector_orig;
+
+	const exp1 o1;
+	NN & cl;
+	Kernel & ker;
+	const vector_orig & vd;
+
+	typedef typename apply_kernel_rtype<decltype(o1.value(vect_dist_key_dx(0)))>::rtype rtype;
+
+	// calculated value
+	mutable rtype val;
+
+public:
+
+	vector_dist_expression_op(const exp1 & o1, NN & cl, Kernel & ker, const vector_orig & vd)
+	:o1(o1),cl(cl),ker(ker),vd(vd)
+	{}
+
+	/*! \brief Initialize the calculation
+	 *
+	 *
+	 */
+	void init() const
+	{
+		val = 0.0;
+
+		auto it = vd.getDomainIterator();
+
+		while (it.isNext())
+		{
+			auto key = it.get();
+
+			val += apply_kernel_is_number_or_expression<decltype(o1.value(key)),vector_orig,exp1,NN,Kernel,rtype>::apply(vd,cl,o1,key,ker);
+
+			++it;
+		}
+	}
+
+	/*! \brief Evaluate the expression
+	 *
+	 * \param key where to evaluate the expression
+	 *
+	 */
+	inline rtype value(const vect_dist_key_dx & key) const
+	{
+		return val;
+	}
+};
+
+///////////////////////////////////////////// Apply kernel operator ////
+////////////////////////////////////////////////////////////////////////
+
+/* \brief Apply kernel expression
+ *
+ * \param va vector expression one
+ * \param vb vector expression two
+ *
+ * \return an object that encapsulate the expression
+ *
+ */
+template<typename exp1, typename exp2, unsigned int op1, typename NN, typename Kernel, typename vector_type>
+inline vector_dist_expression_op<vector_dist_expression_op<exp1,exp2,op1>,boost::mpl::vector<NN,Kernel,vector_type>,VECT_APPLYKER_IN>
+applyKernel_in(const vector_dist_expression_op<exp1,exp2,op1> & va, vector_type & vd, NN & cl, Kernel & ker)
+{
+	vector_dist_expression_op<vector_dist_expression_op<exp1,exp2,op1>,boost::mpl::vector<NN,Kernel,vector_type>,VECT_APPLYKER_IN> exp_sum(va,cl,ker,vd);
+
+	return exp_sum;
+}
+
+/* \brief Apply kernel expression
+ *
+ * \param va vector expression one
+ * \param vb vector expression two
+ *
+ * \return an object that encapsulate the expression
+ *
+ */
+template<typename exp1, typename exp2, unsigned int op1, typename NN, typename Kernel, typename vector_type>
+inline vector_dist_expression_op<vector_dist_expression_op<exp1,exp2,op1>,boost::mpl::vector<NN,Kernel,vector_type>,VECT_APPLYKER_REDUCE>
+applyKernel_reduce(const vector_dist_expression_op<exp1,exp2,op1> & va, vector_type & vd, NN & cl, Kernel & ker)
+{
+	vector_dist_expression_op<vector_dist_expression_op<exp1,exp2,op1>,boost::mpl::vector<NN,Kernel,vector_type>,VECT_APPLYKER_REDUCE> exp_sum(va,cl,ker,vd);
+
+	return exp_sum;
+}
+
+
+
+#endif /* OPENFPM_NUMERICS_SRC_OPERATORS_VECTOR_VECTOR_DIST_OPERATORS_APPLY_KERNEL_HPP_ */
diff --git a/src/Operators/Vector/vector_dist_operators_apply_kernel_unit_tests.hpp b/src/Operators/Vector/vector_dist_operators_apply_kernel_unit_tests.hpp
new file mode 100644
index 00000000..ff345fab
--- /dev/null
+++ b/src/Operators/Vector/vector_dist_operators_apply_kernel_unit_tests.hpp
@@ -0,0 +1,304 @@
+/*
+ * vector_dist_operators_apply_kernel_unit_tests.hpp
+ *
+ *  Created on: Jun 19, 2016
+ *      Author: i-bird
+ */
+
+#ifndef OPENFPM_NUMERICS_SRC_OPERATORS_VECTOR_VECTOR_DIST_OPERATORS_APPLY_KERNEL_UNIT_TESTS_HPP_
+#define OPENFPM_NUMERICS_SRC_OPERATORS_VECTOR_VECTOR_DIST_OPERATORS_APPLY_KERNEL_UNIT_TESTS_HPP_
+
+template <typename vector,typename Kernel, typename NN_type> bool check_values_apply_kernel(vector & vd, Kernel & ker, NN_type & NN)
+{
+	bool ret = true;
+	auto it = vd.getDomainIterator();
+
+	// ### WIKI 13 ###
+	//
+	// Check that apply kernel work
+	//
+	auto it2 = vd.getDomainIterator();
+	while (it2.isNext())
+	{
+		float base2 = 0.0;
+		auto p = it2.get();
+
+		Point<3,float> xp = vd.getPos(p);
+
+		float base1 = vd.template getProp<A>(p);
+
+		float prp_x = vd.template getProp<VC>(p) * vd.template getProp<VB>(p) + norm(vd.template getProp<VB>(p));
+
+		// For each neighborhood particle
+		auto Np = NN.template getNNIterator<NO_CHECK>(NN.getCell(vd.getPos(p)));
+
+		while (Np.isNext())
+		{
+			// Neighborhood particle q
+			auto q = Np.get();
+
+			if (q == p.getKey())	{++Np; continue;};
+
+			// position q
+			Point<3,float> xq = vd.getPos(q);
+
+			float prp_y = vd.template getProp<VC>(q) * vd.template getProp<VB>(q) + norm(vd.template getProp<VB>(q));
+
+			base2 += ker.value(xp,xq,prp_x,prp_y);
+
+			++Np;
+		}
+
+		base2 += vd.template getProp<C>(p);
+
+		ret &= base1 == base2;
+
+		++it2;
+	}
+
+	BOOST_REQUIRE_EQUAL(ret,true);
+
+	return ret;
+}
+
+template <typename vector,typename Kernel, typename NN_type> bool check_values_apply_kernel_reduce(vector & vd, Kernel & ker, NN_type & NN)
+{
+	bool ret = true;
+	auto it = vd.getDomainIterator();
+
+	float base1 = 0.0;
+	float base2 = 0.0;
+	float base3 = 0.0;
+
+	auto it2 = vd.getDomainIterator();
+	while (it2.isNext())
+	{
+		auto p = it2.get();
+
+		Point<3,float> xp = vd.getPos(p);
+
+		float ker_accu = 0.0;
+		float prp_x = vd.template getProp<VC>(p) * vd.template getProp<VB>(p) + norm(vd.template getProp<VB>(p));
+
+		// For each neighborhood particle
+		auto Np = NN.template getNNIterator<NO_CHECK>(NN.getCell(vd.getPos(p)));
+
+		while (Np.isNext())
+		{
+			// Neighborhood particle q
+			auto q = Np.get();
+
+			if (q == p.getKey())	{++Np; continue;};
+
+			// position q
+			Point<3,float> xq = vd.getPos(q);
+
+			float prp_y = vd.template getProp<VC>(q) * vd.template getProp<VB>(q) + norm(vd.template getProp<VB>(q));
+
+			ker_accu += ker.value(xp,xq,prp_x,prp_y);
+
+			++Np;
+		}
+
+		base2 += ker_accu;
+
+		++it2;
+	}
+
+	auto it3 = vd.getDomainIterator();
+	while (it3.isNext())
+	{
+		auto p = it3.get();
+
+		base1 = vd.template getProp<A>(p);
+		base3 = vd.template getProp<C>(p) + base2;
+
+		ret &= base1 == base3;
+
+		++it3;
+	}
+
+	BOOST_REQUIRE_EQUAL(ret,true);
+
+	return ret;
+}
+
+template <typename vector,typename Kernel, typename NN_type> bool check_values_apply_kernel2(vector & vd, Kernel & ker, NN_type & NN)
+{
+	bool ret = true;
+	auto it = vd.getDomainIterator();
+
+	// ### WIKI 13 ###
+	//
+	// Check that apply kernel work
+	//
+	auto it2 = vd.getDomainIterator();
+	while (it2.isNext())
+	{
+		Point<3,float> base2 = 0.0;
+		auto p = it2.get();
+
+		Point<3,float> xp = vd.getPos(p);
+
+		Point<3,float> base1 = vd.template getProp<VA>(p);
+
+		Point<3,float> prp_x = 2.0 * vd.template getProp<VC>(p) + vd.template getProp<VB>(p);
+
+		// For each neighborhood particle
+		auto Np = NN.template getNNIterator<NO_CHECK>(NN.getCell(vd.getPos(p)));
+
+		while (Np.isNext())
+		{
+			// Neighborhood particle q
+			auto q = Np.get();
+
+			if (q == p.getKey())	{++Np; continue;};
+
+			// position q
+			Point<3,float> xq = vd.getPos(q);
+
+			Point<3,float> prp_y = 2.0 * vd.template getProp<VC>(q) + vd.template getProp<VB>(q);
+
+			base2 += ker.value(xp,xq,prp_x,prp_y);
+
+			++Np;
+		}
+
+		base2 += vd.template getProp<VC>(p);
+
+		ret &= base1 == base2;
+
+		++it2;
+	}
+
+	BOOST_REQUIRE_EQUAL(ret,true);
+
+	return ret;
+}
+
+
+template <typename vector,typename Kernel, typename NN_type> bool check_values_apply_kernel2_reduce(vector & vd, Kernel & ker, NN_type & NN)
+{
+	bool ret = true;
+	auto it = vd.getDomainIterator();
+
+	Point<3,float> base1 = 0.0;
+	Point<3,float> base2 = 0.0;
+	Point<3,float> base3 = 0.0;
+
+	auto it2 = vd.getDomainIterator();
+	while (it2.isNext())
+	{
+		auto p = it2.get();
+
+		Point<3,float> xp = vd.getPos(p);
+
+		Point<3,float> ker_accu = 0.0;
+		Point<3,float> prp_x = 2.0f*vd.template getProp<VC>(p) + vd.template getProp<VB>(p);
+
+		// For each neighborhood particle
+		auto Np = NN.template getNNIterator<NO_CHECK>(NN.getCell(vd.getPos(p)));
+
+		while (Np.isNext())
+		{
+			// Neighborhood particle q
+			auto q = Np.get();
+
+			if (q == p.getKey())	{++Np; continue;};
+
+			// position q
+			Point<3,float> xq = vd.getPos(q);
+			Point<3,float> prp_y = 2.0f*vd.template getProp<VC>(q) + vd.template getProp<VB>(q);
+
+			ker_accu += ker.value(xp,xq,prp_x,prp_y);
+
+			++Np;
+		}
+
+		base2 += ker_accu;
+
+		++it2;
+	}
+
+	auto it3 = vd.getDomainIterator();
+	while (it3.isNext())
+	{
+		auto p = it3.get();
+
+		base1 = vd.template getProp<VA>(p);
+		base3 = vd.template getProp<VC>(p) + base2;
+
+		ret &= base1 == base3;
+
+		++it3;
+	}
+
+	BOOST_REQUIRE_EQUAL(ret,true);
+
+	return ret;
+}
+
+BOOST_AUTO_TEST_CASE( vector_dist_operators_apply_kernel_test )
+{
+	if (create_vcluster().getProcessingUnits() > 3)
+		return;
+
+	Box<3,float> box({0.0,0.0,0.0},{1.0,1.0,1.0});
+
+	// Boundary conditions
+	size_t bc[3]={PERIODIC,PERIODIC,PERIODIC};
+
+	// ghost
+	Ghost<3,float> ghost(0.05);
+
+	// vector type
+	typedef vector_dist<3,float,aggregate<float,float,float,VectorS<3,float>,VectorS<3,float>,VectorS<3,float>,float>> vtype;
+
+	vector_dist<3,float,aggregate<float,float,float,VectorS<3,float>,VectorS<3,float>,VectorS<3,float>,float>> vd(512,box,bc,ghost);
+
+	auto vA = getV<A>(vd);
+	auto vB = getV<B>(vd);
+	auto vC = getV<C>(vd);
+
+	auto vVA = getV<VA>(vd);
+	auto vVB = getV<VB>(vd);
+	auto vVC = getV<VC>(vd);
+
+	// fill vd with some value
+	fill_values(vd);
+
+	vd.map();
+	vd.ghost_get<0,1,2,3,4,5,6>();
+
+	// we apply an exponential kernel to calculate something
+
+	auto cl = vd.getCellList(0.05);
+	exp_kernel ker(0.2);
+
+	vA = applyKernel_in(vVC * vVB + norm(vVB),vd,cl,ker) + vC;
+	check_values_apply_kernel(vd,ker,cl);
+
+	vVA = applyKernel_in(2.0*vVC + vVB ,vd,cl,ker) + vVC;
+	check_values_apply_kernel2(vd,ker,cl);
+
+	vA = applyKernel_reduce(vVC * vVB + norm(vVB),vd,cl,ker) + vC;
+	check_values_apply_kernel_reduce(vd,ker,cl);
+
+	vVA = applyKernel_reduce(2.0*vVC + vVB ,vd,cl,ker) + vVC;
+	check_values_apply_kernel2_reduce(vd,ker,cl);
+
+/*	vA = applyKernel_in_gen(vVC * vVB + norm(vVB),vd,cl,ker) + vC;
+	check_values_apply_kernel(vd,ker,cl);
+
+	vVA = applyKernel_in_gen(2.0*vVC + vVB ,vd,cl,ker) + vVC;
+	check_values_apply_kernel2(vd,ker,cl);
+
+	vA = applyKernel_reduce_gen(vVC * vVB + norm(vVB),vd,cl,ker) + vC;
+	check_values_apply_kernel_reduce(vd,ker,cl);
+
+	vVA = applyKernel_reduce_gen(2.0*vVC + vVB ,vd,cl,ker) + vVC;
+	check_values_apply_kernel2_reduce(vd,ker,cl);*/
+}
+
+
+#endif /* OPENFPM_NUMERICS_SRC_OPERATORS_VECTOR_VECTOR_DIST_OPERATORS_APPLY_KERNEL_UNIT_TESTS_HPP_ */
-- 
GitLab