KADATH
ope_inverse_nodet.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 "ope_eq.hpp"
21 #include "scalar.hpp"
22 #include "tensor_impl.hpp"
23 namespace Kadath {
24 Ope_inverse_nodet::Ope_inverse_nodet (const System_of_eqs* zesys, Ope_eq* target) : Ope_eq(zesys, target->get_dom(), 1) {
25  parts[0] = target ;
26 }
27 
29 }
30 
32 
33  Term_eq target (parts[0]->action()) ;
34 
35  // Various checks
36  if (target.type_data != TERM_T) {
37  cerr << "Ope_inverse only defined with respect for a tensor" << endl ;
38  abort() ;
39  }
40  if (target.val_t->get_valence()!=2) {
41  cerr << "Ope_inverse only defined with respect to a second order tensor" << endl ;
42  abort() ;
43  }
44  if (target.val_t->get_index_type(0)!=target.val_t->get_index_type(1)) {
45  cerr << "Ope_inverse only defined with respect to a tensor which indices are of the same type" << endl ;
46  abort() ;
47  }
48  int typeresult = - target.val_t->get_index_type(0) ;
49  int dim = target.val_t->get_space().get_ndim() ;
50 
51  bool m_doder = (target.der_t==0x0) ? false : true ;
52 
53  Term_eq** res(new Term_eq* [dim*(dim + 1)/2]); // 6 components to compute...
54  Scalar val(target.val_t->get_space()); // val and cmpval are more or less the same intermediate, but with different types
55  Scalar der(target.val_t->get_space());
56  Val_domain cmpval(target.val_t->get_space().get_domain(dom));
57  Val_domain cmpder(target.val_t->get_space().get_domain(dom));
58 
59 
60 
61  // compute the transposed comatrix
62  double signature;
63  gsl_permutation* p(gsl_permutation_calloc(dim-1)); // initialise to identity 0, 1
64  for (int i(1) ; i <= dim ; ++i) // sum over components, only the upper triangular part
65  {
66  for (int j(i) ; j <= dim ; ++j)
67  {
68  cmpval = 0.0; // initialise to 0 before each computation
69  cmpder = 0.0; // initialise to 0 before each computation
70  do
71  {
72  signature = sign(p);
73  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
74  int p2(static_cast<int>(gsl_permutation_get(p, 1)) + 1);
75  vector<int> index1, index2; // manage the indices of the transposed comatrix
76  index1 = ind_com(i, j, p1, 1); // we need to play a bit with indices to get transpose(COM(metric))
77  index2 = ind_com(i, j, p2, 2);
78  cmpval += pow(-1.0, i + j)*signature*(*target.val_t)(index1[0], index1[1])(dom)*(*target.val_t)(index2[0],index2[1])(dom); // sum on permutations
79  if (m_doder)
80  cmpder += pow(-1.0, i + j)*signature*(*target.der_t)(index1[0], index1[1])(dom)*(*target.val_t)(index2[0], index2[1])(dom)
81  + pow(-1.0, i + j)*signature*(*target.val_t)(index1[0], index1[1])(dom)*(*target.der_t)(index2[0], index2[1])(dom);
82  }while(gsl_permutation_next(p) == GSL_SUCCESS);
83  gsl_permutation_free(p) ;
84  p = gsl_permutation_calloc(dim - 1); // reinitialise to identity 0, 1, ready to be used for next component
85  val.set_domain(dom) = cmpval ; // now we have the component of the inverse matrix
86  if (m_doder)
87  {
88  der.set_domain(dom) = cmpder ;
89  res[j - 1 + dim*(i - 1) - i*(i - 1)/2] = new Term_eq (dom, val, der); // just save upper triangular components in a 1D array of Term_eq (the indice will run throug 0, 1, 2, 3, 4, 5 with i, j)
90  }
91  else
92  res[j - 1 + dim*(i - 1) - i*(i - 1)/2] = new Term_eq (dom, val);
93  }
94  }
95  gsl_permutation_free(p);
96 
97  // Value field :
98  Metric_tensor resval(target.val_t->get_space() , typeresult, target.val_t->get_basis());
99  Metric_tensor resder(target.val_t->get_space() , typeresult, target.val_t->get_basis());
100  for (int i(1) ; i <= dim ; ++i)
101  for (int j(i) ; j <= dim ; ++j)
102  resval.set(i, j) = res[j - 1 + dim*(i - 1) - i*(i - 1)/2]->get_val_t();
103 
104  // Der field
105  if (m_doder) {
106  for (int i(1) ; i <= dim ; ++i)
107  for (int j(i) ; j <= dim ; ++j)
108  resder.set(i, j) = res[j - 1 + dim*(i - 1) - i*(i - 1)/2]->get_der_t();
109  }
110 
111  for (int i(0) ; i < dim*(dim + 1)/2 ; ++i)
112  delete res[i];
113  delete[] res;
114 
115  if (!m_doder)
116  return Term_eq (dom, resval) ;
117  else
118  return Term_eq (dom, resval, resder) ;
119 }
120 }
Particular type of Tensor, dedicated to the desription of metrics.
Abstract class that describes the various operators that can appear in the equations.
Definition: ope_eq.hpp:32
MMPtr_array< Ope_eq > parts
Pointers of the various parts of the current operator.
Definition: ope_eq.hpp:38
int dom
Index of the Domain where the operator is defined.
Definition: ope_eq.hpp:36
Term_eq action() const override
Computes the action of the current Ope_eq using its various parts.
Ope_inverse_nodet(const System_of_eqs *syst, Ope_eq *so)
Constructor.
~Ope_inverse_nodet() override
Destructor.
The class Scalar does not really implements scalars in the mathematical sense but rather tensorial co...
Definition: scalar.hpp:67
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
Class used to describe and solve a system of equations.
Scalar & set(const Array< int > &ind)
Returns the value of a component (read/write version).
Definition: tensor_impl.hpp:91
int get_index_type(int i) const
Gives the type (covariant or contravariant) of a given index.
Definition: tensor.hpp:526
const Base_tensor & get_basis() const
Returns the vectorial basis (triad) on which the components are defined.
Definition: tensor.hpp:504
int get_valence() const
Returns the valence.
Definition: tensor.hpp:509
const Space & get_space() const
Returns the Space.
Definition: tensor.hpp:499
This class is intended to describe the manage objects appearing in the equations.
Definition: term_eq.hpp:62
Tensor * der_t
Pointer on the variation, if the Term_eq is a Tensor.
Definition: term_eq.hpp:69
const int type_data
Flag describing the type of data :
Definition: term_eq.hpp:75
Tensor const & get_val_t() const
Definition: term_eq.hpp:355
Tensor const & get_der_t() const
Definition: term_eq.hpp:369
Tensor * val_t
Pointer on the value, if the Term_eq is a Tensor.
Definition: term_eq.hpp:68
Class for storing the basis of decompositions of a field and its values on both the configuration and...
Definition: val_domain.hpp:69