KADATH
domain_polar_periodic_nucleus.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 "polar_periodic.hpp"
23 #include "point.hpp"
24 #include "array_math.hpp"
25 #include "val_domain.hpp"
26 #include "term_eq.hpp"
27 #include "scalar.hpp"
28 #include "tensor_impl.hpp"
29 
30 namespace Kadath {
31 void coef_1d (int, Array<double>&) ;
32 void coef_i_1d (int, Array<double>&) ;
33 int der_1d (int, Array<double>&) ;
34 
35 // Standard constructor
36 Domain_polar_periodic_nucleus::Domain_polar_periodic_nucleus (int num, int ttype, double r, double oome, const Dim_array& nbr) :
37  Domain(num, ttype, nbr), alpha(r), ome(oome), type_time(TO_PI) {
38  assert (nbr.get_ndim()==3) ;
39  switch (type_time) {
40  case TO_PI :
41  maxt = M_PI ;
42  break ;
43  default:
44  cerr << "Unknown case for type_time" << endl ;
45  abort() ;
46  }
47 
48  do_coloc() ;
49  // ome_term_eq = 0x0 ;
50 
51  ome_term_eq = new Term_eq (num_dom, ome) ;
52  ome_term_eq->set_der_d(0.) ;
53 }
54 
55 // Constructor by copy
57  type_time(so.type_time), maxt(so.maxt) {
58 
59  //ome_term_eq = 0x0 ;
60 
61  ome_term_eq = new Term_eq (num_dom, ome) ;
62  ome_term_eq->set_der_d(0.) ;
63 }
64 
66  fread_be (&alpha, sizeof(double), 1, fd) ;
67  fread_be (&ome, sizeof(double), 1, fd) ;
68  fread_be (&type_time, sizeof(int), 1, fd) ;
69  switch (type_time) {
70  case TO_PI :
71  maxt = M_PI ;
72  break ;
73  default:
74  cerr << "Unknown case for type_time" << endl ;
75  abort() ;
76  }
77  do_coloc() ;
78 
79  ome_term_eq = new Term_eq (num_dom, ome) ;
80  ome_term_eq->set_der_d(0.) ;
81 }
82 
83 // Destructor
84 Domain_polar_periodic_nucleus::~Domain_polar_periodic_nucleus() {
85  if (ome_term_eq!=0x0)
86  delete ome_term_eq ;
87 }
88 
89 void Domain_polar_periodic_nucleus::save (FILE* fd) const {
90  nbr_points.save(fd) ;
91  nbr_coefs.save(fd) ;
92  fwrite_be (&ndim, sizeof(int), 1, fd) ;
93  fwrite_be (&type_base, sizeof(int), 1, fd) ;
94  fwrite_be (&alpha, sizeof(double), 1, fd) ;
95  fwrite_be (&ome, sizeof(double), 1, fd) ;
96  fwrite_be (&type_time, sizeof(int), 1, fd) ;
97 }
98 
99 ostream& Domain_polar_periodic_nucleus::print (ostream& o) const {
100  o << "Polar_periodic nucleus" << endl ;
101  o << "time goes to " << maxt << endl ;
102  o << "Rmax = " << alpha << endl ;
103  o << "Omega = " << ome << endl ;
104  o << "Nbr pts = " << nbr_points << endl ;
105  o << endl ;
106  return o ;
107 }
108 
109 
110 /*int Domain_polar_periodic_nucleus::nbr_unknowns_from_adapted() const {
111  return 1 ;
112 }
113 
114 
115 void Domain_polar_periodic_nucleus::vars_to_terms() const {
116 
117  if (ome_term_eq != 0x0)
118  delete ome_term_eq ;
119 
120  ome_term_eq = new Term_eq (num_dom, ome) ;
121  update() ;
122 }
123 
124 void Domain_polar_periodic_nucleus::affecte_coef(int& conte, int cc, bool& found) const {
125  if (conte==cc) {
126  ome_term_eq->set_der_d(1.) ;
127  found = true ;
128  }
129  else {
130  ome_term_eq->set_der_d(0.) ;
131  found = false ;
132  }
133  conte ++ ;
134  update() ;
135 }
136 
137 void Domain_polar_periodic_nucleus::xx_to_vars_from_adapted(double new_ome, const Array<double>& xx, int& pos) const {
138 
139  new_ome -= xx(pos) ;
140  pos ++ ;
141 }
142 
143 void Domain_polar_periodic_nucleus::update_mapping (double cor) {
144 
145  ome += cor ;
146  for (int l=0 ; l<ndim ; l++) {
147  if (absol[l] !=0x0) delete absol[l] ;
148  if (cart[l] !=0x0) delete cart[l] ;
149  if (cart_surr[l] !=0x0) delete cart_surr[l] ;
150  absol[l] = 0x0 ;
151  cart_surr[l] = 0x0 ;
152  cart[l]= 0x0 ;
153  }
154  if (radius !=0x0)
155  delete radius ;
156  radius = 0x0 ;
157  update() ;
158 }
159 
160 void Domain_polar_periodic_nucleus::update_variable (double cor_ome, const Scalar& old, Scalar& res) const {
161  Val_domain cor (-cor_ome * old(num_dom).der_abs(3) / ome) ;
162  res.set_domain(num_dom) = cor + old(num_dom) ;
163  res.set_domain(num_dom).set_base() = old(num_dom).get_base() ;
164 }
165 
166 
167 void Domain_polar_periodic_nucleus::update_constante (double cor_ome, const Scalar& old, Scalar& res) const {
168 
169  Point MM(3) ;
170  Index pos(nbr_points) ;
171  res.set_domain(num_dom).allocate_conf() ;
172  do {
173 
174  MM.set(1) = (*absol[0])(pos) ;
175  MM.set(2) = (*absol[1])(pos) ;
176  MM.set(3) = (*coloc[2])(pos)/(ome+cor_ome) ;
177 
178  res.set_domain(num_dom).set(pos) = old.val_point(MM, +1) ;
179 
180  }
181  while (pos.inc()) ;
182 
183  res.set_domain(num_dom).set_base() = old(num_dom).get_base() ;
184 }
185 
186 
187 
188 void Domain_polar_periodic_nucleus::update_term_eq (Term_eq* so) const {
189 
190  Tensor der (*so->val_t, false) ;
191  for (int cmp=0 ; cmp<so->val_t->get_n_comp() ; cmp ++) {
192 
193 
194 
195  Val_domain dert ((*(*so->val_t).cmp[cmp])(num_dom).der_abs(3)) ;
196 
197  if (!dert.check_if_zero()) {
198  Val_domain res(this) ;
199  res.allocate_conf() ;
200  Index pos (nbr_points) ;
201  do {
202  res.set(pos) = (*ome_term_eq->der_d) * (*coloc[2])(pos(2)) * dert(pos) ;
203  }
204  while (pos.inc()) ;
205  res.set_base() = (*(*so->val_t).cmp[cmp])(num_dom).get_base() ;
206  der.cmp[cmp]->set_domain(num_dom) = res ;
207  }
208  else
209  der.cmp[cmp]->set_domain(num_dom).set_zero() ;
210  }
211 
212  so->set_der_t (der) ;
213 }
214 
215 void Domain_polar_periodic_nucleus::xx_to_ders_from_adapted(const Array<double>& xx, int& pos) const {
216  ome_term_eq->set_der_d(xx(pos)) ;
217  pos++ ;
218  update() ;
219 }
220 
221 
222 void Domain_polar_periodic_nucleus::update() const {
223  ome_term_eq->set_val_d(ome) ;
224 }
225 */
227 
228  Val_domain res (so.der_var(1)) ;
229  switch (bound) {
230  case OUTER_BC :
231  res /= alpha ;
232  break ;
233  default:
234  cerr << "Unknown boundary case in Domain_polar_periodic_nucleus::der_normal" << endl ;
235  abort() ;
236  }
237 return res ;
238 }
239 
240 // Computes the cartesian coordinates
242  for (int i=0 ; i<3 ; i++)
243  assert (coloc[i] != 0x0) ;
244  for (int i=0 ; i<3 ; i++)
245  assert (absol[i] == 0x0) ;
246  for (int i=0 ; i<3 ; i++) {
247  absol[i] = new Val_domain(this) ;
248  absol[i]->allocate_conf() ;
249  }
250  Index index (nbr_points) ;
251  do {
252  absol[0]->set(index) = alpha* ((*coloc[0])(index(0))) *sin((*coloc[1])(index(1))) ; // rho
253  absol[1]->set(index) = alpha* ((*coloc[0])(index(0))) *cos((*coloc[1])(index(1))) ; // z
254  absol[2]->set(index) = (*coloc[2])(index(2)) / ome ; // time
255  }
256  while (index.inc()) ;
257 
258 }
259 
260 // Computes the radius
262 
263  for (int i=0 ; i<2 ; i++)
264  assert (coloc[i] != 0x0) ;
265  assert (radius == 0x0) ;
266  radius = new Val_domain(this) ;
267  radius->allocate_conf() ;
268  Index index (nbr_points) ;
269  do
270  radius->set(index) = alpha* ((*coloc[0])(index(0))) ;
271  while (index.inc()) ;
272 }
273 
274 
275 // Is a point inside this domain ?
276 bool Domain_polar_periodic_nucleus::is_in (const Point& xx, double prec) const {
277 
278  assert (xx.get_ndim()==3) ;
279 
280  double rho_loc = xx(1) ;
281  double z_loc = xx(2) ;
282  double air_loc = sqrt (rho_loc*rho_loc + z_loc*z_loc) ;
283 
284  bool res = (air_loc <= alpha+prec) ? true : false ;
285 
286  if ((xx(3)<0-prec) || (xx(3)>maxt/ome + prec))
287  res = false ;
288 
289  return res ;
290 }
291 
292 // Convert absolute coordinates to numerical ones
294 
295  assert (is_in(abs)) ;
296  Point num(3) ;
297  double rho_loc = fabs(abs(1)) ;
298  double z_loc = abs(2) ;
299  double air = sqrt(rho_loc*rho_loc+z_loc*z_loc) ;
300  num.set(1) = air/alpha ;
301 
302  if (rho_loc==0) {
303  // Sur l'axe
304  num.set(2) = (z_loc>=0) ? 0 : M_PI ;
305  }
306  else {
307  num.set(2) = atan(rho_loc/z_loc) ;
308  }
309 
310  if (num(2) <0)
311  num.set(2) = M_PI + num(2) ;
312 
313  num.set(3) = abs(3)*ome ;
314 
315  return num ;
316 }
317 
318 double coloc_leg_parity(int, int) ;
320 
321  switch (type_base) {
322  case CHEB_TYPE:
324  del_deriv() ;
325  for (int i=0 ; i<ndim ; i++)
326  coloc[i] = new Array<double> (nbr_points(i)) ;
327  for (int i=0 ; i<nbr_points(0) ; i++)
328  coloc[0]->set(i) = sin(M_PI/2.*i/(nbr_points(0)-1)) ;
329  for (int j=0 ; j<nbr_points(1) ; j++)
330  coloc[1]->set(j) = M_PI/2.*j/(nbr_points(1)-1) ;
331  for (int k=0 ; k<nbr_points(2) ; k++)
332  coloc[2]->set(k) = maxt*k/(nbr_points(2)-1) ;
333  break ;
334  case LEG_TYPE:
336  del_deriv() ;
337  for (int i=0 ; i<ndim ; i++)
338  coloc[i] = new Array<double> (nbr_points(i)) ;
339  for (int i=0 ; i<nbr_points(0) ; i++)
340  coloc[0]->set(i) = coloc_leg_parity(i, nbr_points(0)) ;
341  for (int j=0 ; j<nbr_points(1) ; j++)
342  coloc[1]->set(j) = M_PI/2.*j/(nbr_points(1)-1) ;
343  for (int k=0 ; k<nbr_points(2) ; k++)
344  coloc[2]->set(k) = maxt*k/(nbr_points(2)-1) ;
345  break ;
346  default :
347  cerr << "Unknown type of basis in Domain_polar_periodic_nucleus::do_coloc" << endl ;
348  abort() ;
349  }
350 }
351 // Base for a function symetric in z, using Chebyshev
353  set_cheb_base_with_m (base, 0) ;
354 }
355 
356 // Base for a function anti-symetric in z, using Chebyshev
358  set_anti_cheb_base_with_m(base, 0) ;
359 }
360 
361 // Base for a function symetric in z, using Legendre
363  set_legendre_base_with_m(base, 0) ;
364  }
365 
366 // Base for a function anti-symetric in z, using Legendre
369  }
370 
371 // Base for a function symetric in z, using Chebyshev
373 
374  int l ;
375 
376  assert (type_base == CHEB_TYPE) ;
377  base.allocate(nbr_coefs) ;
378  base.def=true ;
379  Index index(base.bases_1d[0]->get_dimensions()) ;
380 
381  base.bases_1d[2]->set(0) = COS ; // Base in time
382  for (int k=0 ; k<nbr_coefs(2) ; k++) {
383  base.bases_1d[1]->set(k) = (m%2==0) ? COS_EVEN : SIN_ODD ;
384  for (int j=0 ; j<nbr_coefs(1) ; j++) {
385  l = (m%2==0) ? 2*j : 2*j+1 ;
386  index.set(0) = j ; index.set(1) = k ;
387  base.bases_1d[0]->set(index) = (l%2==0) ? CHEB_EVEN : CHEB_ODD ;
388  }
389  }
390 }
391 
392 // Base for a function anti-symetric in z, using Chebyshev
394 
395  int l ;
396 
397  assert (type_base == CHEB_TYPE) ;
398  base.allocate(nbr_coefs) ;
399 
400  Index index(base.bases_1d[0]->get_dimensions()) ;
401 
402  base.def=true ;
403 
404 
405  base.bases_1d[2]->set(0) = COS ; // Base in time
406  for (int k=0 ; k<nbr_coefs(2) ; k++) {
407  base.bases_1d[1]->set(k) = (m%2==0) ? COS_ODD : SIN_EVEN ;
408  for (int j=0 ; j<nbr_coefs(1) ; j++) {
409  l = (m%2==0) ? 2*j+1 : 2*j ;
410  index.set(0) = j ; index.set(1) = k ;
411  base.bases_1d[0]->set(index) = (l%2==1) ? CHEB_ODD : CHEB_EVEN ;
412  }
413  }
414 }
415 
416 // Base for a function symetric in z, using Legendre
418 
419  int l ;
420 
421  assert (type_base == LEG_TYPE) ;
422  base.allocate(nbr_coefs) ;
423  base.def=true ;
424  Index index(base.bases_1d[0]->get_dimensions()) ;
425 
426  base.bases_1d[2]->set(0) = COS ; // Base in time
427  for (int k=0 ; k<nbr_coefs(2) ; k++) {
428  base.bases_1d[1]->set(k) = (m%2==0) ? COS_EVEN : SIN_ODD ;
429  for (int j=0 ; j<nbr_coefs(1) ; j++) {
430  l = (m%2==0) ? 2*j : 2*j+1 ;
431  index.set(0) = j ; index.set(1) = k ;
432  base.bases_1d[0]->set(index) = (l%2==0) ? LEG_EVEN : LEG_ODD ;
433  }
434  }
435 }
436 
437 // Base for a function anti-symetric in z, using Chebyshev
439 
440  int l ;
441 
442  assert (type_base == LEG_TYPE) ;
443  base.allocate(nbr_coefs) ;
444 
445  Index index(base.bases_1d[0]->get_dimensions()) ;
446 
447  base.def=true ;
448 
449 
450  base.bases_1d[2]->set(0) = COS ; // Base in time
451  for (int k=0 ; k<nbr_coefs(2) ; k++) {
452  base.bases_1d[1]->set(k) = (m%2==0) ? COS_ODD : SIN_EVEN ;
453  for (int j=0 ; j<nbr_coefs(1) ; j++) {
454  l = (m%2==0) ? 2*j+1 : 2*j ;
455  index.set(0) = j ; index.set(1) = k ;
456  base.bases_1d[0]->set(index) = (l%2==1) ? LEG_ODD : LEG_EVEN ;
457  }
458  }
459 }
460 
462 
463  assert (type_base == CHEB_TYPE) ;
464  base.allocate(nbr_coefs) ;
465 
466  Index index(base.bases_1d[0]->get_dimensions()) ;
467 
468  base.def=true ;
469  base.bases_1d[2]->set(0) = SIN ;
470  for (int k=0 ; k<nbr_coefs(2) ; k++) {
471  base.bases_1d[1]->set(k) = COS_EVEN ;
472  for (int j=0 ; j<nbr_coefs(1) ; j++) {
473  index.set(0) = j ; index.set(1) = k ;
474  base.bases_1d[0]->set(index) = CHEB_ODD ;
475  }
476  }
477 }
478 
480 
481  assert (type_base == CHEB_TYPE) ;
482  base.allocate(nbr_coefs) ;
483 
484  Index index(base.bases_1d[0]->get_dimensions()) ;
485 
486  base.def=true ;
487  base.bases_1d[2]->set(0) = SIN ;
488  for (int k=0 ; k<nbr_coefs(2) ; k++) {
489  base.bases_1d[1]->set(k) = SIN_EVEN ;
490  for (int j=0 ; j<nbr_coefs(1) ; j++) {
491  index.set(0) = j ; index.set(1) = k ;
492  base.bases_1d[0]->set(index) = CHEB_ODD ;
493  }
494  }
495 }
496 
498 
499  assert (type_base == CHEB_TYPE) ;
500  base.allocate(nbr_coefs) ;
501 
502  Index index(base.bases_1d[0]->get_dimensions()) ;
503 
504  base.def=true ;
505  base.bases_1d[2]->set(0) = SIN ;
506  for (int k=0 ; k<nbr_coefs(2) ; k++) {
507  base.bases_1d[1]->set(k) = SIN_ODD ;
508  for (int j=0 ; j<nbr_coefs(1) ; j++) {
509  index.set(0) = j ; index.set(1) = k ;
510  base.bases_1d[0]->set(index) = CHEB_ODD ;
511  }
512  }
513 }
514 
516 
517  assert (type_base == LEG_TYPE) ;
518  base.allocate(nbr_coefs) ;
519 
520  Index index(base.bases_1d[0]->get_dimensions()) ;
521 
522  base.def=true ;
523  base.bases_1d[2]->set(0) = SIN ;
524  for (int k=0 ; k<nbr_coefs(2) ; k++) {
525  base.bases_1d[1]->set(k) = COS_EVEN ;
526  for (int j=0 ; j<nbr_coefs(1) ; j++) {
527  index.set(0) = j ; index.set(1) = k ;
528  base.bases_1d[0]->set(index) = LEG_ODD ;
529  }
530  }
531 }
532 
534 
535  assert (type_base == LEG_TYPE) ;
536  base.allocate(nbr_coefs) ;
537 
538  Index index(base.bases_1d[0]->get_dimensions()) ;
539 
540  base.def=true ;
541  base.bases_1d[2]->set(0) = SIN ;
542  for (int k=0 ; k<nbr_coefs(2) ; k++) {
543  base.bases_1d[1]->set(k) = SIN_EVEN ;
544  for (int j=0 ; j<nbr_coefs(1) ; j++) {
545  index.set(0) = j ; index.set(1) = k ;
546  base.bases_1d[0]->set(index) = LEG_ODD ;
547  }
548  }
549 }
550 
552 
553  assert (type_base == CHEB_TYPE) ;
554  base.allocate(nbr_coefs) ;
555 
556  Index index(base.bases_1d[0]->get_dimensions()) ;
557 
558  base.def=true ;
559  base.bases_1d[2]->set(0) = SIN ;
560  for (int k=0 ; k<nbr_coefs(2) ; k++) {
561  base.bases_1d[1]->set(k) = SIN_ODD ;
562  for (int j=0 ; j<nbr_coefs(1) ; j++) {
563  index.set(0) = j ; index.set(1) = k ;
564  base.bases_1d[0]->set(index) = LEG_ODD ;
565  }
566  }
567 }
568 
569 // Computes the derivatives with respect to rho,Z as a function of the numerical ones.
570 void Domain_polar_periodic_nucleus::do_der_abs_from_der_var(const Val_domain *const *const der_var, Val_domain **const der_abs) const {
571  Val_domain dr (*der_var[0]/alpha) ;
572  Val_domain dtsr (der_var[1]->div_x()/alpha) ;
573 
574  // D / drho
575  der_abs[0] = new Val_domain (dr.mult_sin_theta() + dtsr.mult_cos_theta()) ;
576  // d/dz :
577  der_abs[1] = new Val_domain (dr.mult_cos_theta() - dtsr.mult_sin_theta()) ;
578  // d/dt :
579  der_abs[2] = new Val_domain (*der_var[2]*ome) ;
580 }
581 
582 // Rules for the multiplication of two basis.
584 
585  assert (a.ndim==3) ;
586  assert (b.ndim==3) ;
587 
588  Base_spectral res(3) ;
589  bool res_def = true ;
590 
591  if (!a.def)
592  res_def=false ;
593  if (!b.def)
594  res_def=false ;
595 
596  if (res_def) {
597 
598 
599  // Bases in time :
600  res.bases_1d[2] = new Array<int> (a.bases_1d[2]->get_dimensions()) ;
601  switch ((*a.bases_1d[2])(0)) {
602  case COS:
603  switch ((*b.bases_1d[2])(0)) {
604  case COS:
605  res.bases_1d[2]->set(0) = COS ;
606  break ;
607  case SIN:
608  res.bases_1d[2]->set(0) = SIN ;
609  break ;
610  default:
611  res_def = false ;
612  break ;
613  }
614  break ;
615  case SIN:
616  switch ((*b.bases_1d[2])(0)) {
617  case COS:
618  res.bases_1d[2]->set(0) = SIN ;
619  break ;
620  case SIN:
621  res.bases_1d[2]->set(0) = COS ;
622  break ;
623  default:
624  res_def = false ;
625  break ;
626  }
627  break ;
628  }
629 
630  // Bases in theta :
631  Index index_1 (a.bases_1d[1]->get_dimensions()) ;
632  res.bases_1d[1] = new Array<int> (a.bases_1d[1]->get_dimensions()) ;
633  do {
634  switch ((*a.bases_1d[1])(index_1)) {
635  case COS_EVEN:
636  switch ((*b.bases_1d[1])(index_1)) {
637  case COS_EVEN:
638  res.bases_1d[1]->set(index_1) = COS_EVEN ;
639  break ;
640  case COS_ODD:
641  res.bases_1d[1]->set(index_1) = COS_ODD ;
642  break ;
643  case SIN_EVEN:
644  res.bases_1d[1]->set(index_1) = SIN_EVEN ;
645  break ;
646  case SIN_ODD:
647  res.bases_1d[1]->set(index_1) = SIN_ODD ;
648  break ;
649  default:
650  res_def = false ;
651  break ;
652  }
653  break ;
654  case COS_ODD:
655  switch ((*b.bases_1d[1])(index_1)) {
656  case COS_EVEN:
657  res.bases_1d[1]->set(index_1) = COS_ODD ;
658  break ;
659  case COS_ODD:
660  res.bases_1d[1]->set(index_1) = COS_EVEN ;
661  break ;
662  case SIN_EVEN:
663  res.bases_1d[1]->set(index_1) = SIN_ODD ;
664  break ;
665  case SIN_ODD:
666  res.bases_1d[1]->set(index_1) = SIN_EVEN ;
667  break ;
668  default:
669  res_def = false ;
670  break ;
671  }
672  break ;
673  case SIN_EVEN:
674  switch ((*b.bases_1d[1])(index_1)) {
675  case COS_EVEN:
676  res.bases_1d[1]->set(index_1) = SIN_EVEN ;
677  break ;
678  case COS_ODD:
679  res.bases_1d[1]->set(index_1) = SIN_ODD ;
680  break ;
681  case SIN_EVEN:
682  res.bases_1d[1]->set(index_1) = COS_EVEN ;
683  break ;
684  case SIN_ODD:
685  res.bases_1d[1]->set(index_1) = COS_ODD ;
686  break ;
687  default:
688  res_def = false ;
689  break ;
690  }
691  break ;
692  case SIN_ODD:
693  switch ((*b.bases_1d[1])(index_1)) {
694  case COS_EVEN:
695  res.bases_1d[1]->set(index_1) = SIN_ODD ;
696  break ;
697  case COS_ODD:
698  res.bases_1d[1]->set(index_1) = SIN_EVEN ;
699  break ;
700  case SIN_EVEN:
701  res.bases_1d[1]->set(index_1) = COS_ODD ;
702  break ;
703  case SIN_ODD:
704  res.bases_1d[1]->set(index_1) = COS_EVEN ;
705  break ;
706  default:
707  res_def = false ;
708  break ;
709  }
710  break ;
711  default:
712  res_def = false ;
713  break ;
714  }
715  }
716  while (index_1.inc()) ;
717 
718 
719  // Base in r :
720  Index index_0 (a.bases_1d[0]->get_dimensions()) ;
721  res.bases_1d[0] = new Array<int> (a.bases_1d[0]->get_dimensions()) ;
722  do {
723  switch ((*a.bases_1d[0])(index_0)) {
724  case CHEB_EVEN:
725  switch ((*b.bases_1d[0])(index_0)) {
726  case CHEB_EVEN:
727  res.bases_1d[0]->set(index_0) = CHEB_EVEN ;
728  break ;
729  case CHEB_ODD:
730  res.bases_1d[0]->set(index_0) = CHEB_ODD ;
731  break ;
732  default:
733  res_def = false ;
734  break ;
735  }
736  break ;
737  case CHEB_ODD:
738  switch ((*b.bases_1d[0])(index_0)) {
739  case CHEB_EVEN:
740  res.bases_1d[0]->set(index_0) = CHEB_ODD ;
741  break ;
742  case CHEB_ODD:
743  res.bases_1d[0]->set(index_0) = CHEB_EVEN ;
744  break ;
745  default:
746  res_def = false ;
747  break ;
748  }
749  break ;
750  case LEG_EVEN:
751  switch ((*b.bases_1d[0])(index_0)) {
752  case LEG_EVEN:
753  res.bases_1d[0]->set(index_0) = LEG_EVEN ;
754  break ;
755  case LEG_ODD:
756  res.bases_1d[0]->set(index_0) = LEG_ODD ;
757  break ;
758  default:
759  res_def = false ;
760  break ;
761  }
762  break ;
763  case LEG_ODD:
764  switch ((*b.bases_1d[0])(index_0)) {
765  case LEG_EVEN:
766  res.bases_1d[0]->set(index_0) = LEG_ODD ;
767  break ;
768  case LEG_ODD:
769  res.bases_1d[0]->set(index_0) = LEG_EVEN ;
770  break ;
771  default:
772  res_def = false ;
773  break ;
774  }
775  break ;
776  default:
777  res_def = false ;
778  break ;
779  }
780  }
781  while (index_0.inc()) ;
782  }
783 
784  if (!res_def)
785  for (int dim=0 ; dim<a.ndim ; dim++)
786  if (res.bases_1d[dim]!= 0x0) {
787  delete res.bases_1d[dim] ;
788  res.bases_1d[dim] = 0x0 ;
789  }
790  res.def = res_def ;
791  return res ;
792 }
793 }
Class for storing the basis of decompositions of a field.
Bases_container bases_1d
Arrays containing the various basis of decomposition.
void allocate(const Dim_array &nbr_coefs)
Allocates the various arrays, for a given number of coefficients.
bool def
true if the Base_spectral is defined and false otherwise.
int ndim
Number of dimensions.
Class for storing the dimensions of an array.
Definition: dim_array.hpp:34
int get_ndim() const
Returns the number of dimensions.
Definition: dim_array.hpp:63
void save(FILE *) const
Save function.
Definition: dim_array.cpp:32
Class for a spherical nucleus with a symmetry in .
virtual void do_radius() const
Computes the generalized radius.
virtual void set_cheb_base_with_m(Base_spectral &, int m) const
Gives the standard base using Chebyshev polynomials.
virtual void set_legendre_base_t_spher(Base_spectral &) const
Gives the base using Legendre polynomials, for the component of a vector.
virtual void set_anti_cheb_base_with_m(Base_spectral &, int m) const
Gives the base using Chebyshev polynomials, for functions antisymetric with respect to .
virtual void do_der_abs_from_der_var(const Val_domain *const *const der_var, Val_domain **const der_abs) const
Computes the derivative with respect to the absolute Cartesian coordinates from the derivative with r...
Domain_polar_periodic_nucleus(int num, int ttype, double radius, double ome, const Dim_array &nbr)
Standard constructor :
virtual void set_legendre_base_with_m(Base_spectral &, int m) const
Gives the stnadard base using Legendre polynomials.
virtual Val_domain div_x(const Val_domain &) const
Division by .
virtual Base_spectral mult(const Base_spectral &, const Base_spectral &) const
Method for the multiplication of two Base_spectral.
virtual Val_domain der_normal(const Val_domain &, int) const
Normal derivative with respect to a given surface.
int type_time
Gives the type of time periodicity.
virtual void set_cheb_base_p_spher(Base_spectral &) const
Gives the base using Chebyshev polynomials, for the component of a vector.
virtual ostream & print(ostream &o) const
Delegate function to virtualize the << operator.
virtual void set_cheb_base(Base_spectral &) const
Gives the standard base for Chebyshev polynomials.
virtual void set_legendre_base_r_spher(Base_spectral &) const
Gives the base using Legendre polynomials, for the radial component of a vector.
Term_eq * ome_term_eq
Pointer on the Term_eq version of the pulsation.
virtual void do_coloc()
Computes the colocation points.
virtual void do_absol() const
Computes the absolute coordinates.
virtual void set_legendre_base(Base_spectral &) const
Gives the standard base for Legendre polynomials.
virtual const Point absol_to_num(const Point &) const
Computes the numerical coordinates from the physical ones.
virtual void save(FILE *) const
Saving function.
virtual void set_legendre_base_p_spher(Base_spectral &) const
Gives the base using Legendre polynomials, for the component of a vector.
virtual void set_cheb_base_r_spher(Base_spectral &) const
Gives the base using Chebyshev polynomials, for the radial component of a vector.
virtual void set_anti_legendre_base(Base_spectral &) const
Gives the base using Legendre polynomials, for functions antisymetric with respect to .
virtual void set_cheb_base_t_spher(Base_spectral &) const
Gives the base using Chebyshev polynomials, for the component of a vector.
virtual void set_anti_cheb_base(Base_spectral &) const
Gives the base using Chebyshev polynomials, for functions antisymetric with respect to .
double maxt
Upper bound of which is or .
virtual bool is_in(const Point &xx, double prec=1e-13) const
Check whether a point lies inside Domain.
virtual void set_anti_legendre_base_with_m(Base_spectral &, int m) const
Gives the base using Legendre polynomials, for functions antisymetric with respect to .
double alpha
Relates the numerical radius to the physical one.
Abstract class that implements the fonctionnalities common to all the type of domains.
Definition: space.hpp:60
virtual void del_deriv()
Destroys the derivated members (like coloc, cart and radius), when changing the type of colocation po...
Definition: domain.cpp:77
Val_domain * radius
The generalized radius.
Definition: space.hpp:78
Memory_mapped_array< Val_domain * > absol
Asbolute coordinates (if defined ; usually Cartesian-like)
Definition: space.hpp:76
int ndim
Number of dimensions.
Definition: space.hpp:64
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
Dim_array nbr_points
Number of colocation points.
Definition: space.hpp:65
int type_base
Type of colocation point :
Definition: space.hpp:73
Memory_mapped_array< Array< double > * > coloc
Colocation points in each dimension (stored in ndim 1d- arrays)
Definition: space.hpp:75
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 Point is used to store the coordinates of a point.
Definition: point.hpp:30
const int & get_ndim() const
Returns the number of dimensions.
Definition: point.hpp:51
double & set(int i)
Read/write of a coordinate.
Definition: point.hpp:47
This class is intended to describe the manage objects appearing in the equations.
Definition: term_eq.hpp:62
void set_der_d(double)
Sets the double variation.
Definition: term_eq.hpp:395
Class for storing the basis of decompositions of a field and its values on both the configuration and...
Definition: val_domain.hpp:69
Val_domain mult_sin_theta() const
Multiplication by .
double & set(const Index &pos)
Read/write the value of the field in the configuration space.
Definition: val_domain.cpp:171
Val_domain mult_cos_theta() const
Multiplication by .
Val_domain der_var(int i) const
Computes the derivative with respect to a numerical coordinate.
Definition: val_domain.cpp:670
void allocate_conf()
Allocates the values in the configuration space and destroys the values in the coefficients space.
Definition: val_domain.cpp:209