KADATH
metric_tensor.cpp
1 /*
2  Copyright 2017 Philippe Grandclement
3 
4  This file is part of Kadath.
5 
6  Kadath is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  Kadath is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with Kadath. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #include "scalar.hpp"
21 #include "tensor_impl.hpp"
22 #include "metric_tensor.hpp"
23 namespace Kadath {
24 double sign(gsl_permutation* p) // compute permutation signature
25 {
26  int card(static_cast<int>(gsl_permutation_size(p)));
27  double signature(1.0);
28  for (int i(0 ); i < card - 1 ; ++i)
29  for (int j(i+1) ; j < card ; ++j)
30  {
31  double pj(static_cast<double>(gsl_permutation_get(p, j))); // convert to int just because I don't like compiler warnings...
32  double pi(static_cast<double>(gsl_permutation_get(p, i)));
33  signature *= (pj - pi) / (j - i); // compute signature
34  }
35  return signature;
36 }
37 
38 vector<int> ind_com(int i, int j, int k, int l) // introduce matrix indices into the transposed comatrix components
39 {
40  vector<int> res(2);
41  if (k < j and l < i)
42  {
43  res[0] = k;
44  res[1] = l;
45  }
46  if (k >= j and l < i)
47  {
48  res[0] = k + 1;
49  res[1] = l;
50  }
51  if (k < j and l >= i)
52  {
53  res[0] = k;
54  res[1] = l + 1;
55  }
56  if (k >= j and l >= i)
57  {
58  res[0] = k + 1;
59  res[1] = l + 1;
60  }
61  return res;
62 }
63 // Storage functions :
64 int metric_tensor_position_array (const Array<int>& idx, int ndim) {
65 
66  assert (idx.get_ndim() == 1) ;
67  assert (idx.get_size(0) == 2) ;
68 
69  for (int i=0 ; i<2 ; i++)
70  assert ((idx(i)>=1) && (idx(i)<=ndim)) ;
71 
72  int res = 0 ;
73  bool found = false ;
74 
75  if (idx(1)>idx(0)) {
76  for (int i=0 ; i<ndim ; i++)
77  for (int j=i ; j<ndim ; j++) {
78  if ((i+1==idx(0)) && (j+1==idx(1)))
79  found = true ;
80  if (!found)
81  res ++ ;
82  }
83  }
84  else {
85  for (int i=0 ; i<ndim ; i++)
86  for (int j=i ; j<ndim ; j++) {
87  if ((i+1==idx(1)) && (j+1==idx(0)))
88  found = true ;
89  if (!found)
90  res ++ ;
91  }
92  }
93  return res;
94 }
95 
96 int metric_tensor_position_index (const Index& idx, int ndim) {
97  assert (idx.get_ndim() == 2) ;
98  for (int i=0 ; i<2 ; i++)
99  assert ((idx(i)>=0) && (idx(i)<ndim)) ;
100 
101  int res = 0 ;
102  bool found = false ;
103 
104  if (idx(1)>idx(0)) {
105  for (int i=0 ; i<ndim ; i++)
106  for (int j=i ; j<ndim ; j++) {
107  if ((i==idx(0)) && (j==idx(1)))
108  found = true ;
109  if (!found)
110  res ++ ;
111  }
112  }
113  else {
114  for (int i=0 ; i<ndim ; i++)
115  for (int j=i ; j<ndim ; j++) {
116  if ((i==idx(1)) && (j==idx(0)))
117  found = true ;
118  if (!found)
119  res ++ ;
120  }
121  }
122  return res ;
123 }
124 
125 Array<int> metric_tensor_indices (int pos, int valence, int ndim) {
126 
127  assert (valence==2) ;
128  Array<int> res (valence) ;
129  int current = 0 ;
130  for (int i=1 ; i<=ndim ; i++)
131  for (int j=i ; j<=ndim ; j++) {
132  if (current==pos) {
133  res.set(0) = i ;
134  res.set(1) = j ;
135  }
136  current ++ ;
137  }
138  return res ;
139 }
140 
142  // Members
144 
145 
146 
148  assert (&espace==&so.espace) ;
149  basis = so.basis ;
150  assert(so.get_type()==get_type()) ;
151 
152  for (int i=0 ; i<n_comp ; i++)
153  *cmp[i] = *so.cmp[i] ;
154  return *this;
155 }
156 
157 
159  assert (so.valence==2) ;
160  assert (&espace==&so.espace) ;
161  basis = so.basis ;
162  assert (so.type_indice(0)==get_type()) ;
163  assert (so.type_indice(1)==get_type()) ;
164 
165  for (int i=1 ; i<=ndim ; i++)
166  for (int j=i ; j<=ndim ; j++)
167  set(i,j) = (so(i,j) + so(j,i))/2. ; // On symetrise in case non sym
168  return *this;
169 }
170 
172  for (int i=0 ; i<n_comp ; i++)
173  *cmp[i] = xx ;
174  return *this;
175 }
176 
178 {
179  int dim(espace.get_ndim());
180  assert(dim == 3);
181  Metric_tensor res(*this);
182  res.set_index_type(0) = -this->get_index_type(0);
183  res.set_index_type(1) = -this->get_index_type(1);
184  for (int d(0) ; d < espace.get_nbr_domains() ; ++d) // sum over components, only the upper triangular part
185  {
186  Val_domain detval(espace.get_domain(d)); // let's compute the determinant...
187  detval = 0.0;
188  gsl_permutation* p(gsl_permutation_calloc(dim)); // initialise to identity 0, 1, 2
189  do
190  {
191  int p1(static_cast<int>(gsl_permutation_get(p, 0)) + 1); // for tensor indices, you need to add one to get a permutation of 1, 2, 3
192  int p2(static_cast<int>(gsl_permutation_get(p, 1)) + 1);
193  int p3(static_cast<int>(gsl_permutation_get(p, 2)) + 1);
194  detval += sign(p)*res(p1, 1)(d)*res(p2, 2)(d)*res(p3, 3)(d); // sum on permutations
195  }while(gsl_permutation_next(p) == GSL_SUCCESS);
196  gsl_permutation_free(p);
197 
198  // compute the transposed comatrix
199  Val_domain cmpval(espace.get_domain(d));
200  for (int i(1) ; i <= dim ; ++i) // sum over components, only the upper triangular part
201  {
202  for (int j(i) ; j <= dim ; ++j)
203  {
204  cmpval = 0.0; // initialise to 0 before each computation
205  p = gsl_permutation_calloc(dim - 1); // reinitialise to identity 0, 1, ready to be used for next component
206  do
207  {
208  int p1(static_cast<int>(gsl_permutation_get(p, 0)) + 1); // always add one for tensor indices, now we have a permutation of 1, 2
209  int p2(static_cast<int>(gsl_permutation_get(p, 1)) + 1);
210  vector<int> index1, index2; // manage the indices of the transposed comatrix
211  index1 = ind_com(i, j, p1, 1); // we need to play a bit with indices to get transpose(COM(metric))
212  index2 = ind_com(i, j, p2, 2);
213  cmpval += pow(-1.0, i + j)*sign(p)*(*this)(index1[0], index1[1])(d)*(*this)(index2[0],index2[1])(d); // sum on permutations
214  }while(gsl_permutation_next(p) == GSL_SUCCESS);
215  gsl_permutation_free(p);
216  res.set(i,j).set_domain(d) = cmpval / detval; // now we have the component of the inverse matrix
217  }
218  }
219  }
220  return res;
221 }
222 
224 {
225  for (int d(0) ; d < ndom ; ++d)
226  {
227  cmp[0]->std_base_domain(d); // xx ou rr
228  cmp[3]->std_base_domain(d); // yy ou tt
229  cmp[5]->std_base_domain(d); // zz ou pp
230  if (basis.get_basis(d) == CARTESIAN_BASIS)
231  {
232  cmp[1]->std_base_xy_cart_domain(d);
233  cmp[2]->std_base_xz_cart_domain(d);
234  cmp[4]->std_base_yz_cart_domain(d);
235  }
236  if (basis.get_basis(d) == SPHERICAL_BASIS)
237  {
238  cmp[1]->std_base_rt_spher_domain(d);
239  cmp[2]->std_base_rp_spher_domain(d);
240  cmp[4]->std_base_tp_spher_domain(d);
241  }
242  }
243 }
244 }
int get_basis(int nd) const
Read only the basis in a given domain.
Definition: base_tensor.hpp:93
Particular type of Tensor, dedicated to the desription of metrics.
Metric_tensor & operator=(const Metric_tensor &)
Assignment to another Metric_tensor.
void std_base2()
Specialized base setting (for AADS)
Metric_tensor inverse()
Computes the inverse of the current objetc.
Val_domain & set_domain(int)
Read/write of a particular Val_domain.
Definition: scalar.hpp:555
const Domain * get_domain(int i) const
returns a pointer on the domain.
Definition: space.hpp:1385
int get_ndim() const
Returns the number of dimensions.
Definition: space.hpp:1373
int get_nbr_domains() const
Returns the number of Domains.
Definition: space.hpp:1375
Tensor handling.
Definition: tensor.hpp:149
int ndim
The dimension/.
Definition: tensor.hpp:156
Base_tensor basis
Tensorial basis with respect to which the tensor components are defined.
Definition: tensor.hpp:163
int ndom
The number of Domain.
Definition: tensor.hpp:155
int valence
Valence of the tensor (0 = scalar, 1 = vector, etc...)
Definition: tensor.hpp:157
Array< int > type_indice
1D array of integers of size valence containing the type of each index: COV for a covariant one and C...
Definition: tensor.hpp:170
Memory_mapped_array< Scalar * > cmp
Array of size n_comp of pointers onto the components.
Definition: tensor.hpp:179
Array< int > get_index_type() const
Definition: tensor.hpp:531
Scalar & set(const Array< int > &ind)
Returns the value of a component (read/write version).
Definition: tensor_impl.hpp:91
int & set_index_type(int i)
Sets the type of the index number.
Definition: tensor.hpp:538
Scalar & set()
Read/write for a Scalar.
Definition: tensor.hpp:364
int n_comp
Number of stored components, depending on the symmetry.
Definition: tensor.hpp:178
const Space & espace
The Space.
Definition: tensor.hpp:154
Class for storing the basis of decompositions of a field and its values on both the configuration and...
Definition: val_domain.hpp:69