From 1334d42e15ec8e27afc441ef50b93246cf90c1c5 Mon Sep 17 00:00:00 2001 From: Matthias Maier Date: Tue, 1 Sep 2015 19:43:12 -0500 Subject: [PATCH] Tensor<1, dim>: Finish interface cleanup --- include/deal.II/base/point.h | 2 +- include/deal.II/base/tensor.h | 89 --------- include/deal.II/base/tensor_base.h | 292 ++++++++++++++++------------- 3 files changed, 161 insertions(+), 222 deletions(-) diff --git a/include/deal.II/base/point.h b/include/deal.II/base/point.h index 51bb6e441c..0231a998a3 100644 --- a/include/deal.II/base/point.h +++ b/include/deal.II/base/point.h @@ -408,7 +408,7 @@ Number Point::operator * (const Tensor<1,dim,Number> &p) const { // simply pass down - return Tensor<1,dim,Number>::operator * (p); + return static_cast >(*this) * p; } diff --git a/include/deal.II/base/tensor.h b/include/deal.II/base/tensor.h index 2aa0744d7f..10cc8b9bbc 100644 --- a/include/deal.II/base/tensor.h +++ b/include/deal.II/base/tensor.h @@ -127,7 +127,6 @@ public: * Number. */ template - explicit Tensor (const Tensor &initializer); /** @@ -212,18 +211,6 @@ public: */ Tensor &operator /= (const Number factor); - /** - * Add two tensors. If possible, you should use operator += instead - * since this does not need the creation of a temporary. - */ - Tensor operator + (const Tensor &) const; - - /** - * Subtract two tensors. If possible, you should use operator -= - * instead since this does not need the creation of a temporary. - */ - Tensor operator - (const Tensor &) const; - /** * Unary minus operator. Negate all entries of a tensor. */ @@ -554,36 +541,6 @@ Tensor::operator /= (const Number s) -template -inline -Tensor -Tensor::operator + (const Tensor &t) const -{ - Tensor tmp(*this); - - for (unsigned int i=0; i -inline -Tensor -Tensor::operator - (const Tensor &t) const -{ - Tensor tmp(*this); - - for (unsigned int i=0; i inline Tensor @@ -756,52 +713,6 @@ std::ostream &operator << (std::ostream &out, const Tensor &p) #endif // DOXYGEN -/** - * Contract a tensor of rank 1 with a tensor of rank 1. The result is - * sum_j src1[j] src2[j]. - * - * @relates Tensor - * @author Guido Kanschat, 2000 - */ -template -inline -typename ProductType::type -contract (const Tensor<1,dim,Number> &src1, - const Tensor<1,dim,OtherNumber> &src2) -{ - typename ProductType::type res = typename ProductType::type(); - for (unsigned int i=0; icontract function, - * but returns the result as a return value, rather than writing it into the - * reference given as the first argument to the contract function. - * - * Note that for the Tensor class, the multiplication operator only - * performs a contraction over a single pair of indices. This is in contrast - * to the multiplication operator for symmetric tensors, which does the double - * contraction. - * - * @relates Tensor - * @author Wolfgang Bangerth, 2005 - */ -template -inline -typename ProductType::type -operator * (const Tensor<1,dim,Number> &src1, - const Tensor<1,dim,OtherNumber> &src2) -{ - return contract(src1, src2); -} - - /** * Double contract two tensors of rank 2, thus computing the Frobenius inner * product sumi,j src1[i][j]*src2[i][j]. diff --git a/include/deal.II/base/tensor_base.h b/include/deal.II/base/tensor_base.h index 29a551be5f..5778ac93f0 100644 --- a/include/deal.II/base/tensor_base.h +++ b/include/deal.II/base/tensor_base.h @@ -323,7 +323,7 @@ public: /** * Publish the rank of this tensor to the outside world. */ - static const unsigned int rank = 1; + static const unsigned int rank = 1; /** * Number of independent components of a tensor of rank 1. @@ -350,11 +350,11 @@ public: /** * Declare an array type which can be used to initialize statically an * object of this type. - * - * Avoid warning about zero-sized array for dim==0 by choosing - * lunatic value that is likely to overflow memory limits. */ - typedef Number array_type[(dim!=0) ? dim : 100000000]; + // Avoid a bogus warning in case of dim==0, and always provide a type + // with positive array size. The constructor will take care that no + // Tensor with dim==0 will be constructed. + typedef Number array_type[(dim!=0) ? dim : 1]; /** * Constructor. Initialize all entries to zero if initialize==true; @@ -379,7 +379,6 @@ public: * Number. */ template - explicit Tensor (const Tensor<1,dim,OtherNumber> &initializer); /** @@ -388,7 +387,7 @@ public: * Note that the derived Point class also provides access through * the () operator for backcompatibility. */ - Number operator [] (const unsigned int index) const; + Number operator [] (const unsigned int index) const; /** * Read and write access to the indexth coordinate. @@ -401,15 +400,15 @@ public: /** * Read access using TableIndices indices */ - Number operator [](const TableIndices<1> &indices) const; + Number operator [] (const TableIndices<1> &indices) const; /** * Read and write access using TableIndices indices */ - Number &operator [](const TableIndices<1> &indices); + Number &operator [] (const TableIndices<1> &indices); /** - * Assignment operator. + * Copy assignment operator. */ Tensor<1,dim,Number> &operator = (const Tensor<1,dim,Number> &rhs); @@ -427,60 +426,50 @@ public: * value allowed for d, allowing the intuitive notation * t=0 to reset all elements of the tensor to zero. */ - Tensor<1,dim,Number> &operator = (const Number d); + template + Tensor<1,dim,Number> &operator = (const OtherNumber d); /** * Test for equality of two tensors. */ - bool operator == (const Tensor<1,dim,Number> &rhs) const; + template + bool operator == (const Tensor<1,dim,OtherNumber> &rhs) const; /** * Test for inequality of two tensors. */ - bool operator != (const Tensor<1,dim,Number> &rhs) const; + template + bool operator != (const Tensor<1,dim,OtherNumber> &rhs) const; /** - * Add another vector, i.e. move this point by the given offset. + * Add another vector to this vector. */ - Tensor<1,dim,Number> &operator += (const Tensor<1,dim,Number> &rhs); + template + Tensor<1,dim,Number> &operator += (const Tensor<1,dim,OtherNumber> &rhs); /** * Subtract another vector. */ - Tensor<1,dim,Number> &operator -= (const Tensor<1,dim,Number> &rhs); + template + Tensor<1,dim,Number> &operator -= (const Tensor<1,dim,OtherNumber> &rhs); /** - * Scale the vector by factor, i.e. multiply all coordinates by + * Scale the vector by factor, i.e., multiply all coordinates by * factor. */ - Tensor<1,dim,Number> &operator *= (const Number factor); + template + Tensor<1,dim,Number> &operator *= (const OtherNumber factor); /** * Scale the vector by 1/factor. */ - Tensor<1,dim,Number> &operator /= (const Number factor); - - /** - * Returns the scalar product of two vectors. - */ - Number operator * (const Tensor<1,dim,Number> &) const; - - /** - * Add two tensors. If possible, use operator += instead since this - * does not need to copy a point at least once. - */ - Tensor<1,dim,Number> operator + (const Tensor<1,dim,Number> &) const; - - /** - * Subtract two tensors. If possible, use operator += instead since - * this does not need to copy a point at least once. - */ - Tensor<1,dim,Number> operator - (const Tensor<1,dim,Number> &) const; + template + Tensor<1,dim,Number> &operator /= (const OtherNumber factor); /** * Tensor with inverted entries. */ - Tensor<1,dim,Number> operator - () const; + Tensor<1,dim,Number> operator - () const; /** * Return the Frobenius-norm of a tensor, i.e. the square root of the sum of @@ -574,7 +563,7 @@ private: * element, because otherwise the compiler would choke. We catch this case * in the constructor to disallow the creation of such an object. */ - Number values[(dim!=0) ? (dim) : (dim+1)]; + array_type values; /** * Help function for unroll. If we have detected an access control bug in @@ -586,7 +575,6 @@ private: void unroll_recursion (Vector &result, unsigned int &start_index) const; -private: /** * Make the following classes friends to this class. In principle, it would * suffice if otherrank==2, but that is not possible in C++ at present. @@ -912,6 +900,8 @@ operator / (const Tensor<0,dim,Number> &t, /** * Add two tensors of rank 0. + * + * @relates Tensor */ template inline @@ -925,6 +915,8 @@ operator+ (const Tensor<0,dim,Number> &p, const Tensor<0,dim,OtherNumber> &q) /** * Subtract two tensors of rank 0. + * + * @relates Tensor */ template inline @@ -960,10 +952,8 @@ inline Tensor<1,dim,Number>::Tensor (const bool initialize) { if (initialize) - // need to create an object Number() to - // initialize to zero to avoid confusion with - // Tensor::operator=(scalar) when using - // something like + // need to create an object Number() to initialize to zero to avoid + // confusion with Tensor::operator=(scalar) when using something like // Tensor<1,dim,Tensor<1,dim,Number> >. for (unsigned int i=0; i!=dim; ++i) values[i] = Number(); @@ -1008,20 +998,15 @@ Tensor<1,dim,Number>::Tensor (const Tensor<1,dim,OtherNumber> &p) +// At some places in the library, we have Point<0> for formal reasons +// (e.g., we sometimes have Quadrature for faces, so we have +// Quadrature<0> for dim=1, and then we have Point<0>). To avoid warnings +// in the above function that the loop end check always fails, we +// implement this function here template <> inline Tensor<1,0,double>::Tensor (const Tensor<1,0,double> &) { - // at some places in the library, - // we have Point<0> for formal - // reasons (e.g., we sometimes have - // Quadrature for faces, so - // we have Quadrature<0> for dim=1, - // and then we have Point<0>). To - // avoid warnings in the above - // function that the loop end check - // always fails, we implement this - // function here } @@ -1044,6 +1029,8 @@ Number &Tensor<1,dim,Number>::operator [] (const unsigned int index) return values[index]; } + + template inline Number Tensor<1,dim,Number>::operator [] (const TableIndices<1> &indices) const @@ -1052,6 +1039,8 @@ Number Tensor<1,dim,Number>::operator [] (const TableIndices<1> &indices) const return values[indices[0]]; } + + template inline Number &Tensor<1,dim,Number>::operator [] (const TableIndices<1> &indices) @@ -1062,33 +1051,28 @@ Number &Tensor<1,dim,Number>::operator [] (const TableIndices<1> &indices) -template <> +template inline -Tensor<1,0,double> &Tensor<1,0,double>::operator = (const Tensor<1,0,double> &) +Tensor<1,dim,Number> & +Tensor<1,dim,Number>::operator = (const Tensor<1,dim,Number> &p) { - // at some places in the library, - // we have Point<0> for formal - // reasons (e.g., we sometimes have - // Quadrature for faces, so - // we have Quadrature<0> for dim=1, - // and then we have Point<0>). To - // avoid warnings in the above - // function that the loop end check - // always fails, we implement this - // function here + for (unsigned int i=0; i +template <> inline -Tensor<1,dim,Number> & -Tensor<1,dim,Number>::operator = (const Tensor<1,dim,Number> &p) +Tensor<1,0,double> &Tensor<1,0,double>::operator = (const Tensor<1,0,double> &) { - for (unsigned int i=0; i for formal reasons + // (e.g., we sometimes have Quadrature for faces, so we have + // Quadrature<0> for dim=1, and then we have Point<0>). To avoid warnings + // in the above function that the loop end check always fails, we + // implement this function here return *this; } @@ -1109,14 +1093,15 @@ Tensor<1,dim,Number>::operator = (const Tensor<1,dim,OtherNumber> &p) template +template inline -Tensor<1,dim,Number> &Tensor<1,dim,Number>::operator = (const Number d) +Tensor<1,dim,Number> &Tensor<1,dim,Number>::operator = (const OtherNumber d) { - Assert (d==Number(0), ExcMessage ("Only assignment with zero is allowed")); + Assert (d == OtherNumber(), ExcMessage ("Only assignment with zero is allowed")); (void) d; for (unsigned int i=0; i &Tensor<1,dim,Number>::operator = (const Number d) template +template inline -bool Tensor<1,dim,Number>::operator == (const Tensor<1,dim,Number> &p) const +bool Tensor<1,dim,Number>::operator == (const Tensor<1,dim,OtherNumber> &p) const { for (unsigned int i=0; i::operator == (const Tensor<1,dim,Number> &p) const +template <> template <> inline bool Tensor<1,0,double>::operator == (const Tensor<1,0,double> &) const @@ -1145,8 +1132,9 @@ bool Tensor<1,0,double>::operator == (const Tensor<1,0,double> &) const template +template inline -bool Tensor<1,dim,Number>::operator != (const Tensor<1,dim,Number> &p) const +bool Tensor<1,dim,Number>::operator != (const Tensor<1,dim,OtherNumber> &p) const { return !((*this) == p); } @@ -1154,8 +1142,9 @@ bool Tensor<1,dim,Number>::operator != (const Tensor<1,dim,Number> &p) const template +template inline -Tensor<1,dim,Number> &Tensor<1,dim,Number>::operator += (const Tensor<1,dim,Number> &p) +Tensor<1,dim,Number> &Tensor<1,dim,Number>::operator += (const Tensor<1,dim,OtherNumber> &p) { for (unsigned int i=0; i &Tensor<1,dim,Number>::operator += (const Tensor<1,dim,Numb template +template inline -Tensor<1,dim,Number> &Tensor<1,dim,Number>::operator -= (const Tensor<1,dim,Number> &p) +Tensor<1,dim,Number> &Tensor<1,dim,Number>::operator -= (const Tensor<1,dim,OtherNumber> &p) { for (unsigned int i=0; i &Tensor<1,dim,Number>::operator -= (const Tensor<1,dim,Numb template +template inline -Tensor<1,dim,Number> &Tensor<1,dim,Number>::operator *= (const Number s) +Tensor<1,dim,Number> &Tensor<1,dim,Number>::operator *= (const OtherNumber s) { for (unsigned int i=0; i &Tensor<1,dim,Number>::operator *= (const Number s) template +template inline -Tensor<1,dim,Number> &Tensor<1,dim,Number>::operator /= (const Number s) +Tensor<1,dim,Number> &Tensor<1,dim,Number>::operator /= (const OtherNumber s) { for (unsigned int i=0; i &Tensor<1,dim,Number>::operator /= (const Number s) -template -inline -Number -Tensor<1,dim,Number>::operator * (const Tensor<1,dim,Number> &p) const -{ - // unroll by hand since this is a - // frequently called function and - // some compilers don't want to - // always unroll the loop in the - // general template - switch (dim) - { - case 1: - return (values[0] * p.values[0]); - break; - case 2: - return (values[0] * p.values[0] + - values[1] * p.values[1]); - break; - case 3: - return (values[0] * p.values[0] + - values[1] * p.values[1] + - values[2] * p.values[2]); - break; - default: - Number q = values[0] * p.values[0]; - for (unsigned int i=1; i -inline -Tensor<1,dim,Number> Tensor<1,dim,Number>::operator + (const Tensor<1,dim,Number> &p) const -{ - return (Tensor<1,dim,Number>(*this) += p); -} - - - -template -inline -Tensor<1,dim,Number> Tensor<1,dim,Number>::operator - (const Tensor<1,dim,Number> &p) const -{ - return (Tensor<1,dim,Number>(*this) -= p); -} - - - template inline Tensor<1,dim,Number> Tensor<1,dim,Number>::operator - () const @@ -1505,6 +1445,94 @@ operator / (const Tensor &t, +/** + * Addition of two tensors of general @tparam rank. + * + * @relates Tensor + */ +template +inline +Tensor::type> +operator+ (const Tensor &p, const Tensor &q) +{ + Tensor::type> tmp (p); + + for (unsigned int i=0; i +inline +Tensor::type> +operator- (const Tensor &p, const Tensor &q) +{ + Tensor::type> tmp (p); + + for (unsigned int i=0; isum_j src1[j] src2[j]. + * + * @relates Tensor + * @author Guido Kanschat, 2000 + */ +template +inline +typename ProductType::type +contract (const Tensor<1,dim,Number> &src1, + const Tensor<1,dim,OtherNumber> &src2) +{ + typename ProductType::type res + = typename ProductType::type(); + for (unsigned int i=0; icontract function, + * but returns the result as a return value, rather than writing it into the + * reference given as the first argument to the contract function. + * + * Note that for the Tensor class, the multiplication operator only + * performs a contraction over a single pair of indices. This is in contrast + * to the multiplication operator for symmetric tensors, which does the double + * contraction. + * + * @relates Tensor + * @author Wolfgang Bangerth, 2005 + */ +template +inline +typename ProductType::type +operator * (const Tensor<1,dim,Number> &src1, + const Tensor<1,dim,OtherNumber> &src2) +{ + return contract(src1, src2); +} + + + DEAL_II_NAMESPACE_CLOSE #endif -- 2.39.5