KADATH
tensor_calculus.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 "tensor.hpp"
21 #include "scalar.hpp"
22 #include "tensor_impl.hpp"
23 namespace Kadath {
25  if (!name_affected) {
26  cerr << "Names of indices must be affected in Tensor::do_summation" << endl ;
27  abort() ;
28  }
29 
30  Array<int> sum_ind (valence) ;
31  Array<int> nsame (valence) ;
32  sum_ind = -1 ;
33  nsame = 0 ;
34  for (int i=0 ; i<valence ; i++)
35  for (int j=i+1 ; j<valence ; j++) {
36  if (name_indice[i]==name_indice[j]) {
37  nsame.set(i) ++ ;
38  nsame.set(j) ++ ;
39  if ((nsame(i)>1) || (nsame(j)>1)) {
40  cerr << "Too many identical indices in Tensor::do_summation" << endl ;
41  abort() ;
42  }
43  sum_ind.set(i) = j ;
44  sum_ind.set(j) = i ;
45  if (type_indice(i)==type_indice(j)) {
46  cerr << "Can not sum on indices of the same type in Tensor::do_summation" << endl ;
47  abort() ;
48  }
49  }
50  }
51 
52  int valence_res = 0 ;
53  for (int i=0 ; i<valence ; i++)
54  if (nsame(i)==0)
55  valence_res ++ ;
56 
57  // difference Scalar or not :
58  if (valence_res > 0) {
59  Array<int> type_ind_res (valence_res) ;
60  char* name_ind_res = new char[valence_res] ;
61  int conte = 0 ;
62  for (int i=0 ; i<valence ; i++)
63  if (nsame(i)==0) {
64  type_ind_res.set(conte) = type_indice(i) ;
65  name_ind_res[conte] = name_indice[i] ;
66  conte ++ ;
67  }
68 
69  Tensor res (espace, valence_res, type_ind_res, basis) ;
70  res.name_affected = true ;
71  for (int i=0 ; i<valence_res ; i++)
72  res.name_indice[i] = name_ind_res[i] ;
73  delete name_ind_res ;
74 
75  res = 0 ;
76  Array<bool> first (res.get_n_comp()) ;
77  first = true ;
78 
79  // Loop on the various components :
80  Index pos (*this) ;
81  Index pos_res (res) ;
82  do {
83  bool take = true ;
84  for (int i=0 ; i<valence ; i++)
85  if (pos(sum_ind(i))!=pos(i))
86  take = false ;
87 
88  if (take) {
89  conte = 0 ;
90  for (int i=0 ; i<valence ; i++)
91  if (nsame(i)==0) {
92  pos_res.set(conte)=pos(i) ;
93  conte ++ ;
94  }
95  int ind (res.position(pos_res)) ;
96  if (first(ind)) {
97  for (int dd=0 ; dd<espace.get_nbr_domains() ; dd++)
98  res.set(pos_res).set_domain(dd).set_base() = (*this)(pos)(dd).get_base() ;
99  first.set(ind) = false ;
100  }
101  res.set(pos_res) += (*this)(pos) ;
102  }
103  }
104  while (pos.inc()) ;
105  return res ;
106  }
107  else {
108  // Scalar case :
109  Scalar res(espace) ;
110  res = 0 ;
111  bool first = true ;
112  Index pos (*this) ;
113  do {
114  bool take = true ;
115  for (int i=0 ; i<valence ; i++)
116  if (pos(sum_ind(i))!=pos(i))
117  take = false ;
118 
119  if (take) {
120  if (first) {
121  for (int dd=0 ; dd<espace.get_nbr_domains() ; dd++)
122  res.set_domain(dd).set_base() = (*this)(pos)(dd).get_base() ;
123  first = false ;
124  }
125  res += (*this)(pos) ;
126  }
127  }
128  while (pos.inc()) ;
129  return res ;
130  }
131 }
132 
134 
135  // Verif triad (only implemented for cartesian coordinates so far)
136  for (int d=0 ; d<ndom ; d++)
137  assert (basis.get_basis(d)==CARTESIAN_BASIS) ;
138 
139  Array<int> indices_res (valence+1) ;
140  indices_res.set(0) = COV ;
141  for (int i=0 ; i<valence ; i++)
142  indices_res.set(i+1) = type_indice(i) ;
143  Tensor res (espace, valence+1, indices_res, basis) ;
144 
145  for (int i=0 ; i<ndim ; i++) {
146  indices_res.set(0) = i+1 ;
147  for (int j=0 ; j<n_comp ; j++) {
148  Array<int> cible(indices(j)) ;
149  for (int k=0 ; k<valence ; k++)
150  indices_res.set(k+1) = cible(k) ;
151  res.set(indices_res) = operator()(cible).der_abs(i+1) ;
152  }
153  }
154  return res ;
155 }}
reference set(const Index &pos)
Read/write of an element.
Definition: array.hpp:186
void set(Dim_array const &nbr_coefs, int basephi, int basetheta, int baser)
Allocates the various arrays, for a given number of coefficients and sets basis to some values (same ...
int get_basis(int nd) const
Read only the basis in a given domain.
Definition: base_tensor.hpp:93
Class that gives the position inside a multi-dimensional Array.
Definition: index.hpp:38
int & set(int i)
Read/write of the position in a given dimension.
Definition: index.hpp:72
bool inc(int increm, int var=0)
Increments the position of the Index.
Definition: index.hpp:99
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
Scalar der_abs(int) const
Returns the derivative with respect to one particular absolute Cartesian coordinate.
Definition: scalar.cpp:149
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
const Scalar & operator()() const
Read only for a Scalar.
bool name_affected
Indicator that states if the indices have been given names.
Definition: tensor.hpp:172
Memory_mapped_array< char > name_indice
If the indices haves names they are stored here.
Definition: tensor.hpp:176
Base_tensor basis
Tensorial basis with respect to which the tensor components are defined.
Definition: tensor.hpp:163
Tensor do_summation() const
Does the inner contraction of the Tensor.
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
Tensor grad() const
Computes the flat gradient, in Cartesian coordinates.
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
Scalar & set(const Array< int > &ind)
Returns the value of a component (read/write version).
Definition: tensor_impl.hpp:91
int get_n_comp() const
Returns the number of stored components.
Definition: tensor.hpp:514
virtual Array< int > indices(int pos) const
Gives the values of the indices corresponding to a location in the array used for storage of the comp...
Definition: tensor.hpp:484
int n_comp
Number of stored components, depending on the symmetry.
Definition: tensor.hpp:178
const Space & espace
The Space.
Definition: tensor.hpp:154
virtual int position(const Array< int > &idx) const
Gives the location of a given component in the array used for storage (Array version).
Definition: tensor.hpp:470
Base_spectral & set_base()
Sets the basis of decomposition.
Definition: val_domain.hpp:126