KADATH
domain_shell_symphi_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 "spheric_symphi.hpp"
23 #include "array_math.hpp"
24 #include "term_eq.hpp"
25 #include "metric.hpp"
26 #include "scalar.hpp"
27 #include "tensor_impl.hpp"
28 namespace Kadath {
29 Term_eq Domain_shell_symphi::derive_flat_spher (int type_der, char ind_der, const Term_eq& so, const Metric* manipulator) const {
30 
31  assert ((type_der==COV) || (type_der==CON)) ;
32  int val_res = so.val_t->get_valence() + 1 ;
33 
34  bool donames = (ind_der==' ') ? false : true ;
35  bool need_sum = false ;
36 
37  Array<int> type_ind (val_res) ;
38  type_ind.set(0) = COV ;
39  for (int i=1 ; i<val_res ; i++)
40  type_ind.set(i) = so.val_t->get_index_type(i-1) ;
41 
42  if (donames) {
43  if (so.val_t->get_valence()>0)
44  assert (so.val_t->is_name_affected()) ;
45  // Need for summation ?
46  for (int i=1 ; i<val_res ; i++)
47  if (ind_der== so.val_t->get_name_ind()[i-1])
48  need_sum = true ;
49  }
50 
51  // Tensor for val
52  Base_tensor basis (so.val_t->get_space(), SPHERICAL_BASIS) ;
53  Tensor auxi_val (so.val_t->get_space(), val_res, type_ind, basis) ;
54 
55  if (donames) {
56  // Set the names of the indices :
57  auxi_val.set_name_affected() ;
58  auxi_val.set_name_ind(0, ind_der) ;
59  for (int i=1 ; i<val_res ; i++)
60  auxi_val.set_name_ind(i, so.val_t->get_name_ind()[i-1]) ;
61  }
62 
63  // Part derivative
64  //Loop on the components :
65  Index pos_auxi_bis(auxi_val) ;
66  Index pos_so_bis (*so.val_t) ;
67  do {
68  for (int i=0 ; i<val_res-1 ; i++)
69  pos_so_bis.set(i) = pos_auxi_bis(i+1) ;
70  switch (pos_auxi_bis(0)) {
71  case 0 :
72  // d/dr :
73  auxi_val.set(pos_auxi_bis).set_domain(num_dom) = (*so.val_t)(pos_so_bis)(num_dom).der_r() ;
74  break ;
75  case 1 :
76  // 1/r dtheta
77  auxi_val.set(pos_auxi_bis).set_domain(num_dom) = (*so.val_t)(pos_so_bis)(num_dom).der_var(2).div_r() ;
78  break ;
79  case 2 :
80  // 1/r sint d/dphi
81  auxi_val.set(pos_auxi_bis).set_domain(num_dom) = (*so.val_t)(pos_so_bis)(num_dom).der_var(3).div_r().div_sin_theta() ;
82  break ;
83  default :
84  cerr << "Bad indice in Domain_shell_symphi::derive_flat_spher" << endl ;
85  abort() ;
86  }
87  }
88  while (pos_auxi_bis.inc()) ;
89 
90  // Loop indice summation on connection symbols
91  for (int ind_sum=0 ; ind_sum<val_res-1 ; ind_sum++) {
92 
93  //Loop on the components :
94  Index pos_auxi(auxi_val) ;
95  Index pos_so (*so.val_t) ;
96 
97  do {
98  for (int i=0 ; i<val_res-1 ; i++)
99  pos_so.set(i) = pos_auxi(i+1) ;
100  // Different cases of the derivative index :
101  switch (pos_auxi(0)) {
102  case 0 :
103  // Dr nothing
104  break ;
105  case 1 :
106  // Dtheta
107  // Different cases of the source index
108  switch (pos_auxi(ind_sum+1)) {
109  case 0 :
110  //Dtheta S_r
111  pos_so.set(ind_sum) = 1 ;
112  auxi_val.set(pos_auxi).set_domain(num_dom) -= (*so.val_t)(pos_so)(num_dom).div_r() ;
113  break ;
114  case 1 :
115  // Dtheta S_theta
116  pos_so.set(ind_sum) = 0 ;
117  auxi_val.set(pos_auxi).set_domain(num_dom) += (*so.val_t)(pos_so)(num_dom).div_r() ;
118  break ;
119  case 2 :
120  //Dtheta S_phi
121  break ;
122  default :
123  cerr << "Bad indice in Domain_shell_symphi::derive_flat_spher" << endl ;
124  abort() ;
125  }
126  break ;
127  case 2 :
128  // Dphi
129  // Different cases of the source index
130  switch (pos_auxi(ind_sum+1)) {
131  case 0 :
132  //Dphi S_r
133  pos_so.set(ind_sum) = 2 ;
134  auxi_val.set(pos_auxi).set_domain(num_dom) -= (*so.val_t)(pos_so)(num_dom).div_r() ;
135  break ;
136  case 1 :
137  // Dphi S_theta
138  pos_so.set(ind_sum) = 2 ;
139  auxi_val.set(pos_auxi).set_domain(num_dom) -= (*so.val_t)(pos_so)(num_dom).div_r().mult_cos_theta().div_sin_theta() ;
140  break ;
141  case 2 :
142  //Dphi S_phi
143  pos_so.set(ind_sum) = 0 ;
144  auxi_val.set(pos_auxi).set_domain(num_dom) += (*so.val_t)(pos_so)(num_dom).div_r() ;
145  pos_so.set(ind_sum) = 1 ;
146  auxi_val.set(pos_auxi).set_domain(num_dom) += (*so.val_t)(pos_so)(num_dom).div_r().mult_cos_theta().div_sin_theta() ;
147  break ;
148  default :
149  cerr << "Bad indice in Domain_shell_symphi::derive_flat_spher" << endl ;
150  abort() ;
151  }
152  break ;
153  default :
154  cerr << "Bad indice in Domain_shell_symphi::derive_flat_spher" << endl ;
155  abort() ;
156  }
157  }
158  while (pos_auxi.inc()) ;
159  }
160 
161  if (so.der_t==0x0) {
162  // No need for derivative :
163  Term_eq auxi (num_dom, auxi_val) ;
164  // If derive contravariant : manipulate first indice :
165  if (type_der==CON)
166  manipulator->manipulate_ind (auxi, 0) ;
167 
168  if (!need_sum)
169  return auxi ;
170  else
172  }
173  else {
174  // Need to compute the derivative :
175  // Tensor for der
176  Tensor auxi_der (so.val_t->get_space(), val_res, type_ind, basis) ;
177 
178  if (donames) {
179  // Set the names of the indices :
180  auxi_der.set_name_affected() ;
181  auxi_der.set_name_ind(0, ind_der) ;
182  for (int i=1 ; i<val_res ; i++)
183  auxi_der.set_name_ind(i, so.der_t->get_name_ind()[i-1]) ;
184  }
185 
186  // Part derivative
187  //Loop on the components :
188  Index pos_auxi_der_bis(auxi_der) ;
189  do {
190  for (int i=0 ; i<val_res-1 ; i++)
191  pos_so_bis.set(i) = pos_auxi_der_bis(i+1) ;
192  switch (pos_auxi_der_bis(0)) {
193  case 0 :
194  // d/dr :
195  auxi_der.set(pos_auxi_der_bis).set_domain(num_dom) = (*so.der_t)(pos_so_bis)(num_dom).der_r() ;
196  break ;
197  case 1 :
198  // 1/r dtheta
199  auxi_der.set(pos_auxi_der_bis).set_domain(num_dom) = (*so.der_t)(pos_so_bis)(num_dom).der_var(2).div_r() ;
200  break ;
201  case 2 :
202  // 1/r sint d/dphi
203  auxi_der.set(pos_auxi_der_bis).set_domain(num_dom) = (*so.der_t)(pos_so_bis)(num_dom).der_var(3).div_r().div_sin_theta() ;
204  break ;
205  default :
206  cerr << "Bad indice in Domain_shell_symphi::derive_flat_spher" << endl ;
207  abort() ;
208  }
209  }
210  while (pos_auxi_der_bis.inc()) ;
211 
212  // Loop indice summation on connection symbols
213  for (int ind_sum=0 ; ind_sum<val_res-1 ; ind_sum++) {
214 
215  //Loop on the components :
216  Index pos_auxi_der(auxi_val) ;
217  Index pos_so (*so.val_t) ;
218 
219  do {
220  for (int i=0 ; i<val_res-1 ; i++)
221  pos_so.set(i) = pos_auxi_der(i+1) ;
222  // Different cases of the derivative index :
223  switch (pos_auxi_der(0)) {
224  case 0 :
225  // Dr nothing
226  break ;
227  case 1 :
228  // Dtheta
229  // Different cases of the source index
230  switch (pos_auxi_der(ind_sum+1)) {
231  case 0 :
232  //Dtheta S_r
233  pos_so.set(ind_sum) = 1 ;
234  auxi_der.set(pos_auxi_der).set_domain(num_dom) -= (*so.der_t)(pos_so)(num_dom).div_r() ;
235  break ;
236  case 1 :
237  // Dtheta S_theta
238  pos_so.set(ind_sum) = 0 ;
239  auxi_der.set(pos_auxi_der).set_domain(num_dom) += (*so.der_t)(pos_so)(num_dom).div_r() ;
240  break ;
241  case 2 :
242  //Dtheta S_phi
243  break ;
244  default :
245  cerr << "Bad indice in Domain_shell_symphi::derive_flat_spher" << endl ;
246  abort() ;
247  }
248  break ;
249  case 2 :
250  // Dphi
251  // Different cases of the source index
252  switch (pos_auxi_der(ind_sum+1)) {
253  case 0 :
254  //Dphi S_r
255  pos_so.set(ind_sum) = 2 ;
256  auxi_der.set(pos_auxi_der).set_domain(num_dom) -= (*so.der_t)(pos_so)(num_dom).div_r() ;
257  break ;
258  case 1 :
259  // Dphi S_theta
260  pos_so.set(ind_sum) = 2 ;
261  auxi_der.set(pos_auxi_der).set_domain(num_dom) -= (*so.der_t)(pos_so)(num_dom).div_r().mult_cos_theta().div_sin_theta() ;
262  break ;
263  case 2 :
264  //Dphi S_phi
265  pos_so.set(ind_sum) = 0 ;
266  auxi_der.set(pos_auxi_der).set_domain(num_dom) += (*so.der_t)(pos_so)(num_dom).div_r() ;
267  pos_so.set(ind_sum) = 1 ;
268  auxi_der.set(pos_auxi_der).set_domain(num_dom) += (*so.der_t)(pos_so)(num_dom).div_r().mult_cos_theta().div_sin_theta() ;
269  break ;
270  default :
271  cerr << "Bad indice in Domain_shell_symphi::derive_flat_spher" << endl ;
272  abort() ;
273  }
274  break ;
275  default :
276  cerr << "Bad indice in Domain_shell_symphi::derive_flat_spher" << endl ;
277  abort() ;
278  }
279  }
280  while (pos_auxi_der.inc()) ;
281  }
282 
283 
284  // Need for derivative :
285  Term_eq auxi (num_dom, auxi_val, auxi_der) ;
286  // If derive contravariant : manipulate first indice :
287  if (type_der==CON)
288  manipulator->manipulate_ind (auxi, 0) ;
289  if (!need_sum)
290  return auxi ;
291  else
294  }
295 }
296 
297 
298 Term_eq Domain_shell_symphi::derive_flat_cart (int type_der, char ind_der, const Term_eq& so, const Metric* manipulator) const {
299 
300  bool doder = (so.der_t==0x0) ? false : true ;
301  if ((type_der==CON) && (manipulator->p_met_con[num_dom]->der_t==0x0))
302  doder = false ;
303 
304  assert ((type_der==COV) || (type_der==CON)) ;
305  int val_res = so.val_t->get_valence() + 1 ;
306 
307  bool doname = true ;
308  if (so.val_t->get_valence()>0)
309  if (!so.val_t->is_name_affected())
310  doname = false;
311 
312  Array<int> type_ind (val_res) ;
313  type_ind.set(0) = COV ;
314  for (int i=1 ; i<val_res ; i++)
315  type_ind.set(i) = so.val_t->get_index_type(i-1) ;
316 
317  // Need for summation ?
318  bool need_sum = false ;
319  if (doname)
320  for (int i=1 ; i<val_res ; i++)
321  if (ind_der== so.val_t->get_name_ind()[i-1])
322  need_sum = true ;
323 
324  // Tensor for val
325  Base_tensor basis (so.val_t->get_space(), CARTESIAN_BASIS) ;
326  Tensor auxi_val (so.val_t->get_space(), val_res, type_ind, basis) ;
327 
328 
329  // Set the names of the indices :
330  if (doname) {
331  auxi_val.set_name_affected() ;
332  auxi_val.set_name_ind(0, ind_der) ;
333  for (int i=1 ; i<val_res ; i++)
334  auxi_val.set_name_ind(i, so.val_t->get_name_ind()[i-1]) ;
335  }
336 
337  //Loop on the components :
338  Index pos_auxi(auxi_val) ;
339  Index pos_so (*so.val_t) ;
340  do {
341  for (int i=0 ; i<val_res-1 ; i++)
342  pos_so.set(i) = pos_auxi(i+1) ;
343  auxi_val.set(pos_auxi).set_domain(num_dom) = (*so.val_t)(pos_so)(num_dom).der_abs(pos_auxi(0)+1) ;
344  }
345  while (pos_auxi.inc()) ;
346 
347  if (!doder) {
348  // No need for derivative :
349  Term_eq auxi (num_dom, auxi_val) ;
350  // If derive contravariant : manipulate first indice :
351  if (type_der==CON)
352  manipulator->manipulate_ind (auxi, 0) ;
353 
354  if (!need_sum)
355  return auxi ;
356  else
358  }
359  else {
360  // Need to compute the derivative :
361  // Tensor for der
362  Tensor auxi_der (so.val_t->get_space(), val_res, type_ind, basis) ;
363  // Set the names of the indices :
364  auxi_der.set_name_affected() ;
365  auxi_der.set_name_ind(0, ind_der) ;
366  for (int i=1 ; i<val_res ; i++)
367  auxi_der.set_name_ind(i, so.der_t->get_name_ind()[i-1]) ;
368 
369  //Loop on the components :
370  Index pos_auxi_der(auxi_der) ;
371  do {
372  for (int i=0 ; i<val_res-1 ; i++)
373  pos_so.set(i) = pos_auxi_der(i+1) ;
374  auxi_der.set(pos_auxi_der).set_domain(num_dom) = (*so.der_t)(pos_so)(num_dom).der_abs(pos_auxi_der(0)+1) ;
375  }
376  while (pos_auxi_der.inc()) ;
377 
378  // Need for derivative :
379  Term_eq auxi (num_dom, auxi_val, auxi_der) ;
380 
381  // If derive contravariant : manipulate first indice :
382  if (type_der==CON)
383  manipulator->manipulate_ind (auxi, 0) ;
384 
385  if (!need_sum)
386  return auxi ;
387  else
390  }
391 
392 }
393 }
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
virtual Val_domain div_r(const Val_domain &) const
Division by .
virtual Val_domain der_r(const Val_domain &) const
Compute the radial derivative of a scalar field.
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 derive_flat_spher(int, char, const Term_eq &, const Metric *) const
Computes the flat derivative of a Term_eq, in spherical orthonormal coordinates.
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_r() const
Division by the radius.
Definition: val_domain.cpp:743
Val_domain div_sin_theta() const
Division by .
Val_domain mult_cos_theta() const
Multiplication by .