ln_space
functions.h
Go to the documentation of this file.
1 #ifndef HELPER_FUNCTIONS
2 #define HELPER_FUNCTIONS
3 
4 
5 /*
6  *
7  * Authors: Christian Burkhardt and Johannes Friedlein,
8  * FAU Erlangen-Nuremberg, 2019/2020
9  *
10  */
11 
12 
13 #include <deal.II/base/exceptions.h>
14 #include <deal.II/lac/vector.h>
15 
16 #include <gsl/gsl_integration.h>
17 #include <gsl/gsl_sf_gamma.h>
18 
19 #include <cmath>
20 #include <cstdlib>
21 
22 #include <numeric>
23 #include <stdexcept>
24 #include <string>
25 #include <utility>
26 #include <vector>
27 
28 using namespace dealii;
29 using namespace std;
30 
31 
32 template<int dim>
33 Tensor<4,dim> get_tensor_operator_G(const SymmetricTensor<2,dim> &Ma, const SymmetricTensor<2,dim> &Mb)
34 {
35  Tensor<4,dim> tmp; // has minor symmetry of indices k,l
36 
37  for(unsigned int i=0; i<dim; ++i)
38  for(unsigned int j=0; j<dim; ++j)
39  for(unsigned int k=0; k<dim; ++k)
40  for(unsigned int l=k; l<dim; ++l)
41  {
42  double tmp_scalar = Ma[i][k] * Mb[j][l] + Ma[i][l] * Mb[j][k];
43  tmp[i][j][k][l] = tmp_scalar;
44  tmp[i][j][l][k] = tmp_scalar;
45  }
46 
47  return tmp;
48 }
49 
50 
51 // F right F_{a(bc)}
52 template<int dim>
53 Tensor<4,dim> get_tensor_operator_F_right(const SymmetricTensor<2,dim> &Ma,
54  const SymmetricTensor<2,dim> &Mb,
55  const SymmetricTensor<2,dim> &Mc,
56  const SymmetricTensor<2,dim> &T )
57 {
58  Tensor<4,dim> tmp; // has minor symmetry of indices k,l
59 
60  Tensor<2,dim> temp_tensor = contract<1,0>((Tensor<2,dim>)T, (Tensor<2,dim>)Mc);
61  Tensor<2,dim> MbTMc = contract<1,0>((Tensor<2,dim>)Mb,temp_tensor);
62 
63  for(unsigned int i=0; i<dim; ++i)
64  for(unsigned int j=0; j<dim; ++j)
65  for(unsigned int k=0; k<dim; ++k)
66  for(unsigned int l=k; l<dim; ++l)
67  {
68  double tmp_scalar = Ma[i][k] * MbTMc[j][l] + Ma[i][l] * MbTMc[j][k];
69  tmp[i][j][k][l] = tmp_scalar;
70  tmp[i][j][l][k] = tmp_scalar;
71  }
72 
73  return tmp;
74 }
75 
76 
77 // F right F_{(ab)c}
78 template<int dim>
79 Tensor<4,dim> get_tensor_operator_F_left(const SymmetricTensor<2,dim> &Ma,
80  const SymmetricTensor<2,dim> &Mb,
81  const SymmetricTensor<2,dim> &Mc,
82  const SymmetricTensor<2,dim> &T){
83  Tensor<4,dim> tmp;
84 
85  Tensor<2,dim> temp_tensor = contract<1,0>((Tensor<2,dim>)T, (Tensor<2,dim>)Mb);
86  Tensor<2,dim> MaTMb = contract<1,0>((Tensor<2,dim>)Ma,temp_tensor);
87 
88  for(unsigned int i=0; i<dim; ++i)
89  for(unsigned int j=0; j<dim; ++j)
90  for(unsigned int k=0; k<dim; ++k)
91  for(unsigned int l=k; l<dim; ++l)
92  {
93  double tmp_scalar = MaTMb[i][k] * Mc[j][l] + MaTMb[i][l] * Mc[j][k];
94  tmp[i][j][k][l] = tmp_scalar;
95  tmp[i][j][l][k] = tmp_scalar;
96  }
97 
98  return tmp;
99 }
100 
101 
102 
103 // ############################################################################################################
104 // Optimised function to compute outer products of symmetric tensors
105 // ############################################################################################################
106 #ifndef outer_product_sym_H
107 #define outer_product_sym_H
108 
109 template<int dim>
110 SymmetricTensor<4,dim> outer_product_sym( const SymmetricTensor<2,dim> &A, const SymmetricTensor<2,dim> &B )
111 {
112  SymmetricTensor<4,dim> D;
113  // Special nested for-loop to access only non-symmetric entries of 4th order sym. tensor
114  // ToDo: still not optimal element 1112 and 1211 are both accessed
115  for ( unsigned int i=0; i<dim; ++i )
116  for ( unsigned int j=i; j<dim; ++j )
117  for ( unsigned int k=i; k<dim; ++k )
118  for ( unsigned int l=k; l<dim; ++l )
119  {
120  double tmp = A[i][j] * B[k][l] + B[i][j] * A[k][l];
121  D[i][j][k][l] = tmp;
122  D[k][l][i][j] = tmp;
123  }
124  return D;
125 }
126 template<int dim>
127 SymmetricTensor<4,dim> outer_product_sym( const SymmetricTensor<2,dim> &A )
128 {
129  SymmetricTensor<4,dim> D;
130  // Special nested for-loop to access only non-symmetric entries of 4th order sym. tensor
131  // ToDo: still not optimal element 1112 and 1211 are both accessed
132  for ( unsigned int i=0; i<dim; ++i )
133  for ( unsigned int j=i; j<dim; ++j )
134  for ( unsigned int k=i; k<dim; ++k )
135  for ( unsigned int l=k; l<dim; ++l )
136  {
137  double tmp = A[i][j] * A[k][l];
138  D[i][j][k][l] = tmp;
139  D[k][l][i][j] = tmp;
140  }
141  return D;
142 }
143 template<int dim>
144 SymmetricTensor<2,dim> outer_product_sym( const Tensor<1,dim> &A )
145 {
146  SymmetricTensor<2,dim> D;
147  // Special nested for-loop to access only non-symmetric entries of 4th order sym. tensor
148  // ToDo: still not optimal element 1112 and 1211 are both accessed
149  for ( unsigned int i=0; i<dim; ++i )
150  for ( unsigned int j=i; j<dim; ++j )
151  D[i][j] = A[i] * A[j];
152 
153  return D;
154 }
155 
156 #endif //outer_product_sym_H
157 // ############################################################################################################
158 // ############################################################################################################
159 
160 
161 // temp symmetry check [JF]
162 template<int dim>
163 bool symmetry_check ( Tensor<2,dim> &tensor )
164 {
165  for ( unsigned int i=0; i<dim; i++ )
166  for ( unsigned int j=0; j<dim; j++ )
167  if ( i!=j && ( std::abs(tensor[i][j] - tensor[j][i])>1e-12 ) )
168  return false;
169 
170  return true;
171 }
172 template<int dim>
173 bool symmetry_check(const Tensor<4,dim> &temp){
174  for(unsigned int i=0; i<dim; ++i){
175  for(unsigned int j=0; j<dim; ++j){
176  for(unsigned int k=0; k<dim; ++k){
177  for(unsigned int l=0; l<dim; ++l){
178  // absolute difference check
179  if( ( fabs(temp[i][j][k][l] - temp[j][i][k][l]) > 1e-6 )
180  ||
181  ( fabs(temp[i][j][k][l] - temp[i][j][l][k]) > 1e-6 ) )
182  {
183  // relative difference check
184  if( (fabs(fabs(temp[i][j][k][l] - temp[j][i][k][l])/temp[j][i][k][l])> 1e-8)
185  ||
186  (fabs(fabs(temp[i][j][k][l] - temp[i][j][l][k])/temp[i][j][l][k]) >1e-8) )
187  {
188  deallog<< std::endl;
189  deallog<< "Abs not matching: "<<fabs(temp[i][j][k][l] - temp[j][i][k][l])
190  << " | Rel not matching: "<<fabs(temp[i][j][k][l] - temp[j][i][k][l])/temp[j][i][k][l]
191  << " | Abs not matching: "<<fabs(temp[i][j][k][l] - temp[i][j][l][k])
192  << " | Rel not matching: "<<fabs(temp[i][j][k][l] - temp[i][j][l][k])/temp[i][j][l][k]
193  << " | value ijkl: "<< std::scientific << temp[i][j][k][l]
194  << " | value jikl: "<< std::scientific << temp[j][i][k][l]
195  << " | value ijlk: "<< std::scientific << temp[i][j][l][k]
196  << std::endl;
197  return false;
198  }
199  }
200  }
201  }
202  }
203  }
204  return true;
205 }
206 
207 
208 template<int dim>
209 SymmetricTensor<4,dim> symmetrize(const Tensor<4,dim> &tensor){
210  SymmetricTensor<4,dim> sym_tensor;
211  Assert(symmetry_check(tensor), ExcMessage("Tensor to symmetrize is not symmetric!"));
212 
213  Tensor<4,dim> temp_tensor;
214  for(unsigned int i=0; i<dim; ++i)
215  for(unsigned int j=0; j<dim; ++j)
216  for(unsigned int k=0; k<dim; ++k)
217  for(unsigned int l=0; l<dim; ++l)
218  temp_tensor[i][j][k][l] = (tensor[i][j][k][l]+tensor[j][i][k][l]+tensor[i][j][l][k]) / 3.0;
219 
220  for(unsigned int i=0; i<dim; ++i)
221  for(unsigned int j=i; j<dim; ++j)
222  for(unsigned int k=0; k<dim; ++k)
223  for(unsigned int l=k; l<dim; ++l)
224  sym_tensor[i][j][k][l] = temp_tensor[i][j][k][l];
225 // sym_tensor[i][j][k][l] = tensor[i][j][k][l];
226 
227  return sym_tensor;
228 }
229 
230 #endif
bool symmetry_check(Tensor< 2, dim > &tensor)
Definition: functions.h:163
Tensor< 4, dim > get_tensor_operator_F_right(const SymmetricTensor< 2, dim > &Ma, const SymmetricTensor< 2, dim > &Mb, const SymmetricTensor< 2, dim > &Mc, const SymmetricTensor< 2, dim > &T)
Definition: functions.h:53
SymmetricTensor< 4, dim > outer_product_sym(const SymmetricTensor< 2, dim > &A, const SymmetricTensor< 2, dim > &B)
Definition: functions.h:110
Tensor< 4, dim > get_tensor_operator_G(const SymmetricTensor< 2, dim > &Ma, const SymmetricTensor< 2, dim > &Mb)
Definition: functions.h:33
Tensor< 4, dim > get_tensor_operator_F_left(const SymmetricTensor< 2, dim > &Ma, const SymmetricTensor< 2, dim > &Mb, const SymmetricTensor< 2, dim > &Mc, const SymmetricTensor< 2, dim > &T)
Definition: functions.h:79
SymmetricTensor< 4, dim > symmetrize(const Tensor< 4, dim > &tensor)
Definition: functions.h:209