We can use constexpr functions instead of recursive templates.
*
* Use this class as in <code>fixed_int_power@<5,2@>::%value</code> to
* compute 5<sup>2</sup>.
+ *
+ * @deprecated This template has been deprecated in favor of C++11's support
+ * for <code>constexpr</code> calculations, e.g., use
+ *
+ * @code
+ * constexpr int value = Utilities::pow(2, dim);
+ * @endcode
+ *
+ * instead of
+ *
+ * @code
+ * const int value = Utilities::fixed_int_power<2, dim>::value;
+ * @endcode
+ *
+ * to obtain a constant expression for <code>value</code>.
*/
template <int a, int N>
- struct fixed_int_power
+ struct DEAL_II_DEPRECATED fixed_int_power
{
static const int value = a *fixed_int_power<a,N-1>::value;
};
/**
* Base case for the power operation with <code>N=0</code>, which gives the
* result 1.
+ *
+ * @deprecated This template is deprecated: see the note in the general
+ * version of this template for more information.
*/
template <int a>
- struct fixed_int_power<a,0>
+ struct DEAL_II_DEPRECATED fixed_int_power<a,0>
{
static const int value = 1;
};
+ /**
+ * A replacement for <code>std::pow</code> that allows compile-time
+ * calculations for constant expression arguments.
+ */
+ constexpr
+ unsigned int
+ pow(const unsigned int base, const unsigned int iexp)
+ {
+ return iexp == 0 ? 1 : base*dealii::Utilities::pow(base, iexp - 1);
+ }
+
/**
* Optimized replacement for <tt>std::lower_bound</tt> for searching within
* the range of column indices. Slashes execution time by approximately one
typedef typename MatrixFree<dim, Number>::Data data_type;
static const unsigned int dimension = dim;
static const unsigned int n_components = n_components_;
- static const unsigned int n_q_points =
- Utilities::fixed_int_power<n_q_points_1d,dim>::value;
- static const unsigned int tensor_dofs_per_cell =
- Utilities::fixed_int_power<fe_degree+1,dim>::value;
+ static constexpr unsigned int n_q_points = Utilities::pow(n_q_points_1d, dim);
+ static constexpr unsigned int tensor_dofs_per_cell = Utilities::pow(fe_degree + 1, dim);
/**
* Constructor.
struct EvaluatorTensorProduct<evaluate_general, dim, fe_degree,
n_q_points_1d, Number>
{
- static const unsigned int dofs_per_cell =
- Utilities::fixed_int_power<fe_degree+1,dim>::value;
- static const unsigned int n_q_points =
- Utilities::fixed_int_power<n_q_points_1d,dim>::value;
+ static constexpr unsigned int dofs_per_cell = Utilities::pow(fe_degree + 1, dim);
+ static constexpr unsigned int n_q_points = Utilities::pow(n_q_points_1d, dim);
__device__ EvaluatorTensorProduct();
for (unsigned int q=basis_size_1; q!=0; --q)
FEEvaluationImplBasisChange<variant,next_dim,basis_size_1,basis_size_2,n_components,Number,Number2>
::do_forward(transformation_matrix,
- values_in + (q-1)*Utilities::fixed_int_power<basis_size_1,dim-1>::value,
- my_scratch + (q-1)*Utilities::fixed_int_power<basis_size_2,dim-1>::value);
+ values_in + (q-1)*Utilities::pow(basis_size_1, dim-1),
+ my_scratch + (q-1)*Utilities::pow(basis_size_2, dim-1));
EvaluatorTensorProduct<variant, dim, basis_size_1, basis_size_2,
Number,Number2> eval_val (transformation_matrix);
const unsigned int n_inner_blocks = (dim > 1 && basis_size_2 < 10) ? basis_size_2 : 1;
- const unsigned int n_blocks = Utilities::fixed_int_power<basis_size_2,dim-1>::value;
+ const unsigned int n_blocks = Utilities::pow(basis_size_2, dim-1);
for (unsigned int ii=0; ii<n_blocks; ii+=n_inner_blocks)
for (unsigned int c=0; c<n_components; ++c)
{
for (unsigned int q=0; q<basis_size_1; ++q)
FEEvaluationImplBasisChange<variant,next_dim,basis_size_1,basis_size_2,n_components,Number,Number2>
::do_backward(transformation_matrix, false,
- my_scratch + q*Utilities::fixed_int_power<basis_size_2,dim-1>::value,
- values_out + q*Utilities::fixed_int_power<basis_size_1,dim-1>::value);
+ my_scratch + q*Utilities::pow(basis_size_2, dim-1),
+ values_out + q*Utilities::pow(basis_size_1, dim-1));
}
};
eval(AlignedVector<Number>(),
shape_info.shape_gradients_collocation_eo,
shape_info.shape_hessians_collocation_eo);
- constexpr unsigned int n_q_points = Utilities::fixed_int_power<fe_degree+1,dim>::value;
+ constexpr unsigned int n_q_points = Utilities::pow(fe_degree+1, dim);
for (unsigned int c=0; c<n_components; c++)
{
eval(AlignedVector<Number>(),
shape_info.shape_gradients_collocation_eo,
shape_info.shape_hessians_collocation_eo);
- constexpr unsigned int n_q_points = Utilities::fixed_int_power<fe_degree+1,dim>::value;
+ constexpr unsigned int n_q_points = Utilities::pow(fe_degree+1, dim);
for (unsigned int c=0; c<n_components; c++)
{
"of lower degree, so the evaluation results would be "
"wrong. Thus, this class does not permit the desired "
"operation."));
- constexpr unsigned int n_q_points = Utilities::fixed_int_power<n_q_points_1d,dim>::value;
+ constexpr unsigned int n_q_points = Utilities::pow(n_q_points_1d, dim);
for (unsigned int c=0; c<n_components; c++)
{
"operation."));
AssertDimension(shape_info.shape_gradients_collocation_eo.size(),
(n_q_points_1d+1)/2*n_q_points_1d);
- constexpr unsigned int n_q_points = Utilities::fixed_int_power<n_q_points_1d,dim>::value;
+ constexpr unsigned int n_q_points = Utilities::pow(n_q_points_1d, dim);
for (unsigned int c=0; c<n_components; c++)
{
data.fe_degree+1, data.n_q_points_1d);
const unsigned int size_deg = fe_degree > -1 ?
- Utilities::fixed_int_power<fe_degree+1,dim-1>::value :
+ Utilities::pow(fe_degree+1, dim-1) :
(dim > 1 ? Utilities::fixed_power<dim-1>(data.fe_degree+1) : 1);
const unsigned int n_q_points = fe_degree > -1 ?
- Utilities::fixed_int_power<n_q_points_1d,dim-1>::value : data.n_q_points_face;
+ Utilities::pow(n_q_points_1d, dim-1) : data.n_q_points_face;
if (evaluate_grad == false)
for (unsigned int c=0; c<n_components; ++c)
Eval eval2(val2,grad2,val1,data.fe_degree+1, data.n_q_points_1d);
const unsigned int size_deg = fe_degree > -1 ?
- Utilities::fixed_int_power<fe_degree+1,dim-1>::value :
+ Utilities::pow(fe_degree+1, dim-1) :
(dim > 1 ? Utilities::fixed_power<dim-1>(data.fe_degree+1) : 1);
const unsigned int n_q_points = fe_degree > -1 ?
typedef typename BaseClass::gradient_type gradient_type;
static constexpr unsigned int dimension = dim;
static constexpr unsigned int n_components = n_components_;
- static constexpr unsigned int static_n_q_points = Utilities::fixed_int_power<n_q_points_1d,dim>::value;
- static constexpr unsigned int static_dofs_per_component = Utilities::fixed_int_power<fe_degree+1,dim>::value;
+ static constexpr unsigned int static_n_q_points = Utilities::pow(n_q_points_1d, dim);
+ static constexpr unsigned int static_dofs_per_component = Utilities::pow(fe_degree + 1, dim);
static constexpr unsigned int tensor_dofs_per_cell = static_dofs_per_component *n_components;
static constexpr unsigned int static_dofs_per_cell = static_dofs_per_component *n_components;
CellwiseInverseMassMatrix<dim,fe_degree,n_components,Number>
::fill_inverse_JxW_values(AlignedVector<VectorizedArray<Number> > &inverse_jxw) const
{
- const unsigned int dofs_per_cell = Utilities::fixed_int_power<fe_degree+1,dim>::value;
+ constexpr unsigned int dofs_per_cell = Utilities::pow(fe_degree + 1, dim);
Assert(inverse_jxw.size() > 0 &&
inverse_jxw.size() % dofs_per_cell == 0,
ExcMessage("Expected diagonal to be a multiple of scalar dof per cells"));
const VectorizedArray<Number> *in_array,
VectorizedArray<Number> *out_array) const
{
- const unsigned int dofs_per_cell = Utilities::fixed_int_power<fe_degree+1,dim>::value;
+ constexpr unsigned int dofs_per_cell = Utilities::pow(fe_degree + 1, dim);
Assert(inverse_coefficients.size() > 0 &&
inverse_coefficients.size() % dofs_per_cell == 0,
ExcMessage("Expected diagonal to be a multiple of scalar dof per cells"));
template <int dim, int n_rows, int n_columns, typename Number, typename Number2>
struct EvaluatorTensorProduct<evaluate_general,dim,n_rows,n_columns,Number,Number2>
{
- static const unsigned int n_rows_of_product = Utilities::fixed_int_power<n_rows,dim>::value;
- static const unsigned int n_columns_of_product = Utilities::fixed_int_power<n_columns,dim>::value;
+ static constexpr unsigned int n_rows_of_product = Utilities::pow(n_rows, dim);
+ static constexpr unsigned int n_columns_of_product = Utilities::pow(n_columns, dim);
/**
* Empty constructor. Does nothing. Be careful when using 'values' and
constexpr int mm = contract_over_rows ? n_rows : n_columns,
nn = contract_over_rows ? n_columns : n_rows;
- constexpr int stride = Utilities::fixed_int_power<n_columns,direction>::value;
+ constexpr int stride = Utilities::pow(n_columns, direction);
constexpr int n_blocks1 = one_line ? 1 : stride;
- constexpr int n_blocks2 = Utilities::fixed_int_power<n_rows,(direction>=dim)?0:(dim-direction-1)>::value;
+ constexpr int n_blocks2 = Utilities::pow(n_rows, (direction>=dim) ? 0 : (dim-direction-1));
for (int i2=0; i2<n_blocks2; ++i2)
{
constexpr int n_blocks2 = dim > 2 ? n_rows : 1;
AssertIndexRange (face_direction, dim);
- constexpr int stride = Utilities::fixed_int_power<n_rows,face_direction>::value;
- constexpr int out_stride = Utilities::fixed_int_power<n_rows,dim-1>::value;
+ constexpr int stride = Utilities::pow(n_rows, face_direction);
+ constexpr int out_stride = Utilities::pow(n_rows, dim-1);
const Number *DEAL_II_RESTRICT shape_values = this->shape_values;
for (int i2=0; i2<n_blocks2; ++i2)
template <int dim, int n_rows, int n_columns, typename Number, typename Number2>
struct EvaluatorTensorProduct<evaluate_symmetric,dim,n_rows,n_columns,Number,Number2>
{
- static const unsigned int n_rows_of_product = Utilities::fixed_int_power<n_rows,dim>::value;
- static const unsigned int n_columns_of_product = Utilities::fixed_int_power<n_columns,dim>::value;
+ static constexpr unsigned int n_rows_of_product = Utilities::pow(n_rows, dim);
+ static constexpr unsigned int n_columns_of_product = Utilities::pow(n_columns, dim);
/**
* Constructor, taking the data from ShapeInfo
constexpr int n_cols = nn / 2;
constexpr int mid = mm / 2;
- constexpr int stride = Utilities::fixed_int_power<n_columns,direction>::value;
+ constexpr int stride = Utilities::pow(n_columns, direction);
constexpr int n_blocks1 = stride;
- constexpr int n_blocks2 = Utilities::fixed_int_power<n_rows,(direction>=dim)?0:(dim-direction-1)>::value;
+ constexpr int n_blocks2 = Utilities::pow(n_rows, (direction>=dim) ? 0 : (dim-direction-1));
for (int i2=0; i2<n_blocks2; ++i2)
{
constexpr int n_cols = nn / 2;
constexpr int mid = mm / 2;
- constexpr int stride = Utilities::fixed_int_power<n_columns,direction>::value;
+ constexpr int stride = Utilities::pow(n_columns, direction);
constexpr int n_blocks1 = stride;
- constexpr int n_blocks2 = Utilities::fixed_int_power<n_rows,(direction>=dim)?0:(dim-direction-1)>::value;
+ constexpr int n_blocks2 = Utilities::pow(n_rows, (direction>=dim) ? 0 : (dim-direction-1));
for (int i2=0; i2<n_blocks2; ++i2)
{
constexpr int n_cols = nn / 2;
constexpr int mid = mm / 2;
- constexpr int stride = Utilities::fixed_int_power<n_columns,direction>::value;
+ constexpr int stride = Utilities::pow(n_columns, direction);
constexpr int n_blocks1 = stride;
- constexpr int n_blocks2 = Utilities::fixed_int_power<n_rows,(direction>=dim)?0:(dim-direction-1)>::value;
+ constexpr int n_blocks2 = Utilities::pow(n_rows, (direction>=dim) ? 0 : (dim-direction-1));
for (int i2=0; i2<n_blocks2; ++i2)
{
template <int dim, int n_rows, int n_columns, typename Number, typename Number2>
struct EvaluatorTensorProduct<evaluate_evenodd,dim,n_rows,n_columns,Number,Number2>
{
- static const unsigned int n_rows_of_product = Utilities::fixed_int_power<n_rows,dim>::value;
- static const unsigned int n_columns_of_product = Utilities::fixed_int_power<n_columns,dim>::value;
+ static constexpr unsigned int n_rows_of_product = Utilities::pow(n_rows, dim);
+ static constexpr unsigned int n_columns_of_product = Utilities::pow(n_columns, dim);
/**
* Empty constructor. Does nothing. Be careful when using 'values' and
constexpr int n_cols = nn / 2;
constexpr int mid = mm / 2;
- constexpr int stride = Utilities::fixed_int_power<n_columns,direction>::value;
+ constexpr int stride = Utilities::pow(n_columns, direction);
constexpr int n_blocks1 = one_line ? 1 : stride;
- constexpr int n_blocks2 = Utilities::fixed_int_power<n_rows,(direction>=dim)?0:(dim-direction-1)>::value;
+ constexpr int n_blocks2 = Utilities::pow(n_rows, (direction>=dim) ? 0 : (dim-direction-1));
constexpr int offset = (n_columns+1)/2;
template <int dim, int n_rows, int n_columns, typename Number, typename Number2>
struct EvaluatorTensorProduct<evaluate_symmetric_hierarchical,dim,n_rows,n_columns,Number,Number2>
{
- static const unsigned int n_rows_of_product = Utilities::fixed_int_power<n_rows,dim>::value;
- static const unsigned int n_columns_of_product = Utilities::fixed_int_power<n_columns,dim>::value;
+ static constexpr unsigned int n_rows_of_product = Utilities::pow(n_rows, dim);
+ static constexpr unsigned int n_columns_of_product = Utilities::pow(n_columns, dim);
/**
* Empty constructor. Does nothing. Be careful when using 'values' and
constexpr int n_cols = nn / 2;
constexpr int mid = mm / 2;
- constexpr int stride = Utilities::fixed_int_power<n_columns,direction>::value;
+ constexpr int stride = Utilities::pow(n_columns, direction);
constexpr int n_blocks1 = one_line ? 1 : stride;
- constexpr int n_blocks2 = Utilities::fixed_int_power<n_rows,(direction>=dim)?0:(dim-direction-1)>::value;
+ constexpr int n_blocks2 = Utilities::pow(n_rows, (direction>=dim) ? 0 : (dim-direction-1));
// this code may look very inefficient at first sight due to the many
// different cases with if's at the innermost loop part, but all of the