Reference documentation for deal.II version 8.5.1
symmetric_tensor.cc
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2005 - 2016 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE at
12 // the top level of the deal.II distribution.
13 //
14 // ---------------------------------------------------------------------
15 
16 #include <deal.II/base/symmetric_tensor.h>
17 
18 DEAL_II_NAMESPACE_OPEN
19 
20 
21 template <>
23 invert<3,double> (const SymmetricTensor<4,3,double> &t)
24 {
26 
27  // this function follows the exact same
28  // scheme as the 2d case, except that
29  // hardcoding the inverse of a 6x6 matrix
30  // is pretty wasteful. instead, we use the
31  // Gauss-Jordan algorithm implemented for
32  // FullMatrix; the following code is copied
33  // from there because using the FullMatrix
34  // class would introduce circular
35  // references between libbase and liblac
36  const unsigned int N = 6;
37 
38  // first get an estimate of the
39  // size of the elements of this
40  // matrix, for later checks whether
41  // the pivot element is large
42  // enough, or whether we have to
43  // fear that the matrix is not
44  // regular
45  double diagonal_sum = 0;
46  for (unsigned int i=0; i<N; ++i)
47  diagonal_sum += std::fabs(tmp.data[i][i]);
48  const double typical_diagonal_element = diagonal_sum/N;
49  (void)typical_diagonal_element;
50 
51  unsigned int p[N];
52  for (unsigned int i=0; i<N; ++i)
53  p[i] = i;
54 
55  for (unsigned int j=0; j<N; ++j)
56  {
57  // pivot search: search that
58  // part of the line on and
59  // right of the diagonal for
60  // the largest element
61  double max = std::fabs(tmp.data[j][j]);
62  unsigned int r = j;
63  for (unsigned int i=j+1; i<N; ++i)
64  if (std::fabs(tmp.data[i][j]) > max)
65  {
66  max = std::fabs(tmp.data[i][j]);
67  r = i;
68  }
69  // check whether the pivot is
70  // too small
71  Assert(max > 1.e-16*typical_diagonal_element,
72  ExcMessage("This tensor seems to be noninvertible"));
73 
74  // row interchange
75  if (r>j)
76  {
77  for (unsigned int k=0; k<N; ++k)
78  std::swap (tmp.data[j][k], tmp.data[r][k]);
79 
80  std::swap (p[j], p[r]);
81  }
82 
83  // transformation
84  const double hr = 1./tmp.data[j][j];
85  tmp.data[j][j] = hr;
86  for (unsigned int k=0; k<N; ++k)
87  {
88  if (k==j) continue;
89  for (unsigned int i=0; i<N; ++i)
90  {
91  if (i==j) continue;
92  tmp.data[i][k] -= tmp.data[i][j]*tmp.data[j][k]*hr;
93  }
94  }
95  for (unsigned int i=0; i<N; ++i)
96  {
97  tmp.data[i][j] *= hr;
98  tmp.data[j][i] *= -hr;
99  }
100  tmp.data[j][j] = hr;
101  }
102  // column interchange
103  double hv[N];
104  for (unsigned int i=0; i<N; ++i)
105  {
106  for (unsigned int k=0; k<N; ++k)
107  hv[p[k]] = tmp.data[i][k];
108  for (unsigned int k=0; k<N; ++k)
109  tmp.data[i][k] = hv[k];
110  }
111 
112  // scale rows and columns. the mult matrix
113  // here is diag[1, 1, 1, 1/2, 1/2, 1/2]
114  for (unsigned int i=3; i<6; ++i)
115  for (unsigned int j=0; j<3; ++j)
116  tmp.data[i][j] /= 2;
117 
118  for (unsigned int i=0; i<3; ++i)
119  for (unsigned int j=3; j<6; ++j)
120  tmp.data[i][j] /= 2;
121 
122  for (unsigned int i=3; i<6; ++i)
123  for (unsigned int j=3; j<6; ++j)
124  tmp.data[i][j] /= 4;
125 
126  return tmp;
127 }
128 
129 
130 
131 // provide definitions for static members
132 template <int rank, int dim, typename Number>
134 
135 template <int rank, int dim, typename Number>
137 
138 
139 #include "symmetric_tensor.inst"
140 
141 
142 DEAL_II_NAMESPACE_CLOSE
base_tensor_type data
static ::ExceptionBase & ExcMessage(std::string arg1)
#define Assert(cond, exc)
Definition: exceptions.h:313
VectorizedArray< Number > max(const ::VectorizedArray< Number > &x, const ::VectorizedArray< Number > &y)