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