From: Wolfgang Bangerth Date: Tue, 29 Mar 2005 21:27:18 +0000 (+0000) Subject: Finish accessors for fourth order tensors. Add a cautionary note to X-Git-Tag: v8.0.0~14245 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=69978435eb753a79a318c77a927cd46750bbdbe6;p=dealii.git Finish accessors for fourth order tensors. Add a cautionary note to the docs. git-svn-id: https://svn.dealii.org/trunk@10302 0785d39b-7218-0410-832d-ea1e28bc413d --- diff --git a/deal.II/base/include/base/symmetric_tensor.h b/deal.II/base/include/base/symmetric_tensor.h index 2335c94815..7726877858 100644 --- a/deal.II/base/include/base/symmetric_tensor.h +++ b/deal.II/base/include/base/symmetric_tensor.h @@ -52,6 +52,46 @@ namespace internal else return TableIndices<2>(previous_indices[0], new_index); } + + + + /** + * Create a TableIndices<4> + * object where the first entries + * up to position-1 are + * taken from previous_indices, + * and new_index is put at + * position + * position. The + * remaining indices remain in + * invalid state. + */ + TableIndices<4> merge (const TableIndices<4> &previous_indices, + const unsigned int new_index, + const unsigned int position) + { + Assert (position < 4, ExcIndexRange (position, 0, 4)); + + switch (position) + { + case 0: + return TableIndices<4>(new_index); + case 1: + return TableIndices<4>(previous_indices[0], + new_index); + case 2: + return TableIndices<4>(previous_indices[0], + previous_indices[1], + new_index); + case 3: + return TableIndices<4>(previous_indices[0], + previous_indices[1], + previous_indices[2], + new_index); + } + Assert (false, ExcInternalError()); + return TableIndices<4>(); + } /** @@ -209,7 +249,7 @@ namespace internal * * @author Wolfgang Bangerth, 2002, 2005 */ - template + template class Accessor { public: @@ -468,6 +508,25 @@ namespace internal * SymmetricTensor<1,dim> and SymmetricTensor<3,dim> do not * exist and their use will most likely lead to compiler errors. * + * + *

Accessing elements

+ * + * The elements of a tensor t can be accessed using the + * bracket operator, i.e. for a tensor of rank 4, + * t[0][1][0][1] accesses the element + * t0101. This access can be used for both reading + * and writing (if the tensor is non-constant at least). You may also + * perform other operations on it, although that may lead to confusing + * situations because several elements of the tensor are stored at the + * same location. For example, for a rank-2 tensor that is assumed to + * be zero at the beginning, writing t[0][1]+=1; t[1][0]+=1; + * will lead to the same element being increased by one + * twice, because even though the accesses use different + * indices, the elements that are accessed are symmetric and therefore + * stored at the same location. It may therefore be useful in + * application programs to restrict operations on individual elements + * to simple reads or writes. + * * @author Wolfgang Bangerth, 2005 */ template @@ -659,7 +718,7 @@ class SymmetricTensor /** * Data storage for a symmetric tensor. */ - typename internal::SymmetricTensorAccessors::StorageType<2,dim>::base_tensor_type data; + typename internal::SymmetricTensorAccessors::StorageType::base_tensor_type data; }; @@ -670,24 +729,24 @@ namespace internal { namespace SymmetricTensorAccessors { -// template -// Accessor:: -// Accessor (const tensor_type &tensor, -// const TableIndices &previous_indices) -// : -// tensor (tensor), -// previous_indices (previous_indices) -// {} + template + Accessor:: + Accessor (tensor_type &tensor, + const TableIndices &previous_indices) + : + tensor (tensor), + previous_indices (previous_indices) + {} -// template -// Accessor -// Accessor::operator[] (const unsigned int i) -// { -// return Accessor (tensor, -// merge (previous_indices, i, rank-P)); -// } + template + Accessor + Accessor::operator[] (const unsigned int i) + { + return Accessor (tensor, + merge (previous_indices, i, rank-P)); + } @@ -918,6 +977,59 @@ SymmetricTensor<2,3>::operator * (const SymmetricTensor<2,3> &s) const +template <> +double +SymmetricTensor<4,1>::operator * (const SymmetricTensor<4,1> &s) const +{ + return data[0][0] * s.data[0][0]; +} + + + +template <> +double +SymmetricTensor<4,2>::operator * (const SymmetricTensor<4,2> &s) const +{ + const unsigned int dim = 2; + + // this is not really efficient and + // could be improved by counting + // how often each tensor entry is + // accessed, but this isn't a + // really frequent operation anyway + double t = 0; + for (unsigned int i=0; i +double +SymmetricTensor<4,3>::operator * (const SymmetricTensor<4,3> &s) const +{ + const unsigned int dim = 3; + + // this is not really efficient and + // could be improved by counting + // how often each tensor entry is + // accessed, but this isn't a + // really frequent operation anyway + double t = 0; + for (unsigned int i=0; i double & SymmetricTensor<2,1>::operator () (const TableIndices<2> &indices) @@ -1070,6 +1182,238 @@ SymmetricTensor<2,3>::operator () (const TableIndices<2> &indices) const +template <> +double & +SymmetricTensor<4,1>::operator () (const TableIndices<4> &indices) +{ + const unsigned int rank = 4; + const unsigned int dim = 1; + for (unsigned int r=0; r +double +SymmetricTensor<4,1>::operator () (const TableIndices<4> &indices) const +{ + const unsigned int rank = 4; + const unsigned int dim = 1; + for (unsigned int r=0; r +double & +SymmetricTensor<4,2>::operator () (const TableIndices<4> &indices) +{ + const unsigned int rank = 4; + const unsigned int dim = 2; + for (unsigned int r=0; r +double +SymmetricTensor<4,2>::operator () (const TableIndices<4> &indices) const +{ + const unsigned int rank = 4; + const unsigned int dim = 2; + for (unsigned int r=0; r +double & +SymmetricTensor<4,3>::operator () (const TableIndices<4> &indices) +{ + const unsigned int rank = 4; + const unsigned int dim = 3; + for (unsigned int r=0; r +double +SymmetricTensor<4,3>::operator () (const TableIndices<4> &indices) const +{ + const unsigned int rank = 4; + const unsigned int dim = 3; + for (unsigned int r=0; r internal::SymmetricTensorAccessors::Accessor SymmetricTensor::operator [] (const unsigned int row) const @@ -1096,7 +1440,7 @@ template <> double SymmetricTensor<2,1>::norm () const { - return std::sqrt(data[0]*data[0]); + return std::fabs(data[0]); } @@ -1119,6 +1463,65 @@ SymmetricTensor<2,3>::norm () const } + +template <> +double +SymmetricTensor<4,1>::norm () const +{ + return std::fabs(data[0][0]); +} + + + +template <> +double +SymmetricTensor<4,2>::norm () const +{ + const unsigned int dim = 2; + + // this is not really efficient and + // could be improved by counting + // how often each tensor entry is + // accessed, but this isn't a + // really frequent operation anyway + double t = 0; + for (unsigned int i=0; i +double +SymmetricTensor<4,3>::norm () const +{ + const unsigned int dim = 3; + + // this is not really efficient and + // could be improved by counting + // how often each tensor entry is + // accessed, but this isn't a + // really frequent operation anyway + double t = 0; + for (unsigned int i=0; i