KADATH
domain_shell_inner_adapted_for_metric.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 "headcpp.hpp"
21 #include "utilities.hpp"
22 #include "adapted.hpp"
23 #include "point.hpp"
24 #include "array_math.hpp"
25 #include "term_eq.hpp"
26 #include "metric.hpp"
27 #include "scalar.hpp"
28 #include "tensor_impl.hpp"
29 
30 namespace Kadath {
31 Term_eq Domain_shell_inner_adapted::derive_flat_spher (int type_der, char ind_der, const Term_eq& so, const Metric* manipulator) const {
32 
33  assert ((type_der==COV) || (type_der==CON)) ;
34  int val_res = so.val_t->get_valence() + 1 ;
35 
36  bool donames = (ind_der==' ') ? false : true ;
37  bool need_sum = false ;
38 
39  Array<int> type_ind (val_res) ;
40  type_ind.set(0) = COV ;
41  for (int i=1 ; i<val_res ; i++)
42  type_ind.set(i) = so.val_t->get_index_type(i-1) ;
43 
44  if (donames) {
45  if (so.val_t->get_valence()>0)
46  assert (so.val_t->is_name_affected()) ;
47  // Need for summation ?
48  for (int i=1 ; i<val_res ; i++)
49  if (ind_der== so.val_t->get_name_ind()[i-1])
50  need_sum = true ;
51  }
52 
53 
54  // Flat grad space
55  Term_eq fgrad (flat_grad_spher(so)) ;
56  bool doder = (fgrad.der_t==0x0) ? false : true ;
57 
58  // Connexions parts
59  Base_tensor basis (so.val_t->get_space(), SPHERICAL_BASIS) ;
60  Tensor auxi_val (so.val_t->get_space(), val_res, type_ind, basis) ;
61  auxi_val = 0 ;
62 
63  if (donames) {
64  // Set the names of the indices :
65  auxi_val.set_name_affected() ;
66  auxi_val.set_name_ind(0, ind_der) ;
67  fgrad.val_t->set_name_affected() ;
68  fgrad.val_t->set_name_ind(0, ind_der) ;
69  for (int i=1 ; i<val_res ; i++) {
70  auxi_val.set_name_ind(i, so.val_t->get_name_ind()[i-1]) ;
71  fgrad.val_t->set_name_ind (i, so.val_t->get_name_ind()[i-1]) ;
72  }
73  }
74 
75  // Part derivative
76  //Loop on the components :
77  Index pos_auxi_bis(auxi_val) ;
78  Index pos_so_bis (*so.val_t) ;
79 
80  // Loop indice summation on connection symbols
81  for (int ind_sum=0 ; ind_sum<val_res-1 ; ind_sum++) {
82 
83  //Loop on the components :
84  Index pos_auxi(auxi_val) ;
85  Index pos_so (*so.val_t) ;
86 
87  do {
88  for (int i=0 ; i<val_res-1 ; i++)
89  pos_so.set(i) = pos_auxi(i+1) ;
90  // Different cases of the derivative index :
91  switch (pos_auxi(0)) {
92  case 0 :
93  // Dr nothing
94  break ;
95  case 1 :
96  // Dtheta
97  // Different cases of the source index
98  switch (pos_auxi(ind_sum+1)) {
99  case 0 :
100  //Dtheta S_r
101  pos_so.set(ind_sum) = 1 ;
102  auxi_val.set(pos_auxi).set_domain(num_dom) -= (*so.val_t)(pos_so)(num_dom) ;
103  break ;
104  case 1 :
105  // Dtheta S_theta
106  pos_so.set(ind_sum) = 0 ;
107  auxi_val.set(pos_auxi).set_domain(num_dom) += (*so.val_t)(pos_so)(num_dom) ;
108  break ;
109  case 2 :
110  //Dtheta S_phi
111  break ;
112  default :
113  cerr << "Bad indice in Domain_shell_inner_adapted::derive_flat_spher" << endl ;
114  abort() ;
115  }
116  break ;
117  case 2 :
118  // Dphi
119  // Different cases of the source index
120  switch (pos_auxi(ind_sum+1)) {
121  case 0 :
122  //Dphi S_r
123  pos_so.set(ind_sum) = 2 ;
124  auxi_val.set(pos_auxi).set_domain(num_dom) -= (*so.val_t)(pos_so)(num_dom) ;
125  break ;
126  case 1 :
127  // Dphi S_theta
128  pos_so.set(ind_sum) = 2 ;
129  auxi_val.set(pos_auxi).set_domain(num_dom) -= (*so.val_t)(pos_so)(num_dom).mult_cos_theta().div_sin_theta() ;
130  break ;
131  case 2 :
132  //Dphi S_phi
133  pos_so.set(ind_sum) = 0 ;
134  auxi_val.set(pos_auxi).set_domain(num_dom) += (*so.val_t)(pos_so)(num_dom) ;
135  pos_so.set(ind_sum) = 1 ;
136  auxi_val.set(pos_auxi).set_domain(num_dom) += (*so.val_t)(pos_so)(num_dom).mult_cos_theta().div_sin_theta() ;
137  break ;
138  default :
139  cerr << "Bad indice in Domain_shell_inner_adapted::derive_flat_spher" << endl ;
140  abort() ;
141  }
142  break ;
143  default :
144  cerr << "Bad indice in Domain_shell_inner_adapted::derive_flat_spher" << endl ;
145  abort() ;
146  }
147  }
148  while (pos_auxi.inc()) ;
149  }
150 
151  if (!doder) {
152  // No need for derivative :
153  Term_eq occi (num_dom, auxi_val) ;
154 
155  Term_eq auxi (occi / (*rad_term_eq) + fgrad) ;
156 
157  // If derive contravariant : manipulate first indice :
158  if (type_der==CON)
159  manipulator->manipulate_ind (auxi, 0) ;
160 
161  if (!need_sum)
162  return auxi ;
163  else
165  }
166  else {
167  // Need to compute the derivative :
168  // Tensor for der
169  Tensor auxi_der (so.val_t->get_space(), val_res, type_ind, basis) ;
170  auxi_der = 0 ;
171 
172  if (donames) {
173  // Set the names of the indices :
174  auxi_der.set_name_affected() ;
175  auxi_der.set_name_ind(0, ind_der) ;
176  fgrad.der_t->set_name_affected() ;
177  fgrad.der_t->set_name_ind(0, ind_der) ;
178  for (int i=1 ; i<val_res ; i++) {
179  auxi_der.set_name_ind(i, so.der_t->get_name_ind()[i-1]) ;
180  fgrad.der_t->set_name_ind(i, so.der_t->get_name_ind()[i-1]) ;
181  }
182  }
183 
184  // Part derivative
185  //Loop on the components :
186  Index pos_auxi_der_bis(auxi_der) ;
187 
188  // Loop indice summation on connection symbols
189  for (int ind_sum=0 ; ind_sum<val_res-1 ; ind_sum++) {
190 
191  //Loop on the components :
192  Index pos_auxi_der(auxi_val) ;
193  Index pos_so (*so.val_t) ;
194 
195  do {
196  for (int i=0 ; i<val_res-1 ; i++)
197  pos_so.set(i) = pos_auxi_der(i+1) ;
198  // Different cases of the derivative index :
199  switch (pos_auxi_der(0)) {
200  case 0 :
201  // Dr nothing
202  break ;
203  case 1 :
204  // Dtheta
205  // Different cases of the source index
206  switch (pos_auxi_der(ind_sum+1)) {
207  case 0 :
208  //Dtheta S_r
209  pos_so.set(ind_sum) = 1 ;
210  auxi_der.set(pos_auxi_der).set_domain(num_dom) -= (*so.der_t)(pos_so)(num_dom) ;
211  break ;
212  case 1 :
213  // Dtheta S_theta
214  pos_so.set(ind_sum) = 0 ;
215  auxi_der.set(pos_auxi_der).set_domain(num_dom) += (*so.der_t)(pos_so)(num_dom) ;
216  break ;
217  case 2 :
218  //Dtheta S_phi
219  break ;
220  default :
221  cerr << "Bad indice in Domain_shell_inner_adapted::derive_flat_spher" << endl ;
222  abort() ;
223  }
224  break ;
225  case 2 :
226  // Dphi
227  // Different cases of the source index
228  switch (pos_auxi_der(ind_sum+1)) {
229  case 0 :
230  //Dphi S_r
231  pos_so.set(ind_sum) = 2 ;
232  auxi_der.set(pos_auxi_der).set_domain(num_dom) -= (*so.der_t)(pos_so)(num_dom) ;
233  break ;
234  case 1 :
235  // Dphi S_theta
236  pos_so.set(ind_sum) = 2 ;
237  auxi_der.set(pos_auxi_der).set_domain(num_dom) -= (*so.der_t)(pos_so)(num_dom).mult_cos_theta().div_sin_theta() ;
238  break ;
239  case 2 :
240  //Dphi S_phi
241  pos_so.set(ind_sum) = 0 ;
242  auxi_der.set(pos_auxi_der).set_domain(num_dom) += (*so.der_t)(pos_so)(num_dom) ;
243  pos_so.set(ind_sum) = 1 ;
244  auxi_der.set(pos_auxi_der).set_domain(num_dom) += (*so.der_t)(pos_so)(num_dom).mult_cos_theta().div_sin_theta() ;
245  break ;
246  default :
247  cerr << "Bad indice in Domain_shell_inner_adapted::derive_flat_spher" << endl ;
248  abort() ;
249  }
250  break ;
251  default :
252  cerr << "Bad indice in Domain_shell_inner_adapted::derive_flat_spher" << endl ;
253  abort() ;
254  }
255  }
256  while (pos_auxi_der.inc()) ;
257  }
258 
259 
260  // Need for derivative :
261  Term_eq occi (num_dom, auxi_val, auxi_der) ;
262  Term_eq auxi (occi/(*rad_term_eq) + fgrad) ;
263 
264  // If derive contravariant : manipulate first indice :
265  if (type_der==CON)
266  manipulator->manipulate_ind (auxi, 0) ;
267  if (!need_sum)
268  return auxi ;
269  else
272  }
273 }
274 
275 
276 Term_eq Domain_shell_inner_adapted::derive_flat_cart (int type_der, char ind_der, const Term_eq& so, const Metric* manipulator) const {
277 
278  bool doder = (so.der_t==0x0) ? false : true ;
279  if ((type_der==CON) && (manipulator->p_met_con[num_dom]->der_t==0x0))
280  doder = false ;
281 
282  assert ((type_der==COV) || (type_der==CON)) ;
283  int val_res = so.val_t->get_valence() + 1 ;
284 
285  bool doname = true ;
286  if (so.val_t->get_valence()>0)
287  if (!so.val_t->is_name_affected())
288  doname = false;
289 
290  Term_eq fgrad (partial_cart(so)) ;
291  if (fgrad.der_t==0x0)
292  doder = false ;
293 
294  // Need for summation ?
295  bool need_sum = false ;
296  if (doname)
297  for (int i=1 ; i<val_res ; i++)
298  if (ind_der== so.val_t->get_name_ind()[i-1])
299  need_sum = true ;
300 
301  // Set the names of the indices :
302  if (doname) {
303  fgrad.val_t->set_name_affected() ;
304  fgrad.val_t->set_name_ind(0, ind_der) ;
305  for (int i=1 ; i<val_res ; i++)
306  fgrad.val_t->set_name_ind(i, so.val_t->get_name_ind()[i-1]) ;
307  }
308 
309  if (!doder) {
310  // If derive contravariant : manipulate first indice :
311  if (type_der==CON)
312  manipulator->manipulate_ind (fgrad, 0) ;
313 
314  if (!need_sum)
315  return fgrad ;
316  else
317  return Term_eq (num_dom, fgrad.val_t->do_summation_one_dom(num_dom)) ;
318  }
319  else {
320  // Need to compute the derivative :
321 
322  fgrad.der_t->set_name_affected() ;
323  fgrad.der_t->set_name_ind(0, ind_der) ;
324  for (int i=1 ; i<val_res ; i++)
325  fgrad.der_t->set_name_ind(i, so.der_t->get_name_ind()[i-1]) ;
326 
327  // If derive contravariant : manipulate first indice :
328  if (type_der==CON)
329  manipulator->manipulate_ind (fgrad, 0) ;
330 
331  if (!need_sum)
332  return fgrad ;
333  else
336  }
337 
338 }
339 }
340 
reference set(const Index &pos)
Read/write of an element.
Definition: array.hpp:186
Describes the tensorial basis used by the various tensors.
Definition: base_tensor.hpp:49
Term_eq flat_grad_spher(const Term_eq &) const
Computes the flat gradient of a field, in orthonormal spherical coordinates.
virtual Term_eq derive_flat_spher(int, char, const Term_eq &, const Metric *) const
Computes the flat derivative of a Term_eq, in spherical orthonormal coordinates.
Term_eq * rad_term_eq
Pointer on the Term_eq containing the radius.
Definition: adapted.hpp:72
virtual Term_eq derive_flat_cart(int, char, const Term_eq &, const Metric *) const
Computes the flat derivative of a Term_eq, in Cartesian coordinates.
virtual Term_eq partial_cart(const Term_eq &) const
Computes the part of the gradient containing the partial derivative of the field, in Cartesian coordi...
virtual Val_domain mult_cos_theta(const Val_domain &) const
Multiplication by .
int num_dom
Number of the current domain (used by the Space)
Definition: space.hpp:63
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
Purely abstract class for metric handling.
Definition: metric.hpp:39
MMPtr_array< Term_eq > p_met_con
Array of pointers on various Term_eq.
Definition: metric.hpp:55
virtual void manipulate_ind(Term_eq &so, int ind) const
Uses the Metric to manipulate one of the index of a Term_eq (i.e.
Definition: metric.cpp:645
Val_domain & set_domain(int)
Read/write of a particular Val_domain.
Definition: scalar.hpp:555
Tensor handling.
Definition: tensor.hpp:149
void set_name_ind(int dd, char name)
Sets the name of one index ; the names must have been affected first.
void set_name_affected()
Affects the name of the indices.
Definition: tensor.hpp:435
Scalar & set(const Array< int > &ind)
Returns the value of a component (read/write version).
Definition: tensor_impl.hpp:91
char const * get_name_ind() const
Definition: tensor.hpp:424
int get_index_type(int i) const
Gives the type (covariant or contravariant) of a given index.
Definition: tensor.hpp:526
int get_valence() const
Returns the valence.
Definition: tensor.hpp:509
bool is_name_affected() const
Check whether the names of the indices have been affected.
Definition: tensor.hpp:429
Tensor do_summation_one_dom(int dd) const
Does the inner contraction of the Tensor in a given domain.
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
Tensor * val_t
Pointer on the value, if the Term_eq is a Tensor.
Definition: term_eq.hpp:68
Val_domain div_sin_theta() const
Division by .