KADATH
domain_nucleus_symphi_affecte_tau.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 "spheric_symphi.hpp"
22 #include "array_math.hpp"
23 #include "scalar.hpp"
24 #include "tensor_impl.hpp"
25 #include "tensor.hpp"
26 namespace Kadath {
27 void Domain_nucleus_symphi::affecte_tau_val_domain (Val_domain& so, const Array<double>& values, int& conte) const {
28 
29  so.allocate_coef() ;
30  *so.cf = 0. ;
31  Index pos_cf (nbr_coefs) ;
32 
33  // Positions of the Galerkin basis
34  Index pos_gal_t (nbr_coefs) ;
35  Index pos_gal_r (nbr_coefs) ;
36  Index pos_gal_rt (nbr_coefs) ;
37  double fact_t, fact_r, fact_rt ;
38 
39 
40  int kmin, kmax ;
41  // Base in phi
42  int basep = (*so.get_base().bases_1d[2]) (0) ;
43  switch (basep) {
44  case COS_EVEN:
45  kmin = 0 ;
46  kmax = nbr_coefs(2)-1 ;
47  break ;
48  case COS_ODD:
49  kmin = 0 ;
50  kmax = nbr_coefs(2)-2 ;
51  break ;
52  case SIN_EVEN:
53  kmin = 1 ;
54  kmax = nbr_coefs(2)-2 ;
55  break ;
56  case SIN_ODD:
57  kmin = 0 ;
58  kmax = nbr_coefs(2)-2 ;
59  break ;
60  default:
61  cerr << "Unknow phi basis in Domain_nucleus_symphi::affecte_tau_val_domain" << endl ;
62  abort() ;
63  }
64 
65 
66 
67  int lquant ;
68  // Loop on phi :
69  for (int k=kmin ; k<=kmax ; k++) {
70 
71  pos_cf.set(2) = k ;
72 
73  int mquant ;
74  switch (basep) {
75  case COS_EVEN:
76  mquant = 2*k ;
77  break ;
78  case COS_ODD:
79  mquant = 2*k+1 ;
80  break ;
81  case SIN_EVEN:
82  mquant = 2*k ;
83  break ;
84  case SIN_ODD:
85  mquant = 2*k+1 ;
86  break ;
87  default:
88  cerr << "Unknow phi basis in Domain_nucleus_symphi::affecte_tau_val_domain" << endl ;
89  abort() ;
90  }
91 
92  // Loop on theta
93  int baset = (*so.get_base().bases_1d[1]) (k) ;
94  for (int j=0 ; j<nbr_coefs(1) ; j++) {
95  int baser = (*so.get_base().bases_1d[0]) (j, k) ;
96  pos_cf.set(1) = j ;
97  // Loop on r :
98  for (int i=0 ; i<nbr_coefs(0) ; i++) {
99  pos_cf.set(0) = i ;
100  switch (baset) {
101  case COS_EVEN :
102  lquant = 2*j ;
103  // No galerkin :
104  if ((mquant==0) && (lquant==0)) {
105  so.cf->set(pos_cf) += values(conte) ;
106  conte ++ ;
107  }
108  else if (mquant==0) {
109  if (i!=0) {
110  // Galerkin base in r only
111  pos_gal_r = pos_cf ;
112  pos_gal_r.set(0) = 0 ;
113  switch (baser) {
114  case CHEB_EVEN :
115  fact_r = - pow(-1, i) ;
116  break ;
117  case LEG_EVEN : {
118  fact_r = -1. ;
119  for (int t=0 ; t<i ; t++)
120  fact_r *= -double(2*t+1)/double(2*t+2) ;
121  }
122  break ;
123  default :
124  cerr << "Strange base in Domain_nucleus_symphi::affecte_tau_val_domain" << endl ;
125  abort() ;
126  }
127 
128  so.cf->set(pos_cf) += values(conte) ;
129  so.cf->set(pos_gal_r) += fact_r*values(conte) ;
130  conte ++ ;
131  }
132  }
133  else if ((j!=0) && (i!=0)) {
134  // Need to use two_dimensional Galerkin basis (aouch !)
135  pos_gal_r = pos_cf ;
136  pos_gal_r.set(0) = 0 ;
137  pos_gal_t = pos_cf ;
138  pos_gal_t.set(1) = 0 ;
139  pos_gal_rt = pos_cf ;
140  pos_gal_rt.set(0) = 0 ;
141  pos_gal_rt.set(1) = 0 ;
142  switch (baser) {
143  case CHEB_EVEN :
144  fact_r = -pow(-1, i) ;
145  fact_t = -1. ;
146  fact_rt = pow(-1, i) ;
147  break ;
148  case LEG_EVEN : {
149  double l0 = 1 ;
150  for (int t=0 ; t<i ; t++)
151  l0 *= -double(2*t+1)/double(2*t+2) ;
152  fact_r = - l0 ;
153  fact_t = -1. ;
154  fact_rt = l0 ;
155  }
156  break ;
157  default :
158  cerr << "Strange base in Domain_nucleus_symphi::affecte_tau_val_domain" << endl ;
159  abort() ;
160  }
161  so.cf->set(pos_cf) += values(conte) ;
162  so.cf->set(pos_gal_r) += fact_r*values(conte) ;
163  so.cf->set(pos_gal_t) += fact_t*values(conte) ;
164  so.cf->set(pos_gal_rt) += fact_rt*values(conte) ;
165  conte ++ ;
166  }
167  break ;
168  case COS_ODD:
169  lquant = 2*j+1 ;
170  if ((j!=nbr_coefs(1)-1) && (i!=nbr_coefs(0)-1)) {
171  if ((k==0) && (lquant<=1)) {
172  so.cf->set(pos_cf) += values(conte) ;
173  conte ++ ;
174  }
175  else {
176  if ((mquant==0) && (i!=0)) {
177  pos_gal_r = pos_cf ;
178  pos_gal_r.set(0) = 0 ;
179  switch (baser) {
180  case CHEB_ODD :
181  fact_r = - (2*i+1) * pow(-1, i) ;
182  break ;
183  case LEG_ODD : {
184  fact_r = -1. ;
185  for (int t=0 ; t<i ; t++)
186  fact_r *= -double(2*t+3)/double(2*t+2) ;
187  }
188  break ;
189  default :
190  cerr << "Strange base in Domain_nucleus_symphi::affecte_tau_val_domain" << endl ;
191  abort() ;
192  }
193  so.cf->set(pos_cf) += values(conte) ;
194  so.cf->set(pos_gal_r) += fact_r*values(conte) ;
195  conte ++ ;
196  }
197  else if ((j!=0) && (i!=0)) {
198  // Need to use two_dimensional Galerkin basis (aouch !)
199  pos_gal_r = pos_cf ;
200  pos_gal_r.set(0) = 0 ;
201  pos_gal_t = pos_cf ;
202  pos_gal_t.set(1) = 0 ;
203  pos_gal_rt = pos_cf ;
204  pos_gal_rt.set(0) = 0 ;
205  pos_gal_rt.set(1) = 0 ;
206  switch (baser) {
207  case CHEB_ODD :
208  fact_r = -pow(-1, i)*(2*i+1) ;
209  fact_t = -1. ;
210  fact_rt = pow(-1, i)*(2*i+1) ;
211  break ;
212  case LEG_ODD : {
213  double l0 = 1 ;
214  for (int t=0 ; t<i ; t++)
215  l0 *= -double(2*t+3)/double(2*t+2) ;
216  fact_r = - l0 ;
217  fact_t = -1. ;
218  fact_rt = l0 ;
219  }
220  break ;
221  default :
222  cerr << "Strange base in Domain_nucleus_symphi::affecte_tau_val_domain" << endl ;
223  abort() ;
224  }
225  so.cf->set(pos_cf) += values(conte) ;
226  so.cf->set(pos_gal_r) += fact_r*values(conte) ;
227  so.cf->set(pos_gal_t) += fact_t*values(conte) ;
228  so.cf->set(pos_gal_rt) += fact_rt*values(conte) ;
229  conte ++ ;
230  }
231  }
232  }
233  break ;
234  case SIN_EVEN:
235  lquant = 2*j ;
236  if ((j!=0) && (j!=nbr_coefs(1)-1)) {
237  if ((mquant<=1) && (lquant==0)) {
238  so.cf->set(pos_cf) += values(conte) ;
239  conte ++ ;
240  }
241  else {
242  if ((mquant<=1) && (i!=0)) {
243  // Galerkin base in r only
244  pos_gal_r = pos_cf ;
245  pos_gal_r.set(0) = 0 ;
246  switch (baser) {
247  case CHEB_EVEN :
248  fact_r = - pow(-1, i) ;
249  break ;
250  case LEG_EVEN : {
251  fact_r = -1. ;
252  for (int t=0 ; t<i ; t++)
253  fact_r *= -double(2*t+1)/double(2*t+2) ;
254  }
255  break ;
256  default :
257  cerr << "Strange base in Domain_nucleus_symphi::affecte_tau_val_domain" << endl ;
258  abort() ;
259  }
260  so.cf->set(pos_cf) += values(conte) ;
261  so.cf->set(pos_gal_r) += fact_r*values(conte) ;
262  conte ++ ;
263  }
264 
265  else //Double Galerkin
266  if ((j!=1) && (i!=0)) {
267  // Need to use two_dimensional Galerkin basis (aouch !)
268  pos_gal_r = pos_cf ;
269  pos_gal_r.set(0) = 0 ;
270  pos_gal_t = pos_cf ;
271  pos_gal_t.set(1) = 1 ;
272  pos_gal_rt = pos_cf ;
273  pos_gal_rt.set(0) = 0 ;
274  pos_gal_rt.set(1) = 1 ;
275  switch (baser) {
276  case CHEB_EVEN :
277  fact_r = -pow(-1, i) ;
278  fact_t = -j ;
279  fact_rt = pow(-1, i)*j ;
280  break ;
281  case LEG_EVEN : {
282  double l0 = 1 ;
283  for (int t=0 ; t<i ; t++)
284  l0 *= -double(2*t+1)/double(2*t+2) ;
285  fact_r = - l0 ;
286  fact_t = -j ;
287  fact_rt = l0*j ;
288  }
289  break ;
290  default :
291  cerr << "Strange base in Domain_nucleus_symphi::affecte_tau_val_domain" << endl ;
292  abort() ;
293  }
294  so.cf->set(pos_cf) += values(conte) ;
295  so.cf->set(pos_gal_r) += fact_r*values(conte) ;
296  so.cf->set(pos_gal_t) += fact_t*values(conte) ;
297  so.cf->set(pos_gal_rt) += fact_rt*values(conte) ;
298  conte ++ ;
299  }
300  }
301  }
302 
303  break ;
304  case SIN_ODD:
305  lquant = 2*j+1 ;
306  if ((j!=nbr_coefs(1)-1) && (i!=nbr_coefs(0)-1)) {
307  if ((mquant<=1) && (lquant<=1)) {
308  so.cf->set(pos_cf) += values(conte) ;
309  conte ++ ;
310  }
311  else {
312  if ((mquant<=1) && (i!=0)) {
313  pos_gal_r = pos_cf ;
314  pos_gal_r.set(0) = 0 ;
315  switch (baser) {
316  case CHEB_ODD :
317  fact_r = - (2*i+1) * pow(-1, i) ;
318  break ;
319  case LEG_ODD : {
320  fact_r = -1. ;
321  for (int t=0 ; t<i ; t++)
322  fact_r *= -double(2*t+3)/double(2*t+2) ;
323  }
324  break ;
325  default :
326  cerr << "Strange base in Domain_nucleus_symphi::affecte_tau_val_domain" << endl ;
327  abort() ;
328  }
329  so.cf->set(pos_cf) += values(conte) ;
330  so.cf->set(pos_gal_r) += fact_r*values(conte) ;
331  conte ++ ;
332  }
333  else if ((j!=0) && (i!=0)) {
334  // Need to use two_dimensional Galerkin basis (aouch !)
335  pos_gal_r = pos_cf ;
336  pos_gal_r.set(0) = 0 ;
337  pos_gal_t = pos_cf ;
338  pos_gal_t.set(1) = 0 ;
339  pos_gal_rt = pos_cf ;
340  pos_gal_rt.set(0) = 0 ;
341  pos_gal_rt.set(1) = 0 ;
342  switch (baser) {
343  case CHEB_ODD :
344  fact_r = -pow(-1, i)*(2*i+1) ;
345  fact_t = -(2*j+1) ;
346  fact_rt = pow(-1, i)*(2*i+1)*(2*j+1) ;
347  break ;
348  case LEG_ODD : {
349  double l0 = 1 ;
350  for (int t=0 ; t<i ; t++)
351  l0 *= -double(2*t+3)/double(2*t+2) ;
352  fact_r = - l0 ;
353  fact_t = -(2*j+1) ;
354  fact_rt = l0*(2*j+1) ;
355  }
356  break ;
357  default :
358  cerr << "Strange base in Domain_nucleus_symphi::affecte_tau_val_domain" << endl ;
359  abort() ;
360  }
361  so.cf->set(pos_cf) += values(conte) ;
362  so.cf->set(pos_gal_r) += fact_r*values(conte) ;
363  so.cf->set(pos_gal_t) += fact_t*values(conte) ;
364  so.cf->set(pos_gal_rt) += fact_rt*values(conte) ;
365  conte ++ ;
366  }
367  }
368  }
369  break ;
370  default:
371  cerr << "Unknow theta basis in Domain_nucleus_symphi::affecte_tau_val_domain" << endl ;
372  abort() ;
373  }
374  }
375  }
376  }
377 }
378 
379 void Domain_nucleus_symphi::affecte_tau (Tensor& tt, int dom, const Array<double>& cf, int& pos_cf) const {
380 
381  // Check right domain
382  assert (tt.get_space().get_domain(dom)==this) ;
383 
384  int val = tt.get_valence() ;
385  switch (val) {
386  case 0 :
387  affecte_tau_val_domain (tt.set().set_domain(dom), cf, pos_cf) ;
388  break ;
389  case 1 : {
390  bool found = false ;
391  // Cartesian basis
392  if (tt.get_basis().get_basis(dom)==CARTESIAN_BASIS) {
393  affecte_tau_val_domain (tt.set(1).set_domain(dom), cf, pos_cf) ;
394  affecte_tau_val_domain (tt.set(2).set_domain(dom), cf, pos_cf) ;
395  affecte_tau_val_domain (tt.set(3).set_domain(dom), cf, pos_cf) ;
396  found = true ;
397  }
398 
399  if (!found) {
400  cerr << "Unknown type of vector Domain_nucleus_symphi::affecte_tau" << endl ;
401  abort() ;
402  }
403  }
404  break ;
405  case 2 : {
406  bool found = false ;
407  // Cartesian basis and symetric
408  if ((tt.get_basis().get_basis(dom)==CARTESIAN_BASIS) && (tt.get_n_comp()==6)) {
409  affecte_tau_val_domain (tt.set(1,1).set_domain(dom), cf, pos_cf) ;
410  affecte_tau_val_domain (tt.set(1,2).set_domain(dom), cf, pos_cf) ;
411  affecte_tau_val_domain (tt.set(1,3).set_domain(dom), cf, pos_cf) ;
412  affecte_tau_val_domain (tt.set(2,2).set_domain(dom), cf, pos_cf) ;
413  affecte_tau_val_domain (tt.set(2,3).set_domain(dom), cf, pos_cf) ;
414  affecte_tau_val_domain (tt.set(3,3).set_domain(dom), cf, pos_cf) ;
415  found = true ;
416  }
417  // Cartesian basis and not symetric
418  if ((tt.get_basis().get_basis(dom)==CARTESIAN_BASIS) && (tt.get_n_comp()==9)) {
419  affecte_tau_val_domain (tt.set(1,1).set_domain(dom), cf, pos_cf) ;
420  affecte_tau_val_domain (tt.set(1,2).set_domain(dom), cf, pos_cf) ;
421  affecte_tau_val_domain (tt.set(1,3).set_domain(dom), cf, pos_cf) ;
422  affecte_tau_val_domain (tt.set(2,1).set_domain(dom), cf, pos_cf) ;
423  affecte_tau_val_domain (tt.set(2,2).set_domain(dom), cf, pos_cf) ;
424  affecte_tau_val_domain (tt.set(2,3).set_domain(dom), cf, pos_cf) ;
425  affecte_tau_val_domain (tt.set(3,1).set_domain(dom), cf, pos_cf) ;
426  affecte_tau_val_domain (tt.set(3,2).set_domain(dom), cf, pos_cf) ;
427  affecte_tau_val_domain (tt.set(3,3).set_domain(dom), cf, pos_cf) ;
428  found = true ;
429  }
430  if (!found) {
431  cerr << "Unknown type of 2-tensor Domain_nucleus_symphi::affecte_tau" << endl ;
432  abort() ;
433  }
434  }
435  break ;
436  default :
437  cerr << "Valence " << val << " not implemented in Domain_nucleus_symphi::affecte_tau" << endl ;
438  break ;
439  }
440 }}
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.
int get_basis(int nd) const
Read only the basis in a given domain.
Definition: base_tensor.hpp:93
void affecte_tau_val_domain(Val_domain &so, const Array< double > &cf, int &pos_cf) const
Affects some coefficients to a Val_domain.
virtual void affecte_tau(Tensor &, int, const Array< double > &, int &) const
Affects some coefficients to a Tensor.
Dim_array nbr_coefs
Number of coefficients.
Definition: space.hpp:66
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
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
Tensor handling.
Definition: tensor.hpp:149
Scalar & set(const Array< int > &ind)
Returns the value of a component (read/write version).
Definition: tensor_impl.hpp:91
const Base_tensor & get_basis() const
Returns the vectorial basis (triad) on which the components are defined.
Definition: tensor.hpp:504
int get_n_comp() const
Returns the number of stored components.
Definition: tensor.hpp:514
int get_valence() const
Returns the valence.
Definition: tensor.hpp:509
const Space & get_space() const
Returns the Space.
Definition: tensor.hpp:499
Class for storing the basis of decompositions of a field and its values on both the configuration and...
Definition: val_domain.hpp:69
void allocate_coef()
Allocates the values in the coefficient space and destroys the values in the configuration space.
Definition: val_domain.cpp:216
Array< double > * cf
Pointer on the Array of the values in the coefficients space.
Definition: val_domain.hpp:77
const Base_spectral & get_base() const
Returns the basis of decomposition.
Definition: val_domain.hpp:122