KADATH
domain_shell_inner_adapted_term_eq.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 "scalar.hpp"
26 #include "tensor_impl.hpp"
27 #include "vector.hpp"
28 
29 namespace Kadath {
31  return derive_r(so) ;
32 }
33 
35 
36  assert (so.get_dom() == num_dom) ;
37 
38  Tensor val_res(*so.val_t, false) ;
39 
40  for (int cmp = 0 ; cmp<so.val_t->get_n_comp() ; cmp++) {
41  Array<int>ind (val_res.indices(cmp)) ;
42  val_res.set(ind).set_domain(num_dom) = (*so.val_t)(ind)(num_dom).der_var(1) / (*der_rad_term_eq->val_t)()(num_dom) ;
43  }
44 
45  bool doder = ((so.der_t==0x0) || (der_rad_term_eq->der_t==0x0)) ? false : true ;
46  if (doder) {
47  Tensor der_res (*so.der_t, false) ;
48  for (int cmp = 0 ; cmp<so.val_t->get_n_comp() ; cmp++) {
49  Array<int>ind (val_res.indices(cmp)) ;
50  der_res.set(ind).set_domain(num_dom) = ((*so.der_t)(ind)(num_dom).der_var(1)*(*der_rad_term_eq->val_t)()(num_dom)
51  - (*so.val_t)(ind)(num_dom).der_var(1)*(*der_rad_term_eq->der_t)()(num_dom)) /
53  }
54  return Term_eq (num_dom, val_res, der_res) ;
55  }
56  else
57  return Term_eq (num_dom, val_res) ;
58 }
59 
61 
62  assert (so.get_dom() == num_dom) ;
63  Term_eq* dtprime ;
64  Tensor val_res(*so.val_t, false) ;
65 
66  for (int cmp = 0 ; cmp<so.val_t->get_n_comp() ; cmp++) {
67  Array<int>ind (val_res.indices(cmp)) ;
68  val_res.set(ind).set_domain(num_dom) = (*so.val_t)(ind)(num_dom).der_var(2) ;
69  }
70  bool doder = (so.der_t==0x0) ? false : true ;
71 
72  if (doder) {
73  Tensor der_res (*so.der_t, false) ;
74  for (int cmp = 0 ; cmp<so.val_t->get_n_comp() ; cmp++) {
75  Array<int>ind (val_res.indices(cmp)) ;
76  der_res.set(ind).set_domain(num_dom) = (*so.der_t)(ind)(num_dom).der_var(2) ;
77  }
78  dtprime = new Term_eq (num_dom, val_res, der_res) ;
79  }
80  else
81  dtprime = new Term_eq (num_dom, val_res) ;
82 
83 
84  Term_eq res (*dtprime - (*dt_rad_term_eq) * derive_r(so)) ;
85  delete dtprime ;
86  return res ;
87 
88 }
89 
91 
92  Term_eq* dpprime ;
93  Tensor val_res(*so.val_t, false) ;
94 
95  for (int cmp = 0 ; cmp<so.val_t->get_n_comp() ; cmp++) {
96  Array<int>ind (val_res.indices(cmp)) ;
97  val_res.set(ind).set_domain(num_dom) = (*so.val_t)(ind)(num_dom).der_var(3) ;
98  }
99  bool doder = (so.der_t==0x0) ? false : true ;
100 
101  if (doder) {
102  Tensor der_res (*so.der_t, false) ;
103  for (int cmp = 0 ; cmp<so.val_t->get_n_comp() ; cmp++) {
104  Array<int>ind (val_res.indices(cmp)) ;
105  der_res.set(ind).set_domain(num_dom) = (*so.der_t)(ind)(num_dom).der_var(3) ;
106  }
107  dpprime = new Term_eq (num_dom, val_res, der_res) ;
108  }
109  else
110  dpprime = new Term_eq (num_dom, val_res) ;
111 
112 
113  Term_eq res (*dpprime - (*dp_rad_term_eq) * derive_r(so)) ;
114  delete dpprime ;
115  return res ;
116 
117 }
118 
119 
121 
122  assert (so.get_dom() == num_dom) ;
123 
124  int valso = so.get_val_t().get_valence() ;
125  Array<int> type_ind (valso+1) ;
126  type_ind.set(0) = COV ;
127  for (int i=0 ; i<valso ; i++)
128  type_ind.set(i+1) = so.get_val_t().get_index_type(i) ;
129 
130  Base_tensor basis (sp) ;
131  basis.set_basis(num_dom) = SPHERICAL_BASIS ;
132  Tensor res (sp, valso+1 , type_ind, basis) ;
133 
134  Term_eq comp_r (derive_r(so)) ;
135  Term_eq comp_t (derive_t(so)/(*rad_term_eq)) ;
137 
138 
139  // Loop on cmp :
140  for (int nc=0 ; nc<so.get_val_t().get_n_comp() ; nc++) {
141 
142  Array<int> ind (so.get_val_t().indices(nc)) ;
143  Array<int> indtarget (valso+1) ;
144  for (int i=0 ; i<valso ; i++)
145  indtarget.set(i+1) = ind(i) ;
146 
147  // R comp :
148  indtarget.set(0) = 1 ;
149  res.set(indtarget).set_domain(num_dom) = comp_r.get_val_t()(ind)(num_dom);
150  // theta comp :
151  indtarget.set(0) = 2 ;
152  res.set(indtarget).set_domain(num_dom) = comp_t.get_val_t()(ind)(num_dom) ;
153  // Phi comp :
154  indtarget.set(0) = 3 ;
155  res.set(indtarget).set_domain(num_dom) = comp_p.get_val_t()(ind)(num_dom) ;
156  }
157  bool doder = ((so.der_t==0x0) || (inner_radius_term_eq->der_t==0x0)) ? false : true ;
158 
159  if (!doder) {
160  return Term_eq (num_dom, res) ;
161  }
162  else {
163 
164  Tensor resder (sp, valso+1 , type_ind, basis) ;
165  // Loop on cmp :
166  for (int nc=0 ; nc<so.get_val_t().get_n_comp() ; nc++) {
167 
168  Array<int> ind (so.get_val_t().indices(nc)) ;
169  Array<int> indtarget (valso+1) ;
170  for (int i=0 ; i<valso ; i++)
171  indtarget.set(i+1) = ind(i) ;
172 
173  // R comp :
174  indtarget.set(0) = 1 ;
175  resder.set(indtarget).set_domain(num_dom) = comp_r.get_der_t()(ind)(num_dom);
176  // theta comp :
177  indtarget.set(0) = 2 ;
178  resder.set(indtarget).set_domain(num_dom) = comp_t.get_der_t()(ind)(num_dom) ;
179  // Phi comp :
180  indtarget.set(0) = 3 ;
181  resder.set(indtarget).set_domain(num_dom) = comp_p.get_der_t()(ind)(num_dom) ;
182  }
183  return Term_eq (num_dom, res, resder) ;
184  }
185 }
186 
188 
190 
191  Scalar val_norme (sp) ;
192  val_norme.set_domain(num_dom) = sqrt((*grad.val_t)(1)(num_dom)*(*grad.val_t)(1)(num_dom)
193  + (*grad.val_t)(2)(num_dom)*(*grad.val_t)(2)(num_dom)
194  + (*grad.val_t)(3)(num_dom)*(*grad.val_t)(3)(num_dom)) ;
195  bool doder = ((grad.der_t==0x0) || (inner_radius_term_eq->der_t==0x0)) ? false : true ;
196  if (doder) {
197  Scalar der_norme (sp) ;
198  der_norme.set_domain(num_dom) = ((*grad.der_t)(1)(num_dom)*(*grad.val_t)(1)(num_dom)
199  + (*grad.der_t)(2)(num_dom)*(*grad.val_t)(2)(num_dom)
200  + (*grad.der_t)(3)(num_dom)*(*grad.val_t)(3)(num_dom)) / val_norme(num_dom) ;
201  Term_eq norme (num_dom, val_norme, der_norme) ;
202  if (normal_spher==0x0)
203  normal_spher = new Term_eq (grad / norme) ;
204  else
205  *normal_spher = Term_eq(grad/norme) ;
206  }
207  else {
208  Term_eq norme (num_dom, val_norme) ;
209  if (normal_spher==0x0)
210  normal_spher = new Term_eq (grad / norme) ;
211  else
212  *normal_spher = Term_eq(grad/norme) ;
213  }
214 }
215 
217 
218 
219  do_normal_spher() ;
220 
221  Base_tensor basis (sp) ;
222  basis.set_basis(num_dom) = CARTESIAN_BASIS ;
223  Vector val (sp, CON, basis) ;
224 
230 
231  bool doder = (normal_spher->der_t==0x0) ? false : true ;
232  if (doder) {
233  Vector der (sp, CON, basis) ;
234 
240 
241  if (normal_cart==0x0)
242  normal_cart = new Term_eq (num_dom, val, der) ;
243  else
244  *normal_cart = Term_eq(num_dom, val,der) ;
245  }
246  else {
247  if (normal_cart==0x0)
248  normal_cart = new Term_eq (num_dom, val) ;
249  else
250  *normal_cart = Term_eq(num_dom, val) ;
251  }
252 }
253 
255 
256 
257  switch (bound) {
258  case INNER_BC : {
259  // Deformed surface
260  if (normal_spher == 0x0)
261  do_normal_spher() ;
262 
263  int valso = so.get_val_t().get_valence() ;
264 
265  Term_eq grad (flat_grad_spher(so)) ;
266 
267  Tensor res (so.get_val_t(), false) ;
268 
269  // Loop on cmp :
270  for (int nc=0 ; nc<so.get_val_t().get_n_comp() ; nc++) {
271 
272  Array<int> ind (so.get_val_t().indices(nc)) ;
273  Array<int> indgrad (valso+1) ;
274  for (int i=0 ; i<valso ; i++)
275  indgrad.set(i+1) = ind(i) ;
276 
277  indgrad.set(0) = 1 ;
278  res.set(ind).set_domain(num_dom) = (*grad.val_t)(indgrad)(num_dom) * (*normal_spher->val_t)(1)(num_dom) ;
279  indgrad.set(0) = 2 ;
280  res.set(ind).set_domain(num_dom) += (*grad.val_t)(indgrad)(num_dom) * (*normal_spher->val_t)(2)(num_dom) ;
281  indgrad.set(0) = 3 ;
282  res.set(ind).set_domain(num_dom) += (*grad.val_t)(indgrad)(num_dom) * (*normal_spher->val_t)(3)(num_dom) ;
283  }
284 
285  bool doder = ((grad.der_t == 0x0) || (normal_spher->der_t == 0x0)) ? false : true ;
286  if (doder) {
287 
288  Tensor der (so.get_val_t(), false) ;
289 
290  // Loop on cmp :
291  for (int nc=0 ; nc<so.get_val_t().get_n_comp() ; nc++) {
292 
293  Array<int> ind (so.get_val_t().indices(nc)) ;
294  Array<int> indgrad (valso+1) ;
295  for (int i=0 ; i<valso ; i++)
296  indgrad.set(i+1) = ind(i) ;
297 
298  indgrad.set(0) = 1 ;
299  der.set(ind).set_domain(num_dom) = (*grad.der_t)(indgrad)(num_dom) * (*normal_spher->val_t)(1)(num_dom)
300  + (*grad.val_t)(indgrad)(num_dom) * (*normal_spher->der_t)(1)(num_dom) ;
301  indgrad.set(0) = 2 ;
302  der.set(ind).set_domain(num_dom) += (*grad.der_t)(indgrad)(num_dom) * (*normal_spher->val_t)(2)(num_dom)
303  + (*grad.val_t)(indgrad)(num_dom) * (*normal_spher->der_t)(2)(num_dom) ;
304  indgrad.set(0) = 3 ;
305  der.set(ind).set_domain(num_dom) += (*grad.der_t)(indgrad)(num_dom) * (*normal_spher->val_t)(3)(num_dom)
306  + (*grad.val_t)(indgrad)(num_dom) * (*normal_spher->der_t)(3)(num_dom) ;
307  }
308 
309  return Term_eq (num_dom, res, der) ;
310  }
311  else return Term_eq (num_dom, res) ;
312  }
313  case OUTER_BC : {
314  return derive_r(so) ;
315  }
316  default :
317  cerr << "Unknown boundary in Domain_shell_inner_adapted::der_normal" << endl ;
318  abort() ;
319  }
320 }
321 
323 #ifndef REMOVE_ALL_CHECKS
324  if (mm!=0) {
325  cerr << "Domain_shell_inner_adapted::lap_term_eq not defined for m != 0 (for now)" << endl ;
326  abort() ;
327  }
328 
329  if (so.get_val_t().get_valence() != 0) {
330  cerr << "Domain_shell_inner_adapted::lap_term_eq only defined for scalars" << endl ;
331  abort() ;
332  }
333 #endif
334  // Angular part :
335  Term_eq dert (derive_t(so));
336  Term_eq p1 (derive_t(dert)) ;
338  Term_eq der2p (derive_p(derive_p(so))) ;
340 
341  Term_eq dr(derive_r(so)) ;
342 
343  Term_eq res (derive_r(dr) + 2 *dr / (*rad_term_eq) + (p1+p2+p3)/(*rad_term_eq)/(*rad_term_eq));
344 
345 
346  return res ;
347 }
348 
350 
351 
352  return so * (*rad_term_eq) ;
353 }
354 
356 
357  Tensor der (*so->val_t, false) ;
358  for (int cmp=0 ; cmp<so->val_t->get_n_comp() ; cmp ++) {
359 
360 
361 
362  Val_domain derr ((*(*so->val_t).cmp[cmp])(num_dom).der_var(1) / (*der_rad_term_eq->val_t)()(num_dom)) ;
363 
364  if (!derr.check_if_zero()) {
365  Val_domain res(this) ;
366  res.allocate_conf() ;
367  Index pos (nbr_points) ;
368  do {
369  res.set(pos) = (*(*inner_radius_term_eq->der_t).cmp[0])(num_dom)(pos) / 2. * (1-((*coloc[0])(pos(0)))) * derr(pos) ;
370  }
371  while (pos.inc()) ;
372  res.set_base() = (*(*so->val_t).cmp[cmp])(num_dom).get_base() ;
373  der.cmp[cmp]->set_domain(num_dom) = res ;
374  }
375  else
376  der.cmp[cmp]->set_domain(num_dom).set_zero() ;
377  }
378 
379  so->set_der_t (der) ;
380 }
381 
383  int dom = so.get_dom() ;
384  assert (dom == num_dom) ;
385 
386  int valence = so.val_t->get_valence() ;
387 
388  Array<int> type_ind (valence+1) ;
389  type_ind.set(0) = COV ;
390  for (int i=1 ; i<valence+1 ; i++)
391  type_ind.set(i) = so.val_t->get_index_type(i-1) ;
392 
393  Base_tensor basis (so.get_val_t().get_space()) ;
394  basis.set_basis(dom) = SPHERICAL_BASIS ;
395 
396  Term_eq comp_r (derive_r(so)) ;
397  Term_eq comp_t (derive_t(so) / (*rad_term_eq)) ;
399 
400  Tensor val_res (so.get_val_t().get_space(), valence+1, type_ind, basis) ;
401  {
402  Index pos_so (*so.val_t) ;
403  Index pos_res (val_res) ;
404  do {
405  for (int i=1 ; i<valence+1 ; i++)
406  pos_res.set(i) = pos_so(i-1) ;
407  // R part
408  pos_res.set(0) = 0 ;
409  val_res.set(pos_res).set_domain(num_dom) = (*comp_r.val_t)(pos_so)(num_dom) ;
410  // Theta part
411  pos_res.set(0) = 1 ;
412  val_res.set(pos_res).set_domain(num_dom) = (*comp_t.val_t)(pos_so)(num_dom) ;
413  // Phi part
414  pos_res.set(0) = 2 ;
415  val_res.set(pos_res).set_domain(num_dom) = (*comp_p.val_t)(pos_so)(num_dom) ;
416  }
417  while (pos_so.inc()) ;
418 }
419 
420  bool doder = ((so.der_t==0x0) || (inner_radius_term_eq->der_t==0x0)) ? false : true ;
421  if (doder) {
422  Tensor der_res (so.get_val_t().get_space(), valence+1, type_ind, basis) ;
423  Index pos_so (*so.der_t) ;
424  Index pos_res (val_res) ;
425  do {
426  for (int i=1 ; i<valence+1 ; i++)
427  pos_res.set(i) = pos_so(i-1) ;
428  // R part
429  pos_res.set(0) = 0 ;
430  der_res.set(pos_res).set_domain(num_dom) = (*comp_r.der_t)(pos_so)(num_dom) ;
431  // Theta part
432  pos_res.set(0) = 1 ;
433  der_res.set(pos_res).set_domain(num_dom) = (*comp_t.der_t)(pos_so)(num_dom) ;
434  // Phi part
435  pos_res.set(0) = 2 ;
436  der_res.set(pos_res).set_domain(num_dom) = (*comp_p.der_t)(pos_so)(num_dom) ;
437  }
438  while (pos_so.inc()) ;
439 
440  return Term_eq (num_dom, val_res, der_res) ;
441  }
442  else
443  return Term_eq (num_dom, val_res) ;
444 }
445 
446 
448 
449  int dom = so.get_dom() ;
450  assert (dom == num_dom) ;
451 
452  int valence = so.val_t->get_valence() ;
453  int val_res = so.val_t->get_valence() + 1 ;
454 
455  Array<int> type_ind (val_res) ;
456  type_ind.set(0) = COV ;
457  for (int i=1 ; i<val_res ; i++)
458  type_ind.set(i) = so.val_t->get_index_type(i-1) ;
459 
460  Base_tensor basis (so.get_val_t().get_space()) ;
461  basis.set_basis(dom) = SPHERICAL_BASIS ;
462 
463  Tensor auxi_val (so.get_val_t().get_space(), val_res, type_ind, basis) ;
464  for (int cmp=0 ; cmp<auxi_val.get_n_comp() ; cmp ++)
465  auxi_val.set(auxi_val.indices(cmp)) = 0 ;
466 
467  for (int ind_sum=0 ; ind_sum<valence ; ind_sum++) {
468 
469  //Loop on the components :
470  Index pos_auxi(auxi_val) ;
471  Index pos_so (*so.val_t) ;
472 
473  do {
474  for (int i=0 ; i<valence ; i++)
475  pos_so.set(i) = pos_auxi(i+1) ;
476  // Different cases of the derivative index :
477  switch (pos_auxi(0)) {
478  case 0 :
479  // Dr nothing
480  break ;
481  case 1 :
482  // Dtheta
483  // Different cases of the source index
484  switch (pos_auxi(ind_sum+1)) {
485  case 0 :
486  //Dtheta S_r
487  pos_so.set(ind_sum) = 1 ;
488  auxi_val.set(pos_auxi).set_domain(dom) -= (*so.val_t)(pos_so)(dom).div_r() ;
489  break ;
490  case 1 :
491  // Dtheta S_theta
492  pos_so.set(ind_sum) = 0 ;
493  auxi_val.set(pos_auxi).set_domain(dom) += (*so.val_t)(pos_so)(dom).div_r() ;
494  break ;
495  case 2 :
496  //Dtheta S_phi
497  break ;
498  default :
499  cerr << "Bad indice in Domain_shell_inner_adapted::connection_spher" << endl ;
500  abort() ;
501  }
502  break ;
503  case 2 :
504  // Dphi
505  // Different cases of the source index
506  switch (pos_auxi(ind_sum+1)) {
507  case 0 :
508  //Dphi S_r
509  pos_so.set(ind_sum) = 2 ;
510  auxi_val.set(pos_auxi).set_domain(dom) -= (*so.val_t)(pos_so)(dom).div_r() ;
511  break ;
512  case 1 :
513  // Dphi S_theta
514  pos_so.set(ind_sum) = 2 ;
515  auxi_val.set(pos_auxi).set_domain(dom) -= (*so.val_t)(pos_so)(dom).div_r().mult_cos_theta().div_sin_theta() ;
516  break ;
517  case 2 :
518  //Dphi S_phi
519  pos_so.set(ind_sum) = 0 ;
520  auxi_val.set(pos_auxi).set_domain(dom) += (*so.val_t)(pos_so)(dom).div_r() ;
521  pos_so.set(ind_sum) = 1 ;
522  auxi_val.set(pos_auxi).set_domain(dom) += (*so.val_t)(pos_so)(dom).div_r().mult_cos_theta().div_sin_theta() ;
523  break ;
524  default :
525  cerr << "Bad indice in Domain_shell_inner_adapted::connection_spher" << endl ;
526  abort() ;
527  }
528  break ;
529  default :
530  cerr << "Bad indice in Domain_shell_inner_adapted::connection_spher" << endl ;
531  abort() ;
532  }
533  }
534  while (pos_auxi.inc()) ;
535  }
536 
537 
538  if ((so.der_t==0x0) || (inner_radius_term_eq->der_t==0x0)) {
539  // No need for derivative :
540  return Term_eq (dom, auxi_val) ;
541  }
542  else {
543 
544  // Need to compute the derivative :
545  // Tensor for der
546  Tensor auxi_der (so.get_val_t().get_space(), val_res, type_ind, basis) ;
547  for (int cmp=0 ; cmp<auxi_der.get_n_comp() ; cmp ++)
548  auxi_der.set(auxi_der.indices(cmp)) = 0 ;
549 
550  // Loop indice summation on connection symbols
551  for (int ind_sum=0 ; ind_sum<valence ; ind_sum++) {
552 
553  //Loop on the components :
554  Index pos_auxi_der(auxi_der) ;
555  Index pos_so (*so.der_t) ;
556 
557  do {
558  for (int i=0 ; i<valence ; i++)
559  pos_so.set(i) = pos_auxi_der(i+1) ;
560  // Different cases of the derivative index :
561  switch (pos_auxi_der(0)) {
562  case 0 :
563  // Dr nothing
564  break ;
565  case 1 :
566  // Dtheta
567  // Different cases of the source index
568  switch (pos_auxi_der(ind_sum+1)) {
569  case 0 :
570  //Dtheta S_r
571  pos_so.set(ind_sum) = 1 ;
572  auxi_der.set(pos_auxi_der).set_domain(dom) -=
573  ((*so.der_t)(pos_so)(dom) -(*so.val_t)(pos_so)(dom)*(*rad_term_eq->der_t)()(dom)/(*rad_term_eq->val_t)()(dom)).div_r() ;
574  break ;
575  case 1 :
576  // Dtheta S_theta
577  pos_so.set(ind_sum) = 0 ;
578  auxi_der.set(pos_auxi_der).set_domain(dom) +=
579  ((*so.der_t)(pos_so)(dom) -(*so.val_t)(pos_so)(dom)*(*rad_term_eq->der_t)()(dom)/(*rad_term_eq->val_t)()(dom)).div_r() ;
580  break ;
581  case 2 :
582  //Dtheta S_phi
583  break ;
584  default :
585  cerr << "Bad indice in Domain_shell_inner_adapted::connection_spher" << endl ;
586  abort() ;
587  }
588  break ;
589  case 2 :
590  // Dphi
591  // Different cases of the source index
592  switch (pos_auxi_der(ind_sum+1)) {
593  case 0 :
594  //Dphi S_r
595  pos_so.set(ind_sum) = 2 ;
596  auxi_der.set(pos_auxi_der).set_domain(dom) -=
597  ((*so.der_t)(pos_so)(dom) -(*so.val_t)(pos_so)(dom)*(*rad_term_eq->der_t)()(dom)/(*rad_term_eq->val_t)()(dom)).div_r() ;
598  break ;
599  case 1 :
600  // Dphi S_theta
601  pos_so.set(ind_sum) = 2 ;
602  auxi_der.set(pos_auxi_der).set_domain(dom) -=
603  ((*so.der_t)(pos_so)(dom) -(*so.val_t)(pos_so)(dom)*(*rad_term_eq->der_t)()(dom)/(*rad_term_eq->val_t)()(dom)).div_r().mult_cos_theta().div_sin_theta() ;
604  break ;
605  case 2 :
606  //Dphi S_phi
607  pos_so.set(ind_sum) = 0 ;
608  auxi_der.set(pos_auxi_der).set_domain(dom) +=
609  ((*so.der_t)(pos_so)(dom) -(*so.val_t)(pos_so)(dom)*(*rad_term_eq->der_t)()(dom)/(*rad_term_eq->val_t)()(dom)).div_r() ;
610  pos_so.set(ind_sum) = 1 ;
611  auxi_der.set(pos_auxi_der).set_domain(dom) +=
612  ((*so.der_t)(pos_so)(dom) -(*so.val_t)(pos_so)(dom)*(*rad_term_eq->der_t)()(dom)/(*rad_term_eq->val_t)()(dom)).div_r().mult_cos_theta().div_sin_theta() ;
613  break ;
614  default :
615  cerr << "Bad indice in Domain_shell_inner_adapted::connection_spher" << endl ;
616  abort() ;
617  }
618  break ;
619  default :
620  cerr << "Bad indice in Domain_shell_inner_adapted::connection_spher" << endl ;
621  abort() ;
622  }
623  }
624  while (pos_auxi_der.inc()) ;
625  }
626 
627  return Term_eq (dom, auxi_val, auxi_der) ;
628  }
629 }
630 
632  int dom = so.get_dom() ;
633  assert (dom == num_dom) ;
634 
635  int valence = so.val_t->get_valence() ;
636 
637  Array<int> type_ind (valence+1) ;
638  type_ind.set(0) = COV ;
639  for (int i=1 ; i<valence+1 ; i++)
640  type_ind.set(i) = so.val_t->get_index_type(i-1) ;
641 
642  Base_tensor basis (so.get_val_t().get_space()) ;
643  basis.set_basis(dom) = CARTESIAN_BASIS ;
644 
645  Term_eq comp_r (derive_r(so)) ;
646  Term_eq comp_t (derive_t(so) / (*rad_term_eq)) ;
648 
649  Tensor val_res (so.get_val_t().get_space(), valence+1, type_ind, basis) ;
650  {
651  Index pos_so (*so.val_t) ;
652  Index pos_res (val_res) ;
653  do {
654  for (int i=1 ; i<valence+1 ; i++)
655  pos_res.set(i) = pos_so(i-1) ;
656 
657  Val_domain auxi (mult_sin_theta((*comp_r.val_t)(pos_so)(num_dom)) + mult_cos_theta((*comp_t.val_t)(pos_so)(num_dom))) ;
658  // X part
659  pos_res.set(0) = 0 ;
660  val_res.set(pos_res).set_domain(num_dom) = mult_cos_phi(auxi) - mult_sin_phi((*comp_p.val_t)(pos_so)(num_dom)) ;
661  // Y part
662  pos_res.set(0) = 1 ;
663  val_res.set(pos_res).set_domain(num_dom) = mult_sin_phi(auxi) + mult_cos_phi((*comp_p.val_t)(pos_so)(num_dom)) ;
664  // Z part
665  pos_res.set(0) = 2 ;
666  val_res.set(pos_res).set_domain(num_dom) =
667  mult_cos_theta((*comp_r.val_t)(pos_so)(num_dom)) - mult_sin_theta((*comp_t.val_t)(pos_so)(num_dom)) ;
668  }
669  while (pos_so.inc()) ;
670 }
671 
672  bool doder = ((so.der_t==0x0) || (rad_term_eq->der_t==0x0)) ? false : true ;
673  if (doder) {
674  Tensor der_res (so.get_val_t().get_space(), valence+1, type_ind, basis) ;
675  Index pos_so (*so.der_t) ;
676  Index pos_res (val_res) ;
677  do {
678  for (int i=1 ; i<valence+1 ; i++)
679  pos_res.set(i) = pos_so(i-1) ;
680 
681  Val_domain auxi (mult_sin_theta((*comp_r.der_t)(pos_so)(num_dom)) + mult_cos_theta((*comp_t.der_t)(pos_so)(num_dom))) ;
682  // X part
683  pos_res.set(0) = 0 ;
684  der_res.set(pos_res).set_domain(num_dom) = mult_cos_phi(auxi) - mult_sin_phi((*comp_p.der_t)(pos_so)(num_dom)) ;
685  // Y part
686  pos_res.set(0) = 1 ;
687  der_res.set(pos_res).set_domain(num_dom) = mult_sin_phi(auxi) + mult_cos_phi((*comp_p.der_t)(pos_so)(num_dom)) ;
688  // Z part
689  pos_res.set(0) = 2 ;
690  der_res.set(pos_res).set_domain(num_dom) =
691  mult_cos_theta((*comp_r.der_t)(pos_so)(num_dom)) - mult_sin_theta((*comp_t.der_t)(pos_so)(num_dom)) ;
692  }
693  while (pos_so.inc()) ;
694 
695  return Term_eq (num_dom, val_res, der_res) ;
696  }
697  else
698  return Term_eq (num_dom, val_res) ;
699 }
700 
701 const Term_eq* Domain_shell_inner_adapted::give_normal (int bound, int tipe) const {
702  assert (bound==INNER_BC) ;
703  switch (tipe) {
704  case CARTESIAN_BASIS :
705  if (normal_cart==0x0)
706  do_normal_cart() ;
707  return normal_cart ;
708 
709  case SPHERICAL_BASIS :
710  if (normal_spher==0x0)
711  do_normal_spher() ;
712  return normal_spher ;
713 
714  default:
715  cerr << "Unknown type of tensorial basis in Domain_shell_inner_adapted::give_normal" << endl ;
716  abort() ;
717  }
718 }
719 
720 double integral_1d (int, const Array<double>&) ;
722 
723  int dom = target.get_dom() ;
724  // Check it is a tensor
725 #ifndef REMOVE_ALL_CHECKS
726  if (target.type_data != TERM_T) {
727  cerr << "Ope_int_volume only defined with respect for a tensor" << endl ;
728  abort() ;
729  }
730 
731  if (target.val_t->get_n_comp() != 1) {
732  cerr << "Ope_int_volume only defined with respect to a scalar" << endl ;
733  abort() ;
734  }
735 #endif
737 
738  // The value
739  Array<int> ind (target.val_t->indices(0)) ;
740  Val_domain value ((*integrant.val_t)(ind)(dom)) ;
741  double resval = 0 ;
742  if (value.check_if_zero())
743  resval= 0. ;
744  else {
745  int baset = (*value.get_base().bases_1d[1])(0) ;
746  assert(baset==SIN_ODD) ;
747  Index pos (nbr_coefs) ;
748  for (int j=0 ; j<nbr_coefs(1) ; j++) {
749  pos.set(1) = j ;
750  int baser = (*value.get_base().bases_1d[0]) (j, 0) ;
751  assert (baser==CHEB) ;
752 
753  Array<double> cf (nbr_coefs(0)) ;
754  for (int i=0 ; i<nbr_coefs(0) ; i++) {
755  pos.set(0) = i ;
756  cf.set(i) = value.get_coef(pos) ;
757  }
758  resval += 2./(2.*j+1) * integral_1d(CHEB, cf) ;
759  }
760  resval *= 2*M_PI ;
761  }
762 
763  // The der
764  if (integrant.der_t!=0x0) {
765  Val_domain derval ((*integrant.der_t)(ind)(dom)) ;
766  double resder = 0 ;
767  if (derval.check_if_zero())
768  resder= 0. ;
769  else {
770  int baset = (*derval.get_base().bases_1d[1]) (0) ;
771  assert(baset==SIN_ODD) ;
772  Index pos (nbr_coefs) ;
773  for (int j=0 ; j<nbr_coefs(1) ; j++) {
774  pos.set(1) = j ;
775  int baser = (*derval.get_base().bases_1d[0]) (j, 0) ;
776  assert (baser==CHEB) ;
777 
778  Array<double> cf (nbr_coefs(0)) ;
779  for (int i=0 ; i<nbr_coefs(0) ; i++) {
780  pos.set(0) = i ;
781  cf.set(i) = derval.get_coef(pos) ;
782  }
783  resder += 2./(2.*j+1) * integral_1d(CHEB, cf) ;
784  }
785  resder *= 2*M_PI ;
786  }
787  return Term_eq (dom, resval, resder) ;
788  }
789  else {
790  return Term_eq (dom, resval) ;
791  }
792 }
793 
795  cerr << "Domain_shell_inner_adapted::integ_term_eq not implemented yet" << endl ;
796  abort() ;
797 }
798 }
799 
reference set(const Index &pos)
Read/write of an element.
Definition: array.hpp:186
Bases_container bases_1d
Arrays containing the various basis of decomposition.
Describes the tensorial basis used by the various tensors.
Definition: base_tensor.hpp:49
int & set_basis(int nd)
Read/write the basis in a given domain.
Definition: base_tensor.hpp:91
Term_eq * der_rad_term_eq
Pointer on the Term_eq containing the .
Definition: adapted.hpp:76
Term_eq flat_grad_spher(const Term_eq &) const
Computes the flat gradient of a field, in orthonormal spherical coordinates.
Term_eq derive_t(const Term_eq &so) const
Computes .
Term_eq derive_p(const Term_eq &so) const
Computes .
virtual Term_eq connection_spher(const Term_eq &) const
Computes the part of the gradient involving the connections, in spherical orthonormal coordinates.
virtual Term_eq integ_volume_term_eq(const Term_eq &) const
Volume integral of a Term_eq.
virtual void update_term_eq(Term_eq *) const
Update the value of a field, after the shape of the Domain has been changed by the system.
virtual Term_eq partial_spher(const Term_eq &) const
Computes the part of the gradient containing the partial derivative of the field, in spherical orthon...
Term_eq * rad_term_eq
Pointer on the Term_eq containing the radius.
Definition: adapted.hpp:72
virtual Term_eq dr_term_eq(const Term_eq &) const
Radial derivative of a Term_eq.
virtual Term_eq der_normal_term_eq(const Term_eq &, int) const
Returns the normal derivative of a Term_eq.
virtual Term_eq lap_term_eq(const Term_eq &, int) const
Returns the flat Laplacian of Term_eq, for a given harmonic.
Term_eq * normal_spher
Pointer on the Term_eq containing the normal vector to the inner boundary, in orthonormal spherical c...
Definition: adapted.hpp:64
void do_normal_cart() const
Computes the normal wrt the inner boundary, in Cartesian coordinates.
virtual Val_domain div_r(const Val_domain &) const
Division by .
const Space & sp
The corresponding Space ; required for updating fields whene the mapping changes.
Definition: adapted.hpp:57
Term_eq * dt_rad_term_eq
Pointer on the Term_eq containing the .
Definition: adapted.hpp:80
virtual Term_eq integ_term_eq(const Term_eq &, int) const
Surface integral of a Term_eq.
virtual Val_domain mult_sin_theta(const Val_domain &) const
Multiplication by .
Term_eq * normal_cart
Pointer on the Term_eq containing the normal vector to the inner boundary, in Cartesian coordinates.
Definition: adapted.hpp:68
virtual Val_domain mult_cos_phi(const Val_domain &) const
Multiplication by .
void do_normal_spher() const
Computes the normal wrt the inner boundary, in orthonormal spherical coordinates.
Term_eq * inner_radius_term_eq
Pointer on the inner boundary , as a Term_eq.
Definition: adapted.hpp:59
virtual const Term_eq * give_normal(int, int) const
Returns the vector normal to a surface.
virtual Val_domain mult_sin_phi(const Val_domain &) const
Multiplication by .
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 Term_eq mult_r_term_eq(const Term_eq &) const
Multiplication by of a Term_eq.
virtual Val_domain mult_cos_theta(const Val_domain &) const
Multiplication by .
Term_eq derive_r(const Term_eq &so) const
Computes .
Term_eq * dp_rad_term_eq
Pointer on the Term_eq containing the .
Definition: adapted.hpp:84
virtual Val_domain mult_sin_theta(const Val_domain &) const
Multiplication by .
Definition: domain.cpp:1236
Term_eq do_comp_by_comp(const Term_eq &so, Val_domain(Domain::*pfunc)(const Val_domain &) const) const
Function used to apply the same operation to all the components of a tensor, in the current domain.
Definition: domain.cpp:283
int num_dom
Number of the current domain (used by the Space)
Definition: space.hpp:63
Dim_array nbr_coefs
Number of coefficients.
Definition: space.hpp:66
virtual Val_domain div_sin_theta(const Val_domain &) const
Division by .
Definition: domain.cpp:1248
Dim_array nbr_points
Number of colocation points.
Definition: space.hpp:65
Memory_mapped_array< Array< double > * > coloc
Colocation points in each dimension (stored in ndim 1d- arrays)
Definition: space.hpp:75
virtual Val_domain mult_cos_theta(const Val_domain &) const
Multiplication by .
Definition: domain.cpp:1224
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
Tensor handling.
Definition: tensor.hpp:149
Memory_mapped_array< Scalar * > cmp
Array of size n_comp of pointers onto the components.
Definition: tensor.hpp:179
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
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 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
void set_der_t(Tensor)
Sets the tensorial variation (only the values in the pertinent Domain are copied).
Definition: term_eq.cpp:171
int get_dom() const
Definition: term_eq.hpp:135
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
bool check_if_zero() const
Check whether the logical state is zero or not.
Definition: val_domain.hpp:142
double & set(const Index &pos)
Read/write the value of the field in the configuration space.
Definition: val_domain.cpp:171
Val_domain div_sin_theta() const
Division by .
Val_domain mult_cos_theta() const
Multiplication by .
Base_spectral & set_base()
Sets the basis of decomposition.
Definition: val_domain.hpp:126
Array< double > get_coef() const
Definition: val_domain.hpp:136
void allocate_conf()
Allocates the values in the configuration space and destroys the values in the coefficients space.
Definition: val_domain.cpp:209
const Base_spectral & get_base() const
Returns the basis of decomposition.
Definition: val_domain.hpp:122
A class derived from Tensor to deal specificaly with objects of valence 1 (and so also 1-forms).
Definition: vector.hpp:41
Scalar & set(int)
Read/write access to a component.