KADATH
domain_compact.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 
22 #include "utilities.hpp"
23 #include "spheric.hpp"
24 #include "point.hpp"
25 #include "val_domain.hpp"
26 namespace Kadath {
27 // Standard constructor
28 Domain_compact::Domain_compact (int num, int ttype, double r, const Point& cr, const Dim_array& nbr) : Domain(num, ttype, nbr), alpha(-0.5/r),
29  center(cr) {
30 
31  assert (nbr.get_ndim()==3) ;
32  assert (cr.get_ndim()==3) ;
33  do_coloc() ;
34 
35 }
36 
37 // Copy constructor
38 Domain_compact::Domain_compact (const Domain_compact& so) : Domain(so), alpha(so.alpha), center(so.center){}
39 
40 
41 Domain_compact::Domain_compact (int num, FILE* fd) : Domain(num, fd), center(fd) {
42  fread_be (&alpha, sizeof(double), 1, fd) ;
43  do_coloc() ;
44 }
45 
46 // Destructor
47 Domain_compact::~Domain_compact() {}
48 
49 ostream& Domain_compact::print (ostream& o) const {
50  o << "Compactified domain" << endl ;
51  o << "Rmin = " << -0.5/alpha << endl ;
52  o << "Center = " << center << endl ;
53  o << "Nbr pts = " << nbr_points << endl ;
54  o << endl ;
55  return o ;
56 }
57 
58 void Domain_compact::save (FILE* fd) const {
59  nbr_points.save(fd) ;
60  nbr_coefs.save(fd) ;
61  fwrite_be (&ndim, sizeof(int), 1, fd) ;
62  fwrite_be (&type_base, sizeof(int), 1, fd) ;
63  center.save(fd) ;
64  fwrite_be (&alpha, sizeof(double), 1, fd) ;
65 }
66 
67 
68 Val_domain Domain_compact::der_normal (const Val_domain& so, int bound) const {
69 
70  Val_domain res (so.der_var(1)) ;
71  switch (bound) {
72  case INNER_BC :
73  res = res.mult_xm1() ;
74  res = res.mult_xm1() ;
75  res *= -alpha ;
76  break ;
77  case OUTER_BC :
78  res = res.mult_xm1() ;
79  res = res.mult_xm1() ;
80  res *= -alpha ;
81  break ;
82  default:
83  cerr << "Unknown boundary case in Domain_compact::der_normal" << endl ;
84  abort() ;
85  }
86 return res ;
87 }
88 
89 double Domain_compact::integ (const Val_domain& so, int bound) const {
90 
91  Val_domain rrso (mult_r(mult_r(mult_sin_theta(so)))) ;
92 
93  double res = 0 ;
94  if (!so.check_if_zero())
95  {
96 
97  int baset = (*rrso.get_base().bases_1d[1]) (0) ;
98  Index pcf (nbr_coefs) ;
99  switch (baset) {
100  case COS_ODD :
101  break ;
102  case SIN_EVEN :
103  break ;
104  case COS_EVEN : {
105  res += M_PI*val_boundary(bound, rrso, pcf) ;
106  break ;
107  }
108  case SIN_ODD : {
109  for (int j=0 ; j<nbr_coefs(1) ; j++) {
110  pcf.set(1) = j ;
111  res += 2./(2*double(j)+1) * val_boundary(bound, rrso, pcf) ;
112  }
113  break ;
114  }
115 
116  default :
117  cerr << "Case not yet implemented in Domain_shell::integ" << endl ;
118  abort() ;
119  }
120  res *= 2*M_PI ;
121  }
122  return res ;
123 }
124 
125 // Computes the Cartesian coordinates
127  for (int i=0 ; i<3 ; i++)
128  assert (coloc[i] != 0x0) ;
129  for (int i=0 ; i<3 ; i++)
130  assert (absol[i] == 0x0) ;
131  for (int i=0 ; i<3 ; i++) {
132  absol[i] = new Val_domain(this) ;
133  absol[i]->allocate_conf() ;
134  }
135  Index index (nbr_points) ;
136  do {
137  absol[0]->set(index) = (1./alpha/ ((*coloc[0])(index(0))-1)) *
138  sin((*coloc[1])(index(1)))*cos((*coloc[2])(index(2))) + center(1) ;
139  absol[1]->set(index) = (1./alpha/ ((*coloc[0])(index(0))-1)) *
140  sin((*coloc[1])(index(1)))*sin((*coloc[2])(index(2))) + center(2) ;
141  absol[2]->set(index) = (1./alpha/ ((*coloc[0])(index(0))-1)) * cos((*coloc[1])(index(1))) +
142  center(3) ;
143  }
144  while (index.inc()) ;
145 }
146 
147 // Computes the radius
149  for (int i=0 ; i<3 ; i++)
150  assert (coloc[i] != 0x0) ;
151  assert (radius == 0x0) ;
152  radius = new Val_domain(this) ;
153  radius->allocate_conf() ;
154  Index index (nbr_points) ;
155  do
156  radius->set(index) = 1./alpha/ ((*coloc[0])(index(0))-1) ;
157  while (index.inc()) ;
158 }
159 
160 // Computes the Cartesian coordinates
161 void Domain_compact::do_cart () const {
162  for (int i=0 ; i<3 ; i++)
163  assert (coloc[i] != 0x0) ;
164  for (int i=0 ; i<3 ; i++)
165  assert (cart[i] == 0x0) ;
166  for (int i=0 ; i<3 ; i++) {
167  cart[i] = new Val_domain(this) ;
168  cart[i]->allocate_conf() ;
169  }
170  Index index (nbr_points) ;
171  do {
172  cart[0]->set(index) = (1./alpha/ ((*coloc[0])(index(0))-1)) *
173  sin((*coloc[1])(index(1)))*cos((*coloc[2])(index(2))) + center(1) ;
174  cart[1]->set(index) = (1./alpha/ ((*coloc[0])(index(0))-1)) *
175  sin((*coloc[1])(index(1)))*sin((*coloc[2])(index(2))) + center(2) ;
176  cart[2]->set(index) = (1./alpha/ ((*coloc[0])(index(0))-1)) * cos((*coloc[1])(index(1))) +
177  center(3) ;
178  }
179  while (index.inc()) ;
180 }
181 
182 // Computes the Cartesian coordinates ovzr radius
184  for (int i=0 ; i<3 ; i++)
185  assert (coloc[i] != 0x0) ;
186  for (int i=0 ; i<3 ; i++)
187  assert (cart_surr[i] == 0x0) ;
188  for (int i=0 ; i<3 ; i++) {
189  cart_surr[i] = new Val_domain(this) ;
190  cart_surr[i]->allocate_conf() ;
191  }
192  Index index (nbr_points) ;
193  do {
194  cart_surr[0]->set(index) = sin((*coloc[1])(index(1)))*cos((*coloc[2])(index(2))) ;
195  cart_surr[1]->set(index) = sin((*coloc[1])(index(1)))*sin((*coloc[2])(index(2))) ;
196  cart_surr[2]->set(index) = cos((*coloc[1])(index(1))) ;
197  }
198  while (index.inc()) ;
199 }
200 
201 // Is inside ?
202 bool Domain_compact::is_in (const Point& xx, double prec) const {
203 
204  assert (xx.get_ndim()==3) ;
205 
206  double x_loc = xx(1) - center(1) ;
207  double y_loc = xx(2) - center(2) ;
208  double z_loc = xx(3) - center(3) ;
209  double air_loc = sqrt (x_loc*x_loc + y_loc*y_loc + z_loc*z_loc) ;
210 
211  bool res = (1. + 1./(2*alpha*air_loc) >= -prec) ? true : false ;
212  return res ;
213 }
214 
215 // Converts the absolute coordinates to the numerical ones.
216 const Point Domain_compact::absol_to_num(const Point& abs) const {
217 
218  assert (is_in(abs)) ;
219  Point num(3) ;
220 
221  double x_loc = abs(1) - center(1) ;
222  double y_loc = abs(2) - center(2) ;
223  double z_loc = abs(3) - center(3) ;
224  double air = sqrt(x_loc*x_loc+y_loc*y_loc+z_loc*z_loc) ;
225  num.set(1) = 1. + 1./air/alpha ;
226  double rho = sqrt(x_loc*x_loc+y_loc*y_loc) ;
227 
228  if (rho==0) {
229  // On the axis ?
230  num.set(2) = (z_loc>=0) ? 0 : M_PI ;
231  num.set(3) = 0 ;
232  }
233  else {
234  num.set(2) = atan(rho/z_loc) ;
235  num.set(3) = atan2 (y_loc, x_loc) ;
236  }
237 
238  if (num(2) <0)
239  num.set(2) = M_PI + num(2) ;
240 
241  return num ;
242 }
243 
244 
245 // Convert absolute coordinates to numerical ones
246 const Point Domain_compact::absol_to_num_bound(const Point& abs, int bound) const {
247 
248  assert (bound==INNER_BC) ;
249  assert (is_in(abs, 1e-3)) ;
250  Point num(3) ;
251 
252  double x_loc = abs(1) - center(1) ;
253  double y_loc = abs(2) - center(2) ;
254  double z_loc = abs(3) - center(3) ;
255  num.set(1) = -1 ;
256  double rho = sqrt(x_loc*x_loc+y_loc*y_loc) ;
257 
258  if (rho==0) {
259  // Sur l'axe
260  num.set(2) = (z_loc>=0) ? 0 : M_PI ;
261  num.set(3) = 0 ;
262  }
263  else {
264  num.set(2) = atan(rho/z_loc) ;
265  num.set(3) = atan2 (y_loc, x_loc) ;
266  }
267 
268  if (num(2) <0)
269  num.set(2) = M_PI + num(2) ;
270 
271  return num ;
272 }
273 
274 double coloc_leg(int,int) ;
276 
277  switch (type_base) {
278  case CHEB_TYPE:
280  nbr_coefs.set(2) += 2 ;
281  del_deriv() ;
282  for (int i=0 ; i<ndim ; i++)
283  coloc[i] = new Array<double> (nbr_points(i)) ;
284  for (int i=0 ; i<nbr_points(0) ; i++)
285  coloc[0]->set(i) = -cos(M_PI*i/(nbr_points(0)-1)) ;
286  for (int j=0 ; j<nbr_points(1) ; j++)
287  coloc[1]->set(j) = M_PI/2.*j/(nbr_points(1)-1) ;
288  for (int k=0 ; k<nbr_points(2) ; k++)
289  coloc[2]->set(k) = M_PI*2.*k/nbr_points(2) ;
290  break ;
291  case LEG_TYPE:
293  nbr_coefs.set(2) += 2 ;
294  del_deriv() ;
295  for (int i=0 ; i<ndim ; i++)
296  coloc[i] = new Array<double> (nbr_points(i)) ;
297  for (int i=0 ; i<nbr_points(0) ; i++)
298  coloc[0]->set(i) = coloc_leg(i, nbr_points(0)) ;
299  for (int j=0 ; j<nbr_points(1) ; j++)
300  coloc[1]->set(j) = M_PI/2.*j/(nbr_points(1)-1) ;
301  for (int k=0 ; k<nbr_points(2) ; k++)
302  coloc[2]->set(k) = M_PI*2.*k/nbr_points(2) ;
303  break ;
304  default :
305  cerr << "Unknown type of basis in Domain_compact::do_coloc" << endl ;
306  abort() ;
307  }
308 }
309 
310 // standard base for a symetric function using Chebyshev
312  int m ;
313 
314  assert (type_base == CHEB_TYPE) ;
315 
316  base.allocate(nbr_coefs) ;
317 
318  Index index (base.bases_1d[0]->get_dimensions()) ;
319 
320  base.def=true ;
321  base.bases_1d[2]->set(0) = COSSIN ;
322  for (int k=0 ; k<nbr_coefs(2) ; k++) {
323  m = (k%2==0) ? k/2 : (k-1)/2 ;
324  base.bases_1d[1]->set(k) = (m%2==0) ? COS_EVEN : SIN_ODD ;
325  for (int j=0 ; j<nbr_coefs(1) ; j++) {
326  index.set(0) = j ; index.set(1) = k ;
327  base.bases_1d[0]->set(index) = CHEB ;
328  }
329  }
330 }
331 
333  int m ;
334 
335  assert (type_base == CHEB_TYPE) ;
336 
337  base.allocate(nbr_coefs) ;
338 
339  Index index (base.bases_1d[0]->get_dimensions()) ;
340 
341  if (mquant%2==0) {
342  base.def=true ;
343  base.bases_1d[2]->set(0) = COSSIN ;
344  for (int k=0 ; k<nbr_coefs(2) ; k++) {
345  m = (k%2==0) ? k/2 : (k-1)/2 ;
346  base.bases_1d[1]->set(k) = (m%2==0) ? COS_EVEN : SIN_ODD ;
347  for (int j=0 ; j<nbr_coefs(1) ; j++) {
348  index.set(0) = j ; index.set(1) = k ;
349  base.bases_1d[0]->set(index) = CHEB ;
350  }
351  }
352  }
353  else {
354  base.def=true ;
355  base.bases_1d[2]->set(0) = COSSIN ;
356  for (int k=0 ; k<nbr_coefs(2) ; k++) {
357  m = (k%2==0) ? k/2 : (k-1)/2 ;
358  base.bases_1d[1]->set(k) = (m%2==0) ? SIN_ODD : COS_EVEN ;
359  for (int j=0 ; j<nbr_coefs(1) ; j++) {
360  index.set(0) = j ; index.set(1) = k ;
361  base.bases_1d[0]->set(index) = CHEB ;
362  }
363  }
364  }
365 
366 }
367 
369  set_cheb_base(base) ;
370 }
371 
373  set_legendre_base(base) ;
374 }
375 
376 // standard base for a anti-symetric function using Chebyshev
378  int m ;
379 
380  assert (type_base == CHEB_TYPE) ;
381 
382  base.allocate(nbr_coefs) ;
383 
384  Index index (base.bases_1d[0]->get_dimensions()) ;
385 
386  base.def=true ;
387  base.bases_1d[2]->set(0) = COSSIN ;
388  for (int k=0 ; k<nbr_coefs(2) ; k++) {
389  m = (k%2==0) ? k/2 : (k-1)/2 ;
390  base.bases_1d[1]->set(k) = (m%2==0) ? COS_ODD : SIN_EVEN ;
391  for (int j=0 ; j<nbr_coefs(1) ; j++) {
392  index.set(0) = j ; index.set(1) = k ;
393  base.bases_1d[0]->set(index) = CHEB ;
394  }
395  }
396 }
397 
399  int m ;
400 
401  assert (type_base == CHEB_TYPE) ;
402 
403  base.allocate(nbr_coefs) ;
404 
405  Index index (base.bases_1d[0]->get_dimensions()) ;
406 
407  base.def=true ;
408  base.bases_1d[2]->set(0) = COSSIN ;
409  for (int k=0 ; k<nbr_coefs(2) ; k++) {
410  m = (k%2==0) ? k/2 : (k-1)/2 ;
411  base.bases_1d[1]->set(k) = (m%2==0) ? COS_EVEN : SIN_ODD ;
412  for (int j=0 ; j<nbr_coefs(1) ; j++) {
413  index.set(0) = j ; index.set(1) = k ;
414  base.bases_1d[0]->set(index) = CHEB ;
415  }
416  }
417 }
418 
420  int m ;
421 
422  assert (type_base == CHEB_TYPE) ;
423 
424  base.allocate(nbr_coefs) ;
425 
426  Index index (base.bases_1d[0]->get_dimensions()) ;
427 
428  base.def=true ;
429  base.bases_1d[2]->set(0) = COSSIN ;
430  for (int k=0 ; k<nbr_coefs(2) ; k++) {
431  m = (k%2==0) ? k/2 : (k-1)/2 ;
432  base.bases_1d[1]->set(k) = (m%2==0) ? SIN_EVEN : COS_ODD ;
433  for (int j=0 ; j<nbr_coefs(1) ; j++) {
434  index.set(0) = j ; index.set(1) = k ;
435  base.bases_1d[0]->set(index) = CHEB ;
436  }
437  }
438 }
439 
441  int m ;
442 
443  assert (type_base == CHEB_TYPE) ;
444 
445  base.allocate(nbr_coefs) ;
446 
447  Index index (base.bases_1d[0]->get_dimensions()) ;
448 
449  base.def=true ;
450  base.bases_1d[2]->set(0) = COSSIN ;
451  for (int k=0 ; k<nbr_coefs(2) ; k++) {
452  m = (k%2==0) ? k/2 : (k-1)/2 ;
453  base.bases_1d[1]->set(k) = (m%2==0) ? SIN_ODD : COS_EVEN ;
454  for (int j=0 ; j<nbr_coefs(1) ; j++) {
455  index.set(0) = j ; index.set(1) = k ;
456  base.bases_1d[0]->set(index) = CHEB ;
457  }
458  }
459 }
461  int m ;
462 
463  assert (type_base == CHEB_TYPE) ;
464 
465  base.allocate(nbr_coefs) ;
466 
467  Index index (base.bases_1d[0]->get_dimensions()) ;
468 
469  base.def=true ;
470  base.bases_1d[2]->set(0) = COSSIN ;
471  for (int k=0 ; k<nbr_coefs(2) ; k++) {
472  m = (k%2==0) ? k/2 : (k-1)/2 ;
473  base.bases_1d[1]->set(k) = (m%2==0) ? COS_EVEN : SIN_ODD ;
474  for (int j=0 ; j<nbr_coefs(1) ; j++) {
475  index.set(0) = j ; index.set(1) = k ;
476  base.bases_1d[0]->set(index) = CHEB ;
477  }
478  }
479 }
480 
482  int m ;
483 
484  assert (type_base == CHEB_TYPE) ;
485 
486  base.allocate(nbr_coefs) ;
487 
488  Index index (base.bases_1d[0]->get_dimensions()) ;
489 
490  base.def=true ;
491  base.bases_1d[2]->set(0) = COSSIN ;
492  for (int k=0 ; k<nbr_coefs(2) ; k++) {
493  m = (k%2==0) ? k/2 : (k-1)/2 ;
494  base.bases_1d[1]->set(k) = (m%2==0) ? SIN_ODD : COS_EVEN ;
495  for (int j=0 ; j<nbr_coefs(1) ; j++) {
496  index.set(0) = j ; index.set(1) = k ;
497  base.bases_1d[0]->set(index) = CHEB ;
498  }
499  }
500 }
501 
503  int m ;
504 
505  assert (type_base == CHEB_TYPE) ;
506 
507  base.allocate(nbr_coefs) ;
508 
509  Index index (base.bases_1d[0]->get_dimensions()) ;
510 
511  base.def=true ;
512  base.bases_1d[2]->set(0) = COSSIN ;
513  for (int k=0 ; k<nbr_coefs(2) ; k++) {
514  m = (k%2==0) ? k/2 : (k-1)/2 ;
515  base.bases_1d[1]->set(k) = (m%2==0) ? SIN_EVEN : COS_ODD ;
516  for (int j=0 ; j<nbr_coefs(1) ; j++) {
517  index.set(0) = j ; index.set(1) = k ;
518  base.bases_1d[0]->set(index) = CHEB ;
519  }
520  }
521 }
522 
523 // standard base for a symetric function using Legendre
525 
526  int m ;
527 
528  assert (type_base == LEG_TYPE) ;
529 
530  base.allocate(nbr_coefs) ;
531 
532  Index index (base.bases_1d[0]->get_dimensions()) ;
533 
534  base.def=true ;
535  base.bases_1d[2]->set(0) = COSSIN ;
536  for (int k=0 ; k<nbr_coefs(2) ; k++) {
537  m = (k%2==0) ? k/2 : (k-1)/2 ;
538  base.bases_1d[1]->set(k) = (m%2==0) ? COS_EVEN : SIN_ODD ;
539  for (int j=0 ; j<nbr_coefs(1) ; j++) {
540  index.set(0) = j ; index.set(1) = k ;
541  base.bases_1d[0]->set(index) = LEG ;
542  }
543  }
544 }
545 
546 // standard base for a anti-symetric function using Legendre
548 
549  int m ;
550 
551  assert (type_base == LEG_TYPE) ;
552 
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) = COSSIN ;
559  for (int k=0 ; k<nbr_coefs(2) ; k++) {
560  m = (k%2==0) ? k/2 : (k-1)/2 ;
561  base.bases_1d[1]->set(k) = (m%2==0) ? COS_ODD : SIN_EVEN ;
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 ;
565  }
566  }
567 }
568 
569 
571  int m ;
572 
573  assert (type_base == LEG_TYPE) ;
574 
575  base.allocate(nbr_coefs) ;
576 
577  Index index (base.bases_1d[0]->get_dimensions()) ;
578 
579  base.def=true ;
580  base.bases_1d[2]->set(0) = COSSIN ;
581  for (int k=0 ; k<nbr_coefs(2) ; k++) {
582  m = (k%2==0) ? k/2 : (k-1)/2 ;
583  base.bases_1d[1]->set(k) = (m%2==0) ? COS_EVEN : SIN_ODD ;
584  for (int j=0 ; j<nbr_coefs(1) ; j++) {
585  index.set(0) = j ; index.set(1) = k ;
586  base.bases_1d[0]->set(index) = LEG ;
587  }
588  }
589 }
590 
592  int m ;
593 
594  assert (type_base == LEG_TYPE) ;
595 
596  base.allocate(nbr_coefs) ;
597 
598  Index index (base.bases_1d[0]->get_dimensions()) ;
599 
600  base.def=true ;
601  base.bases_1d[2]->set(0) = COSSIN ;
602  for (int k=0 ; k<nbr_coefs(2) ; k++) {
603  m = (k%2==0) ? k/2 : (k-1)/2 ;
604  base.bases_1d[1]->set(k) = (m%2==0) ? SIN_EVEN : COS_ODD ;
605  for (int j=0 ; j<nbr_coefs(1) ; j++) {
606  index.set(0) = j ; index.set(1) = k ;
607  base.bases_1d[0]->set(index) = LEG ;
608  }
609  }
610 }
611 
613  int m ;
614 
615  assert (type_base == LEG_TYPE) ;
616 
617  base.allocate(nbr_coefs) ;
618 
619  Index index (base.bases_1d[0]->get_dimensions()) ;
620 
621  base.def=true ;
622  base.bases_1d[2]->set(0) = COSSIN ;
623  for (int k=0 ; k<nbr_coefs(2) ; k++) {
624  m = (k%2==0) ? k/2 : (k-1)/2 ;
625  base.bases_1d[1]->set(k) = (m%2==0) ? SIN_ODD : COS_EVEN ;
626  for (int j=0 ; j<nbr_coefs(1) ; j++) {
627  index.set(0) = j ; index.set(1) = k ;
628  base.bases_1d[0]->set(index) = LEG ;
629  }
630  }
631 }
633  int m ;
634 
635  assert (type_base == LEG_TYPE) ;
636 
637  base.allocate(nbr_coefs) ;
638 
639  Index index (base.bases_1d[0]->get_dimensions()) ;
640 
641  base.def=true ;
642  base.bases_1d[2]->set(0) = COSSIN ;
643  for (int k=0 ; k<nbr_coefs(2) ; k++) {
644  m = (k%2==0) ? k/2 : (k-1)/2 ;
645  base.bases_1d[1]->set(k) = (m%2==0) ? COS_EVEN : SIN_ODD ;
646  for (int j=0 ; j<nbr_coefs(1) ; j++) {
647  index.set(0) = j ; index.set(1) = k ;
648  base.bases_1d[0]->set(index) = LEG ;
649  }
650  }
651 }
652 
654  int m ;
655 
656  assert (type_base == LEG_TYPE) ;
657 
658  base.allocate(nbr_coefs) ;
659 
660  Index index (base.bases_1d[0]->get_dimensions()) ;
661 
662  base.def=true ;
663  base.bases_1d[2]->set(0) = COSSIN ;
664  for (int k=0 ; k<nbr_coefs(2) ; k++) {
665  m = (k%2==0) ? k/2 : (k-1)/2 ;
666  base.bases_1d[1]->set(k) = (m%2==0) ? SIN_ODD : COS_EVEN ;
667  for (int j=0 ; j<nbr_coefs(1) ; j++) {
668  index.set(0) = j ; index.set(1) = k ;
669  base.bases_1d[0]->set(index) = LEG ;
670  }
671  }
672 }
673 
675  int m ;
676 
677  assert (type_base == LEG_TYPE) ;
678 
679  base.allocate(nbr_coefs) ;
680 
681  Index index (base.bases_1d[0]->get_dimensions()) ;
682 
683  base.def=true ;
684  base.bases_1d[2]->set(0) = COSSIN ;
685  for (int k=0 ; k<nbr_coefs(2) ; k++) {
686  m = (k%2==0) ? k/2 : (k-1)/2 ;
687  base.bases_1d[1]->set(k) = (m%2==0) ? SIN_EVEN : COS_ODD ;
688  for (int j=0 ; j<nbr_coefs(1) ; j++) {
689  index.set(0) = j ; index.set(1) = k ;
690  base.bases_1d[0]->set(index) = LEG ;
691  }
692  }
693 }
694 
695 // sets the value at infinity
696 void Domain_compact::set_val_inf (Val_domain& so, double x) const {
697 
698  assert (so.get_domain() == this) ;
699 
700  so.coef_i() ;
701  so.set_in_conf() ;
702  Index inf (nbr_points) ;
703  inf.set(0) = nbr_points(0)-1 ;
704  do
705  so.set(inf) = x ;
706  while (inf.inc1(1)) ;
707 }
708 
709 // Computes the derivatives with respect to XYZ as function of the numerical ones.
710 void Domain_compact::do_der_abs_from_der_var(const Val_domain *const *const der_var, Val_domain **const der_abs) const {
711 
712  // d/dx :
713  Val_domain dr (-der_var[0]->mult_xm1()) ;
714  Val_domain sintdr (dr.mult_sin_theta()) ;
715  Val_domain costdt (der_var[1]->mult_cos_theta()) ;
716 
717  Val_domain dpssint (der_var[2]->div_sin_theta()) ;
718 
719  Val_domain auxi_x ((sintdr+costdt).mult_cos_phi() - dpssint.mult_sin_phi()) ;
720  der_abs[0] = new Val_domain (alpha*auxi_x.mult_xm1()) ;
721 
722  // d/dy :
723  Val_domain auxi_y ((sintdr+costdt).mult_sin_phi() + dpssint.mult_cos_phi()) ;
724  der_abs[1] = new Val_domain (alpha*auxi_y.mult_xm1()) ;
725  // d/dz :
726  Val_domain auxi_z (dr.mult_cos_theta() - der_var[1]->mult_sin_theta()) ;
727  der_abs[2] = new Val_domain (alpha*auxi_z.mult_xm1()) ;
728 
729 }
730 
731 // Rules for basis multiplication
733 
734  assert (a.ndim==3) ;
735  assert (b.ndim==3) ;
736 
737  Base_spectral res(3) ;
738  bool res_def = true ;
739 
740  if (!a.def)
741  res_def=false ;
742  if (!b.def)
743  res_def=false ;
744 
745  if (res_def) {
746 
747  // Base in phi :
748  res.bases_1d[2] = new Array<int> (a.bases_1d[2]->get_dimensions()) ;
749  switch ((*a.bases_1d[2])(0)) {
750  case COSSIN:
751  switch ((*b.bases_1d[2])(0)) {
752  case COSSIN:
753  res.bases_1d[2]->set(0) = COSSIN ;
754  break ;
755  default:
756  res_def = false ;
757  break ;
758  }
759  break ;
760  default:
761  res_def = false ;
762  break ;
763  }
764 
765  // Bases in theta :
766  // On check l'alternance :
767  Index index_1 (a.bases_1d[1]->get_dimensions()) ;
768  res.bases_1d[1] = new Array<int> (a.bases_1d[1]->get_dimensions()) ;
769  do {
770  switch ((*a.bases_1d[1])(index_1)) {
771  case COS_EVEN:
772  switch ((*b.bases_1d[1])(index_1)) {
773  case COS_EVEN:
774  res.bases_1d[1]->set(index_1) = (index_1(0)%4<2) ? COS_EVEN : SIN_ODD ;
775  break ;
776  case COS_ODD:
777  res.bases_1d[1]->set(index_1) = (index_1(0)%4<2) ? COS_ODD : SIN_EVEN ;
778  break ;
779  case SIN_EVEN:
780  res.bases_1d[1]->set(index_1) = (index_1(0)%4<2) ? SIN_EVEN : COS_ODD ;
781  break ;
782  case SIN_ODD:
783  res.bases_1d[1]->set(index_1) = (index_1(0)%4<2) ? SIN_ODD : COS_EVEN ;
784  break ;
785  default:
786  res_def = false ;
787  break ;
788  }
789  break ;
790  case COS_ODD:
791  switch ((*b.bases_1d[1])(index_1)) {
792  case COS_EVEN:
793  res.bases_1d[1]->set(index_1) = (index_1(0)%4<2) ? COS_ODD : SIN_EVEN ;
794  break ;
795  case COS_ODD:
796  res.bases_1d[1]->set(index_1) = (index_1(0)%4<2) ? COS_EVEN : SIN_ODD ;
797  break ;
798  case SIN_EVEN:
799  res.bases_1d[1]->set(index_1) = (index_1(0)%4<2) ? SIN_ODD : COS_EVEN ;
800  break ;
801  case SIN_ODD:
802  res.bases_1d[1]->set(index_1) = (index_1(0)%4<2) ? SIN_EVEN : COS_ODD ;
803  break ;
804  default:
805  res_def = false ;
806  break ;
807  }
808  break ;
809  case SIN_EVEN:
810  switch ((*b.bases_1d[1])(index_1)) {
811  case COS_EVEN:
812  res.bases_1d[1]->set(index_1) = (index_1(0)%4<2) ? SIN_EVEN : COS_ODD ;
813  break ;
814  case COS_ODD:
815  res.bases_1d[1]->set(index_1) = (index_1(0)%4<2) ? SIN_ODD : COS_EVEN ;
816  break ;
817  case SIN_EVEN:
818  res.bases_1d[1]->set(index_1) = (index_1(0)%4<2) ? COS_EVEN : SIN_ODD ;
819  break ;
820  case SIN_ODD:
821  res.bases_1d[1]->set(index_1) = (index_1(0)%4<2) ? COS_ODD : SIN_EVEN ;
822  break ;
823  default:
824  res_def = false ;
825  break ;
826  }
827  break ;
828  case SIN_ODD:
829  switch ((*b.bases_1d[1])(index_1)) {
830  case COS_EVEN:
831  res.bases_1d[1]->set(index_1) = (index_1(0)%4<2) ? SIN_ODD : COS_EVEN ;
832  break ;
833  case COS_ODD:
834  res.bases_1d[1]->set(index_1) = (index_1(0)%4<2) ? SIN_EVEN : COS_ODD ;
835  break ;
836  case SIN_EVEN:
837  res.bases_1d[1]->set(index_1) = (index_1(0)%4<2) ? COS_ODD : SIN_EVEN ;
838  break ;
839  case SIN_ODD:
840  res.bases_1d[1]->set(index_1) = (index_1(0)%4<2) ? COS_EVEN : SIN_ODD ;
841  break ;
842  default:
843  res_def = false ;
844  break ;
845  }
846  break ;
847  default:
848  res_def = false ;
849  break ;
850  }
851  }
852  while (index_1.inc()) ;
853 
854 
855  // Base in r :
856  Index index_0 (a.bases_1d[0]->get_dimensions()) ;
857  res.bases_1d[0] = new Array<int> (a.bases_1d[0]->get_dimensions()) ;
858  do {
859  switch ((*a.bases_1d[0])(index_0)) {
860  case CHEB:
861  switch ((*b.bases_1d[0])(index_0)) {
862  case CHEB:
863  res.bases_1d[0]->set(index_0) = CHEB ;
864  break ;
865  default:
866  res_def = false ;
867  break ;
868  }
869  break ;
870  case LEG:
871  switch ((*b.bases_1d[0])(index_0)) {
872  case LEG:
873  res.bases_1d[0]->set(index_0) = LEG ;
874  break ;
875  default:
876  res_def = false ;
877  break ;
878  }
879  break ;
880  default:
881  res_def = false ;
882  break ;
883  }
884  }
885  while (index_0.inc()) ;
886  }
887 
888  if (!res_def)
889  for (int dim=0 ; dim<a.ndim ; dim++)
890  if (res.bases_1d[dim]!= 0x0) {
891  delete res.bases_1d[dim] ;
892  res.bases_1d[dim] = 0x0 ;
893  }
894  res.def = res_def ;
895  return res ;
896 }
897 
898 int Domain_compact::give_place_var (char* p) const {
899  int res = -1 ;
900  if (strcmp(p,"R ")==0)
901  res = 0 ;
902  if (strcmp(p,"T ")==0)
903  res = 1 ;
904  if (strcmp(p,"P ")==0)
905  res = 2 ;
906  return res ;
907 }}
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
int & set(int i)
Read/write of the size of a given dimension.
Definition: dim_array.hpp:54
void save(FILE *) const
Save function.
Definition: dim_array.cpp:32
Class for a spherical compactified domain and a symmetry with respect to the plane .
Definition: spheric.hpp:1007
virtual double val_boundary(int, const Val_domain &, const Index &) const
Computes the value of a field at a boundary.
virtual void set_legendre_r_base(Base_spectral &) const
Gives the base using odd Legendre polynomials$ for the radius.
virtual ostream & print(ostream &o) const
Delegate function to virtualize the << operator.
virtual void set_cheb_base(Base_spectral &so) const
Sets the base to the standard one for Chebyshev polynomials.
virtual void do_coloc()
Computes the colocation points.
virtual Val_domain der_normal(const Val_domain &, int) const
Normal derivative with respect to a given surface.
virtual Val_domain mult_sin_phi(const Val_domain &) const
Multiplication by .
virtual void set_val_inf(Val_domain &, double) const
Sets the value at infinity of a Val_domain : not implemented for this type of Domain.
virtual const Point absol_to_num_bound(const Point &, int) const
Computes the numerical coordinates from the physical ones for a point lying on a boundary.
virtual void save(FILE *) const
Saving function.
virtual void do_cart() const
Computes the Cartesian coordinates.
virtual void set_cheb_base_r_mtz(Base_spectral &) const
Gives the base using Chebyshev polynomials, for the radial component of a vector in the MTZ setting.
virtual void set_legendre_base_t_mtz(Base_spectral &) const
Gives the base using Legendre polynomials, for the component of a vector in the MTZ context.
virtual Val_domain mult_cos_theta(const Val_domain &) const
Multiplication by .
double alpha
Relates the numerical to the physical radii.
Definition: spheric.hpp:1010
virtual Val_domain div_sin_theta(const Val_domain &) const
Division by .
virtual Val_domain mult_r(const Val_domain &) const
Multiplication by .
Point center
Absolute coordinates of the center.
Definition: spheric.hpp:1011
Domain_compact(int num, int ttype, double r_int, const Point &cr, const Dim_array &nbr)
Standard constructor :
virtual void do_cart_surr() const
Computes the Cartesian coordinates over the radius.
virtual const Point absol_to_num(const Point &xxx) const
Computes the numerical coordinates from the physical ones.
virtual Val_domain mult_sin_theta(const Val_domain &) const
Multiplication by .
virtual void set_cheb_base_p_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 set_legendre_base_r_mtz(Base_spectral &) const
Gives the base using Legendre polynomials, for the radial component of a vector in the MTZ context.
virtual void do_absol() const
Computes the absolute coordinates.
virtual void set_legendre_base_p_mtz(Base_spectral &) const
Gives the base using Legendre polynomials, for the component of a vector in the MTZ context.
virtual Val_domain mult_cos_phi(const Val_domain &) const
Multiplication by .
virtual void set_cheb_base_p_mtz(Base_spectral &) const
Gives the base using Chebyshev polynomials, for the component of a vector in the MTZ setting.
virtual void set_cheb_base_t_mtz(Base_spectral &) const
Gives the base using Chebyshev polynomials, for the component of a vector in the MTZ setting.
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 &so) const
Sets the base to the standard one for Legendre polynomials for functions antisymetric in The bases a...
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 int give_place_var(char *) const
Translates a name of a coordinate into its corresponding numerical name.
virtual void set_anti_cheb_base(Base_spectral &so) const
Sets the base to the standard one for Chebyshev polynomials for functions antisymetric in The bases ...
virtual void set_legendre_base(Base_spectral &so) const
Sets the base to the standard one for Legendre polynomials.
virtual Val_domain mult_xm1(const Val_domain &) const
Multiplication by .
virtual bool is_in(const Point &xx, double prec=1e-13) const
Check whether a point lies inside Domain.
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 void set_legendre_base_t_spher(Base_spectral &) const
Gives the base using Legendre polynomials, for the component of a vector.
virtual void set_cheb_r_base(Base_spectral &) const
Gives the base using odd Chebyshev polynomials$ for the radius.
virtual double integ(const Val_domain &, int) const
Surface integral on a given boundary.
virtual void do_radius() const
Computes the generalized radius.
virtual void set_cheb_base_with_m(Base_spectral &so, int m) const
Gives the standard base using Chebyshev polynomials.
virtual void set_legendre_base_p_spher(Base_spectral &) const
Gives the base using Legendre polynomials, for the component of a vector.
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 * > cart
Cartesian coordinates.
Definition: space.hpp:77
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
Memory_mapped_array< Val_domain * > cart_surr
Cartesian coordinates divided by the radius.
Definition: space.hpp:79
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
bool inc1(int var)
Increment on one dimension.
Definition: index.hpp:114
The class Point is used to store the coordinates of a point.
Definition: point.hpp:30
void save(FILE *) const
Saving function.
Definition: point.cpp:33
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
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_phi() const
Multiplication by .
void set_in_conf()
Destroys the values in the coefficient space.
Definition: val_domain.cpp:197
bool check_if_zero() const
Check whether the logical state is zero or not.
Definition: val_domain.hpp:142
Val_domain mult_sin_theta() const
Multiplication by .
Val_domain mult_cos_phi() const
Multiplication by .
void coef_i() const
Computes the values in the configuration space.
Definition: val_domain.cpp:637
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 mult_xm1() 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
const Domain * get_domain() const
Definition: val_domain.hpp:111
const Base_spectral & get_base() const
Returns the basis of decomposition.
Definition: val_domain.hpp:122