mul.hpp 5.13 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/*
 * mul.hpp
 *
 *  Created on: Oct 22, 2015
 *      Author: i-bird
 */

#ifndef OPENFPM_NUMERICS_SRC_FINITEDIFFERENCE_MUL_HPP_
#define OPENFPM_NUMERICS_SRC_FINITEDIFFERENCE_MUL_HPP_

#include <typeinfo>
#include "util/util_debug.hpp"
#include "util/util_num.hpp"

#define HAS_VAL 1
#define HAS_POS_VAL 2

18
//! Evaluate the constant field function
19 20 21
template <unsigned int, typename T>
struct has_val
{
22
	//! evaluate
23 24 25 26 27 28 29
	static float call_val()
	{
		std::cerr << "Error the type " << demangle(typeid(T).name()) << "interpreted as constant field, does not have a function val() or val_pos(), please see the numeric examples in Finite Differences for more information\n";
		return 0;
	}
};

30
//! Evaluate the constant field function
31 32 33
template <typename T>
struct has_val<HAS_VAL,T>
{
34
	//! evaluate
35 36 37 38 39 40
	static decltype(T::val()) call_val()
	{
		return T::val();
	}
};

41
//! Multiplication expression
42 43 44 45 46 47 48 49 50 51 52 53
template<typename v_expr>
struct const_mul_functor_value
{
	//! Number of elements in the vector v_expr
	typedef boost::mpl::size<v_expr> size;

	//! Last element of sum
	typedef typename boost::mpl::at<v_expr,boost::mpl::int_<size::value-1> >::type last;

	//! sum functor
	std::unordered_map<long int,typename last::stype> & cols;

54
	//! grid size
55 56
	const grid_sm<last::dims,void> & gs;

57
	//! grid mapping
Pietro Incardona's avatar
Pietro Incardona committed
58
	const grid_dist_id<last::dims,typename last::stype,scalar<size_t>,typename last::b_grid::decomposition::extended_type> & g_map;
59

60
	//! grid position
61 62 63 64 65
	grid_dist_key_dx<last::dims> & kmap;

	//! coefficent
	typename last::stype coeff;

66 67 68
	//! spacing
	typename last::stype (& spacing)[last::dims];

69
	/*! \brief constructor
70 71 72 73 74
	 *
	 * \param g_map mapping grid
	 * \param kmap grid point (row) where we evaluate the non-zero colums
	 * \param gs grid size
	 * \param spacing grid spacing
75 76
	 * \param cols non zero colums
	 * \param coeff multiplication coefficent
77 78
	 *
	 */
79 80 81 82 83 84
	const_mul_functor_value(const grid_dist_id<last::dims,typename last::stype,scalar<size_t>,typename last::b_grid::decomposition::extended_type> & g_map,
			                grid_dist_key_dx<last::dims> & kmap,
							const grid_sm<last::dims,void> & gs,
							typename last::stype (& spacing)[last::dims],
							std::unordered_map<long int,typename last::stype> & cols,
							typename last::stype coeff)
85
	:cols(cols),gs(gs),g_map(g_map),kmap(kmap),coeff(coeff),spacing(spacing)
86 87 88 89 90 91 92 93 94 95 96 97 98
	{};



	//! It call this function for every constant expression in the mul
	template<typename T>
	void operator()(T& t)
	{
		typedef typename boost::mpl::at<v_expr, boost::mpl::int_<T::value> >::type cfield;

		coeff *= has_val<is_const_field<cfield>::value * 1,cfield>::call_val();
	}

99 100 101 102 103
	/*! \brief Get the coefficent
	 *
	 * \return the coefficent
	 *
	 */
104 105 106 107 108 109 110 111
	typename last::stype getCoeff()
	{
		return coeff;
	}
};

/*! \brief It model an expression expr1 * expr2
 *
112
 * \warning expr1 MUST be a constant expression only expr2 depend form variable, this requirement ensure linearity in the solving variable of the equations
113 114 115 116 117 118 119 120
 *
 * \tparam expr1
 * \tparam expr2
 *
 */
template<typename ... expr >
struct mul
{
121
	//! Transform from variadic template to boost mpl vector
122 123
	typedef boost::mpl::vector<expr... > v_expr;

124
	//! size of v_expr
125 126
	typedef typename boost::mpl::size<v_expr>::type v_sz;

127
	//! type on which this expression operate
128 129
	typedef typename boost::mpl::at<v_expr, boost::mpl::int_<v_sz::type::value - 1> >::type Sys_eqs;

130
	/*! \brief Calculate which colums of the Matrix are non zero
131
	 *
132 133
	 * \param g_map mapping grid
	 * \param kmap position where the multiplication is calculated
134
	 * \param gs Grid info
135
	 * \param spacing of the grid
136 137
	 * \param cols non-zero colums calculated by the function
	 * \param coeff coefficent (constant in front of the derivative)
138 139
	 *
	 */
140 141 142 143 144 145
	inline static void value(const grid_dist_id<Sys_eqs::dims,typename Sys_eqs::stype,scalar<size_t>,typename Sys_eqs::b_grid::decomposition::extended_type> & g_map,
			                 grid_dist_key_dx<Sys_eqs::dims> & kmap,
							 const grid_sm<Sys_eqs::dims,void> & gs,
							 typename Sys_eqs::stype (& spacing )[Sys_eqs::dims],
							 std::unordered_map<long int,typename Sys_eqs::stype > & cols,
							 typename Sys_eqs::stype coeff)
146
	{
147
		const_mul_functor_value<v_expr> mfv(g_map,kmap,gs,spacing,cols,coeff);
148 149 150 151 152 153 154

		//
		boost::mpl::for_each_ref< boost::mpl::range_c<int,0,v_sz::type::value - 2> >(mfv);

		//! Last element of multiplication
		typedef typename boost::mpl::at< v_expr ,boost::mpl::int_<v_sz::value-2> >::type last_m;

155
		last_m::value(g_map,kmap,gs,spacing,cols,mfv.coeff);
156 157
	}

158
	/*! \brief Calculate the position in the cell where the mul operator is performed
159
	 *
160 161
	 * it just return the position of the staggered property in the last expression
	 *
162
	 * \param pos position where we are calculating the derivative
163 164
	 * \param gs Grid info
	 * \param s_pos staggered position of the properties
165 166
	 *
	 */
167 168 169
	inline static grid_key_dx<Sys_eqs::dims> position(grid_key_dx<Sys_eqs::dims> & pos,
			                                          const grid_sm<Sys_eqs::dims,void> & gs,
													  const comb<Sys_eqs::dims> (& s_pos)[Sys_eqs::nvar])
170
	{
171
		return boost::mpl::at<v_expr, boost::mpl::int_<v_sz::type::value - 2> >::type::position(pos,gs,s_pos);
172 173 174 175 176
	}
};


#endif /* OPENFPM_NUMERICS_SRC_FINITEDIFFERENCE_MUL_HPP_ */