KADATH
domain_compact_symphi.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 "spheric_symphi.hpp"
23 #include "array_math.hpp"
24 #include "val_domain.hpp"
25 namespace Kadath {
26 // Standard constructor
27 Domain_compact_symphi::Domain_compact_symphi (int num, int ttype, double r, const Point& cr, const Dim_array& nbr) : Domain(num, ttype, nbr), alpha(-0.5/r),
28  center(cr) {
29 
30  assert (nbr.get_ndim()==3) ;
31  assert (cr.get_ndim()==3) ;
32  do_coloc() ;
33 
34 }
35 
36 // Copy constructor
37 Domain_compact_symphi::Domain_compact_symphi (const Domain_compact_symphi& so) : Domain(so), alpha(so.alpha), center(so.center){}
38 
39 
40 Domain_compact_symphi::Domain_compact_symphi (int num, FILE* fd) : Domain(num, fd), center(fd) {
41  fread_be (&alpha, sizeof(double), 1, fd) ;
42  do_coloc() ;
43 }
44 
45 // Destructor
46 Domain_compact_symphi::~Domain_compact_symphi() {}
47 
48 ostream& Domain_compact_symphi::print (ostream& o) const {
49  o << "Compactified domain sym phi" << endl ;
50  o << "Rmin = " << -0.5/alpha << endl ;
51  o << "Center = " << center << endl ;
52  o << "Nbr pts = " << nbr_points << endl ;
53  o << endl ;
54  return o ;
55 }
56 
57 void Domain_compact_symphi::save (FILE* fd) const {
58  nbr_points.save(fd) ;
59  nbr_coefs.save(fd) ;
60  fwrite_be (&ndim, sizeof(int), 1, fd) ;
61  fwrite_be (&type_base, sizeof(int), 1, fd) ;
62  center.save(fd) ;
63  fwrite_be (&alpha, sizeof(double), 1, fd) ;
64 }
65 
66 
68 
69  Val_domain res (so.der_var(1)) ;
70  switch (bound) {
71  case INNER_BC :
72  res = res.mult_xm1() ;
73  res = res.mult_xm1() ;
74  res *= -alpha ;
75  break ;
76  case OUTER_BC :
77  res = res.mult_xm1() ;
78  res = res.mult_xm1() ;
79  res *= -alpha ;
80  break ;
81  default:
82  cerr << "Unknown boundary case in Domain_compact_symphi::der_normal" << endl ;
83  abort() ;
84  }
85 return res ;
86 }
87 
88 double Domain_compact_symphi::integ (const Val_domain& so, int bound) const {
89  double res = 0 ;
90 
91  if (bound!=OUTER_BC) {
92  cerr << "Domain_compact_symphi::integ only defined for r=infty yet..." << endl ;
93  abort() ;
94  }
95 
96  int baset = (*so.base.bases_1d[1]) (0) ;
97  if (baset != COS_EVEN) {
98  // Odd function
99  return res ;
100  }
101  else {
102 
103  Val_domain auxi (so.div_xm1()) ;
104  auxi = auxi.div_xm1() ;
105  auxi /= alpha * alpha ;
106  auxi.coef() ;
107 
108  //Loop on theta :
109  Index pos (get_nbr_coefs()) ;
110  pos.set(2) = 0 ;
111  for (int j=0 ; j<nbr_coefs(1) ; j++) {
112  pos.set(1) = j ;
113  double fact_tet = 2./double(1-4*j*j) ;
114  // Loop on r :
115  for (int i=0 ; i<nbr_coefs(0) ; i++) {
116  pos.set(0) = i ;
117  res += fact_tet*(*auxi.cf)(pos) ;
118  }
119  }
120  return res*2*M_PI ;
121  }
122 }
123 
124 // Computes the Cartesian coordinates
126  for (int i=0 ; i<3 ; i++)
127  assert (coloc[i] != 0x0) ;
128  for (int i=0 ; i<3 ; i++)
129  assert (absol[i] == 0x0) ;
130  for (int i=0 ; i<3 ; i++) {
131  absol[i] = new Val_domain(this) ;
132  absol[i]->allocate_conf() ;
133  }
134  Index index (nbr_points) ;
135  do {
136  absol[0]->set(index) = (1./alpha/ ((*coloc[0])(index(0))-1)) *
137  sin((*coloc[1])(index(1)))*cos((*coloc[2])(index(2))) + center(1) ;
138  absol[1]->set(index) = (1./alpha/ ((*coloc[0])(index(0))-1)) *
139  sin((*coloc[1])(index(1)))*sin((*coloc[2])(index(2))) + center(2) ;
140  absol[2]->set(index) = (1./alpha/ ((*coloc[0])(index(0))-1)) * cos((*coloc[1])(index(1))) +
141  center(3) ;
142  }
143  while (index.inc()) ;
144 }
145 
146 // Computes the radius
148  for (int i=0 ; i<3 ; i++)
149  assert (coloc[i] != 0x0) ;
150  assert (radius == 0x0) ;
151  radius = new Val_domain(this) ;
152  radius->allocate_conf() ;
153  Index index (nbr_points) ;
154  do
155  radius->set(index) = 1./alpha/ ((*coloc[0])(index(0))-1) ;
156  while (index.inc()) ;
157 }
158 
159 // Computes the Cartesian coordinates
161  for (int i=0 ; i<3 ; i++)
162  assert (coloc[i] != 0x0) ;
163  for (int i=0 ; i<3 ; i++)
164  assert (cart[i] == 0x0) ;
165  for (int i=0 ; i<3 ; i++) {
166  cart[i] = new Val_domain(this) ;
167  cart[i]->allocate_conf() ;
168  }
169  Index index (nbr_points) ;
170  do {
171  cart[0]->set(index) = (1./alpha/ ((*coloc[0])(index(0))-1)) *
172  sin((*coloc[1])(index(1)))*cos((*coloc[2])(index(2))) + center(1) ;
173  cart[1]->set(index) = (1./alpha/ ((*coloc[0])(index(0))-1)) *
174  sin((*coloc[1])(index(1)))*sin((*coloc[2])(index(2))) + center(2) ;
175  cart[2]->set(index) = (1./alpha/ ((*coloc[0])(index(0))-1)) * cos((*coloc[1])(index(1))) +
176  center(3) ;
177  }
178  while (index.inc()) ;
179 
180  switch (type_base) {
181  case CHEB_TYPE:
182  set_cheb_base_forx_cart(cart[0]->set_base()) ;
183  set_cheb_base_fory_cart(cart[1]->set_base()) ;
184  set_cheb_base_forz_cart(cart[2]->set_base()) ;
185  break ;
186  case LEG_TYPE:
187  set_legendre_base_forx_cart(cart[0]->set_base()) ;
188  set_legendre_base_fory_cart(cart[1]->set_base()) ;
189  set_legendre_base_forz_cart(cart[2]->set_base()) ;
190  break ;
191  default :
192  cerr << "Unknown type of basis in Domain_compact_symphi::do_cart" << endl ;
193  abort() ;
194  }
195 }
196 
197 // Computes the Cartesian coordinates ovzr radius
199  for (int i=0 ; i<3 ; i++)
200  assert (coloc[i] != 0x0) ;
201  for (int i=0 ; i<3 ; i++)
202  assert (cart_surr[i] == 0x0) ;
203  for (int i=0 ; i<3 ; i++) {
204  cart_surr[i] = new Val_domain(this) ;
205  cart_surr[i]->allocate_conf() ;
206  }
207  Index index (nbr_points) ;
208  do {
209  cart_surr[0]->set(index) = sin((*coloc[1])(index(1)))*cos((*coloc[2])(index(2))) ;
210  cart_surr[1]->set(index) = sin((*coloc[1])(index(1)))*sin((*coloc[2])(index(2))) ;
211  cart_surr[2]->set(index) = cos((*coloc[1])(index(1))) ;
212  }
213  while (index.inc()) ;
214 
215  switch (type_base) {
216  case CHEB_TYPE:
217  set_cheb_base_forx_cart(cart_surr[0]->set_base()) ;
218  set_cheb_base_fory_cart(cart_surr[1]->set_base()) ;
219  set_cheb_base_forz_cart(cart_surr[2]->set_base()) ;
220  break ;
221  case LEG_TYPE:
222  set_legendre_base_forx_cart(cart_surr[0]->set_base()) ;
223  set_legendre_base_fory_cart(cart_surr[1]->set_base()) ;
224  set_legendre_base_forz_cart(cart_surr[2]->set_base()) ;
225  break ;
226  default :
227  cerr << "Unknown type of basis in Domain_compact_symphi::do_cart_surr" << endl ;
228  abort() ;
229  }
230 }
231 
232 // Is inside ?
233 bool Domain_compact_symphi::is_in (const Point& xx, double prec) const {
234 
235  assert (xx.get_ndim()==3) ;
236 
237  double x_loc = xx(1) - center(1) ;
238  double y_loc = xx(2) - center(2) ;
239  double z_loc = xx(3) - center(3) ;
240  double air_loc = sqrt (x_loc*x_loc + y_loc*y_loc + z_loc*z_loc) ;
241 
242  bool res = (air_loc >= -0.5/alpha-prec) ? true : false ;
243  return res ;
244 }
245 
246 // Converts the absolute coordinates to the numerical ones.
248 
249  assert (is_in(abs)) ;
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  double air = sqrt(x_loc*x_loc+y_loc*y_loc+z_loc*z_loc) ;
256  num.set(1) = 1. + 1./air/alpha ;
257  double rho = sqrt(x_loc*x_loc+y_loc*y_loc) ;
258 
259  if (rho==0) {
260  // On the axis ?
261  num.set(2) = (z_loc>=0) ? 0 : M_PI ;
262  num.set(3) = 0 ;
263  }
264  else {
265  num.set(2) = atan(rho/z_loc) ;
266  num.set(3) = atan2 (y_loc, x_loc) ;
267  }
268 
269  if (num(2) <0)
270  num.set(2) = M_PI + num(2) ;
271 
272  return num ;
273 }
274 
275 
276 // Convert absolute coordinates to numerical ones
277 const Point Domain_compact_symphi::absol_to_num_bound(const Point& abs, int bound) const {
278 
279  assert (bound==INNER_BC) ;
280  assert (is_in(abs, 1e-3)) ;
281  Point num(3) ;
282 
283  double x_loc = abs(1) - center(1) ;
284  double y_loc = abs(2) - center(2) ;
285  double z_loc = abs(3) - center(3) ;
286  num.set(1) = -1 ;
287  double rho = sqrt(x_loc*x_loc+y_loc*y_loc) ;
288 
289  if (rho==0) {
290  // Sur l'axe
291  num.set(2) = (z_loc>=0) ? 0 : M_PI ;
292  num.set(3) = 0 ;
293  }
294  else {
295  num.set(2) = atan(rho/z_loc) ;
296  num.set(3) = atan2 (y_loc, x_loc) ;
297  }
298 
299  if (num(2) <0)
300  num.set(2) = M_PI + num(2) ;
301 
302  return num ;
303 }
304 
305 double coloc_leg(int,int) ;
307 
308  switch (type_base) {
309  case CHEB_TYPE:
311  del_deriv() ;
312  for (int i=0 ; i<ndim ; i++)
313  coloc[i] = new Array<double> (nbr_points(i)) ;
314  for (int i=0 ; i<nbr_points(0) ; i++)
315  coloc[0]->set(i) = -cos(M_PI*i/(nbr_points(0)-1)) ;
316  for (int j=0 ; j<nbr_points(1) ; j++)
317  coloc[1]->set(j) = M_PI/2.*j/(nbr_points(1)-1) ;
318  for (int k=0 ; k<nbr_points(2) ; k++)
319  coloc[2]->set(k) = M_PI/2.*k/(nbr_points(2)-1) ;
320  break ;
321  case LEG_TYPE:
323  del_deriv() ;
324  for (int i=0 ; i<ndim ; i++)
325  coloc[i] = new Array<double> (nbr_points(i)) ;
326  for (int i=0 ; i<nbr_points(0) ; i++)
327  coloc[0]->set(i) = coloc_leg(i, nbr_points(0)) ;
328  for (int j=0 ; j<nbr_points(1) ; j++)
329  coloc[1]->set(j) = M_PI/2.*j/(nbr_points(1)-1) ;
330  for (int k=0 ; k<nbr_points(2) ; k++)
331  coloc[2]->set(k) = M_PI/2.*k/(nbr_points(2)-1) ;
332  break ;
333  default :
334  cerr << "Unknown type of basis in Domain_compact_symphi::do_coloc" << endl ;
335  abort() ;
336  }
337 }
338 
339 
340 // Base for a function symetric in z, using Chebyshev
342 
343  assert (type_base == CHEB_TYPE) ;
344  base.allocate(nbr_coefs) ;
345 
346  Index index(base.bases_1d[0]->get_dimensions()) ;
347 
348  base.def=true ;
349  base.bases_1d[2]->set(0) = COS_EVEN ;
350  for (int k=0 ; k<nbr_coefs(2) ; k++) {
351  base.bases_1d[1]->set(k) = COS_EVEN ;
352  for (int j=0 ; j<nbr_coefs(1) ; j++) {
353  index.set(0) = j ; index.set(1) = k ;
354  base.bases_1d[0]->set(index) = CHEB ;
355  }
356  }
357 }
358 
359 
361 
362  assert (type_base == CHEB_TYPE) ;
363  base.allocate(nbr_coefs) ;
364 
365  Index index(base.bases_1d[0]->get_dimensions()) ;
366 
367  base.def=true ;
368  base.bases_1d[2]->set(0) = SIN_EVEN ;
369  for (int k=0 ; k<nbr_coefs(2) ; k++) {
370  base.bases_1d[1]->set(k) = COS_EVEN ;
371  for (int j=0 ; j<nbr_coefs(1) ; j++) {
372  index.set(0) = j ; index.set(1) = k ;
373  base.bases_1d[0]->set(index) = CHEB ;
374  }
375  }
376 }
377 
379 
380  assert (type_base == CHEB_TYPE) ;
381  base.allocate(nbr_coefs) ;
382 
383  Index index(base.bases_1d[0]->get_dimensions()) ;
384 
385  base.def=true ;
386  base.bases_1d[2]->set(0) = SIN_EVEN ;
387  for (int k=0 ; k<nbr_coefs(2) ; k++) {
388  base.bases_1d[1]->set(k) = SIN_EVEN ;
389  for (int j=0 ; j<nbr_coefs(1) ; j++) {
390  index.set(0) = j ; index.set(1) = k ;
391  base.bases_1d[0]->set(index) = CHEB ;
392  }
393  }
394 }
395 
397 
398  assert (type_base == CHEB_TYPE) ;
399  base.allocate(nbr_coefs) ;
400 
401  Index index(base.bases_1d[0]->get_dimensions()) ;
402 
403  base.def=true ;
404  base.bases_1d[2]->set(0) = COS_EVEN ;
405  for (int k=0 ; k<nbr_coefs(2) ; k++) {
406  base.bases_1d[1]->set(k) = SIN_ODD ;
407  for (int j=0 ; j<nbr_coefs(1) ; j++) {
408  index.set(0) = j ; index.set(1) = k ;
409  base.bases_1d[0]->set(index) = CHEB ;
410  }
411  }
412 }
413 
415 
416  assert (type_base == CHEB_TYPE) ;
417  base.allocate(nbr_coefs) ;
418 
419  Index index(base.bases_1d[0]->get_dimensions()) ;
420 
421  base.def=true ;
422  base.bases_1d[2]->set(0) = SIN_ODD ;
423  for (int k=0 ; k<nbr_coefs(2) ; k++) {
424  base.bases_1d[1]->set(k) = SIN_ODD ;
425  for (int j=0 ; j<nbr_coefs(1) ; j++) {
426  index.set(0) = j ; index.set(1) = k ;
427  base.bases_1d[0]->set(index) = CHEB ;
428  }
429  }
430 }
431 
433 
434  assert (type_base == CHEB_TYPE) ;
435  base.allocate(nbr_coefs) ;
436 
437  Index index(base.bases_1d[0]->get_dimensions()) ;
438 
439  base.def=true ;
440  base.bases_1d[2]->set(0) = COS_ODD ;
441  for (int k=0 ; k<nbr_coefs(2) ; k++) {
442  base.bases_1d[1]->set(k) = SIN_ODD ;
443  for (int j=0 ; j<nbr_coefs(1) ; j++) {
444  index.set(0) = j ; index.set(1) = k ;
445  base.bases_1d[0]->set(index) = CHEB ;
446  }
447  }
448 }
449 
450 
452 
453  assert (type_base == CHEB_TYPE) ;
454  base.allocate(nbr_coefs) ;
455 
456  Index index(base.bases_1d[0]->get_dimensions()) ;
457 
458  base.def=true ;
459  base.bases_1d[2]->set(0) = SIN_EVEN ;
460  for (int k=0 ; k<nbr_coefs(2) ; k++) {
461  base.bases_1d[1]->set(k) = COS_ODD ;
462  for (int j=0 ; j<nbr_coefs(1) ; j++) {
463  index.set(0) = j ; index.set(1) = k ;
464  base.bases_1d[0]->set(index) = CHEB ;
465  }
466  }
467 }
468 
469 
470 
472 
473  assert (type_base == CHEB_TYPE) ;
474  base.allocate(nbr_coefs) ;
475 
476  Index index(base.bases_1d[0]->get_dimensions()) ;
477 
478  base.def=true ;
479  base.bases_1d[2]->set(0) = COS_ODD ;
480  for (int k=0 ; k<nbr_coefs(2) ; k++) {
481  base.bases_1d[1]->set(k) = SIN_ODD ;
482  for (int j=0 ; j<nbr_coefs(1) ; j++) {
483  index.set(0) = j ; index.set(1) = k ;
484  base.bases_1d[0]->set(index) = CHEB ;
485  }
486  }
487 }
488 
490 
491  assert (type_base == CHEB_TYPE) ;
492  base.allocate(nbr_coefs) ;
493 
494  Index index(base.bases_1d[0]->get_dimensions()) ;
495 
496  base.def=true ;
497  base.bases_1d[2]->set(0) = SIN_ODD ;
498  for (int k=0 ; k<nbr_coefs(2) ; k++) {
499  base.bases_1d[1]->set(k) = SIN_ODD ;
500  for (int j=0 ; j<nbr_coefs(1) ; j++) {
501  index.set(0) = j ; index.set(1) = k ;
502  base.bases_1d[0]->set(index) = CHEB ;
503  }
504  }
505 }
506 
507 
509 
510  assert (type_base == CHEB_TYPE) ;
511  base.allocate(nbr_coefs) ;
512 
513  Index index(base.bases_1d[0]->get_dimensions()) ;
514 
515  base.def=true ;
516  base.bases_1d[2]->set(0) = COS_EVEN ;
517  for (int k=0 ; k<nbr_coefs(2) ; k++) {
518  base.bases_1d[1]->set(k) = COS_ODD ;
519  for (int j=0 ; j<nbr_coefs(1) ; j++) {
520  index.set(0) = j ; index.set(1) = k ;
521  base.bases_1d[0]->set(index) = CHEB ;
522  }
523  }
524 }
525 
526 // Base for a function symetric in z, using Legendre
528 
529  assert (type_base == LEG_TYPE) ;
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) = COS_EVEN ;
536  for (int k=0 ; k<nbr_coefs(2) ; k++) {
537  base.bases_1d[1]->set(k) = COS_EVEN ;
538  for (int j=0 ; j<nbr_coefs(1) ; j++) {
539  index.set(0) = j ; index.set(1) = k ;
540  base.bases_1d[0]->set(index) = LEG ;
541  }
542  }
543 }
544 
545 
547 
548  assert (type_base == LEG_TYPE) ;
549  base.allocate(nbr_coefs) ;
550 
551  Index index(base.bases_1d[0]->get_dimensions()) ;
552 
553  base.def=true ;
554  base.bases_1d[2]->set(0) = SIN_EVEN ;
555  for (int k=0 ; k<nbr_coefs(2) ; k++) {
556  base.bases_1d[1]->set(k) = COS_EVEN ;
557  for (int j=0 ; j<nbr_coefs(1) ; j++) {
558  index.set(0) = j ; index.set(1) = k ;
559  base.bases_1d[0]->set(index) = LEG ;
560  }
561  }
562 }
563 
565 
566  assert (type_base == LEG_TYPE) ;
567  base.allocate(nbr_coefs) ;
568 
569  Index index(base.bases_1d[0]->get_dimensions()) ;
570 
571  base.def=true ;
572  base.bases_1d[2]->set(0) = SIN_EVEN ;
573  for (int k=0 ; k<nbr_coefs(2) ; k++) {
574  base.bases_1d[1]->set(k) = SIN_EVEN ;
575  for (int j=0 ; j<nbr_coefs(1) ; j++) {
576  index.set(0) = j ; index.set(1) = k ;
577  base.bases_1d[0]->set(index) = LEG ;
578  }
579  }
580 }
581 
583 
584  assert (type_base == LEG_TYPE) ;
585  base.allocate(nbr_coefs) ;
586 
587  Index index(base.bases_1d[0]->get_dimensions()) ;
588 
589  base.def=true ;
590  base.bases_1d[2]->set(0) = COS_EVEN ;
591  for (int k=0 ; k<nbr_coefs(2) ; k++) {
592  base.bases_1d[1]->set(k) = SIN_ODD ;
593  for (int j=0 ; j<nbr_coefs(1) ; j++) {
594  index.set(0) = j ; index.set(1) = k ;
595  base.bases_1d[0]->set(index) = LEG ;
596  }
597  }
598 }
599 
601 
602  assert (type_base == LEG_TYPE) ;
603  base.allocate(nbr_coefs) ;
604 
605  Index index(base.bases_1d[0]->get_dimensions()) ;
606 
607  base.def=true ;
608  base.bases_1d[2]->set(0) = SIN_ODD ;
609  for (int k=0 ; k<nbr_coefs(2) ; k++) {
610  base.bases_1d[1]->set(k) = SIN_ODD ;
611  for (int j=0 ; j<nbr_coefs(1) ; j++) {
612  index.set(0) = j ; index.set(1) = k ;
613  base.bases_1d[0]->set(index) = LEG ;
614  }
615  }
616 }
617 
619 
620  assert (type_base == LEG_TYPE) ;
621  base.allocate(nbr_coefs) ;
622 
623  Index index(base.bases_1d[0]->get_dimensions()) ;
624 
625  base.def=true ;
626  base.bases_1d[2]->set(0) = COS_ODD ;
627  for (int k=0 ; k<nbr_coefs(2) ; k++) {
628  base.bases_1d[1]->set(k) = SIN_ODD ;
629  for (int j=0 ; j<nbr_coefs(1) ; j++) {
630  index.set(0) = j ; index.set(1) = k ;
631  base.bases_1d[0]->set(index) = LEG ;
632  }
633  }
634 }
635 
636 
638 
639  assert (type_base == LEG_TYPE) ;
640  base.allocate(nbr_coefs) ;
641 
642  Index index(base.bases_1d[0]->get_dimensions()) ;
643 
644  base.def=true ;
645  base.bases_1d[2]->set(0) = SIN_EVEN ;
646  for (int k=0 ; k<nbr_coefs(2) ; k++) {
647  base.bases_1d[1]->set(k) = COS_ODD ;
648  for (int j=0 ; j<nbr_coefs(1) ; j++) {
649  index.set(0) = j ; index.set(1) = k ;
650  base.bases_1d[0]->set(index) = LEG ;
651  }
652  }
653 }
654 
656 
657  assert (type_base == LEG_TYPE) ;
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) = COS_ODD ;
664  for (int k=0 ; k<nbr_coefs(2) ; k++) {
665  base.bases_1d[1]->set(k) = SIN_ODD ;
666  for (int j=0 ; j<nbr_coefs(1) ; j++) {
667  index.set(0) = j ; index.set(1) = k ;
668  base.bases_1d[0]->set(index) = LEG ;
669  }
670  }
671 }
672 
674 
675  assert (type_base == LEG_TYPE) ;
676  base.allocate(nbr_coefs) ;
677 
678  Index index(base.bases_1d[0]->get_dimensions()) ;
679 
680  base.def=true ;
681  base.bases_1d[2]->set(0) = SIN_ODD ;
682  for (int k=0 ; k<nbr_coefs(2) ; k++) {
683  base.bases_1d[1]->set(k) = SIN_ODD ;
684  for (int j=0 ; j<nbr_coefs(1) ; j++) {
685  index.set(0) = j ; index.set(1) = k ;
686  base.bases_1d[0]->set(index) = LEG ;
687  }
688  }
689 }
690 
691 
693 
694  assert (type_base == LEG_TYPE) ;
695  base.allocate(nbr_coefs) ;
696 
697  Index index(base.bases_1d[0]->get_dimensions()) ;
698 
699  base.def=true ;
700  base.bases_1d[2]->set(0) = COS_EVEN ;
701  for (int k=0 ; k<nbr_coefs(2) ; k++) {
702  base.bases_1d[1]->set(k) = COS_ODD ;
703  for (int j=0 ; j<nbr_coefs(1) ; j++) {
704  index.set(0) = j ; index.set(1) = k ;
705  base.bases_1d[0]->set(index) = LEG ;
706  }
707  }
708 }
709 
710 // sets the value at infinity
711 void Domain_compact_symphi::set_val_inf (Val_domain& so, double x) const {
712 
713  assert (so.get_domain() == this) ;
714 
715  so.coef_i() ;
716  so.set_in_conf() ;
717  Index inf (nbr_points) ;
718  inf.set(0) = nbr_points(0)-1 ;
719  do
720  so.set(inf) = x ;
721  while (inf.inc1(1)) ;
722 }
723 
724 // Computes the derivatives with respect to XYZ as function of the numerical ones.
725 void Domain_compact_symphi::do_der_abs_from_der_var(const Val_domain *const *const der_var, Val_domain **const der_abs) const {
726 
727  // d/dx :
728  Val_domain dr (-der_var[0]->mult_xm1()) ;
729  Val_domain sintdr (dr.mult_sin_theta()) ;
730  Val_domain costdt (der_var[1]->mult_cos_theta()) ;
731 
732  Val_domain dpssint (der_var[2]->div_sin_theta()) ;
733 
734  Val_domain auxi_x ((sintdr+costdt).mult_cos_phi() - dpssint.mult_sin_phi()) ;
735  der_abs[0] = new Val_domain (alpha*auxi_x.mult_xm1()) ;
736 
737  // d/dy :
738  Val_domain auxi_y ((sintdr+costdt).mult_sin_phi() + dpssint.mult_cos_phi()) ;
739  der_abs[1] = new Val_domain (alpha*auxi_y.mult_xm1()) ;
740  // d/dz :
741  Val_domain auxi_z (dr.mult_cos_theta() - der_var[1]->mult_sin_theta()) ;
742  der_abs[2] = new Val_domain (alpha*auxi_z.mult_xm1()) ;
743 
744 }
745 
746 // Rules for basis multiplication
748 
749  assert (a.ndim==3) ;
750  assert (b.ndim==3) ;
751 
752  Base_spectral res(3) ;
753  bool res_def = true ;
754 
755  if (!a.def)
756  res_def=false ;
757  if (!b.def)
758  res_def=false ;
759 
760  if (res_def) {
761 
762 
763  // Base in phi :
764  res.bases_1d[2] = new Array<int> (a.bases_1d[2]->get_dimensions()) ;
765  switch ((*a.bases_1d[2])(0)) {
766  case COS_EVEN:
767  switch ((*b.bases_1d[2])(0)) {
768  case COS_EVEN:
769  res.bases_1d[2]->set(0) = COS_EVEN ;
770  break ;
771  case COS_ODD:
772  res.bases_1d[2]->set(0) = COS_ODD ;
773  break ;
774  case SIN_EVEN:
775  res.bases_1d[2]->set(0) = SIN_EVEN ;
776  break ;
777  case SIN_ODD:
778  res.bases_1d[2]->set(0) = SIN_ODD ;
779  break ;
780 
781  default:
782  res_def = false ;
783  break ;
784  }
785  break ;
786 
787 
788  case COS_ODD:
789  switch ((*b.bases_1d[2])(0)) {
790  case COS_EVEN:
791  res.bases_1d[2]->set(0) = COS_ODD ;
792  break ;
793  case COS_ODD:
794  res.bases_1d[2]->set(0) = COS_EVEN ;
795  break ;
796  case SIN_EVEN:
797  res.bases_1d[2]->set(0) = SIN_ODD ;
798  break ;
799  case SIN_ODD:
800  res.bases_1d[2]->set(0) = SIN_EVEN ;
801  break ;
802 
803  default:
804  res_def = false ;
805  break ;
806  }
807  break ;
808  case SIN_ODD:
809  switch ((*b.bases_1d[2])(0)) {
810  case COS_EVEN:
811  res.bases_1d[2]->set(0) = SIN_ODD ;
812  break ;
813  case COS_ODD:
814  res.bases_1d[2]->set(0) = SIN_EVEN ;
815  break ;
816  case SIN_EVEN:
817  res.bases_1d[2]->set(0) = COS_ODD ;
818  break ;
819  case SIN_ODD:
820  res.bases_1d[2]->set(0) = COS_EVEN ;
821  break ;
822 
823  default:
824  res_def = false ;
825  break ;
826  }
827  break ;
828  case SIN_EVEN:
829  switch ((*b.bases_1d[2])(0)) {
830  case COS_EVEN:
831  res.bases_1d[2]->set(0) = SIN_EVEN ;
832  break ;
833  case COS_ODD:
834  res.bases_1d[2]->set(0) = SIN_ODD ;
835  break ;
836  case SIN_EVEN:
837  res.bases_1d[2]->set(0) = COS_EVEN ;
838  break ;
839  case SIN_ODD:
840  res.bases_1d[2]->set(0) = COS_ODD ;
841  break ;
842 
843  default:
844  res_def = false ;
845  break ;
846  }
847  break ;
848 
849  default:
850  res_def = false ;
851  break ;
852  }
853 
854  // Bases in theta :
855  // On check l'alternance :
856  Index index_1 (a.bases_1d[1]->get_dimensions()) ;
857  res.bases_1d[1] = new Array<int> (a.bases_1d[1]->get_dimensions()) ;
858  do {
859  switch ((*a.bases_1d[1])(index_1)) {
860  case COS_EVEN:
861  switch ((*b.bases_1d[1])(index_1)) {
862  case COS_EVEN:
863  res.bases_1d[1]->set(index_1) = COS_EVEN ;
864  break ;
865  case COS_ODD:
866  res.bases_1d[1]->set(index_1) = COS_ODD ;
867  break ;
868  case SIN_EVEN:
869  res.bases_1d[1]->set(index_1) = SIN_EVEN ;
870  break ;
871  case SIN_ODD:
872  res.bases_1d[1]->set(index_1) = SIN_ODD ;
873  break ;
874 
875  default:
876  res_def = false ;
877  break ;
878  }
879  break ;
880 
881 
882  case COS_ODD:
883  switch ((*b.bases_1d[1])(index_1)) {
884  case COS_EVEN:
885  res.bases_1d[1]->set(index_1) = COS_ODD ;
886  break ;
887  case COS_ODD:
888  res.bases_1d[1]->set(index_1) = COS_EVEN ;
889  break ;
890  case SIN_EVEN:
891  res.bases_1d[1]->set(index_1) = SIN_ODD ;
892  break ;
893  case SIN_ODD:
894  res.bases_1d[1]->set(index_1) = SIN_EVEN ;
895  break ;
896 
897  default:
898  res_def = false ;
899  break ;
900  }
901  break ;
902  case SIN_ODD:
903  switch ((*b.bases_1d[1])(index_1)) {
904  case COS_EVEN:
905  res.bases_1d[1]->set(index_1) = SIN_ODD ;
906  break ;
907  case COS_ODD:
908  res.bases_1d[1]->set(index_1) = SIN_EVEN ;
909  break ;
910  case SIN_EVEN:
911  res.bases_1d[1]->set(index_1) = COS_ODD ;
912  break ;
913  case SIN_ODD:
914  res.bases_1d[1]->set(index_1) = COS_EVEN ;
915  break ;
916 
917  default:
918  res_def = false ;
919  break ;
920  }
921  break ;
922  case SIN_EVEN:
923  switch ((*b.bases_1d[1])(index_1)) {
924  case COS_EVEN:
925  res.bases_1d[1]->set(index_1) = SIN_EVEN ;
926  break ;
927  case COS_ODD:
928  res.bases_1d[1]->set(index_1) = SIN_ODD ;
929  break ;
930  case SIN_EVEN:
931  res.bases_1d[1]->set(index_1) = COS_EVEN ;
932  break ;
933  case SIN_ODD:
934  res.bases_1d[1]->set(index_1) = COS_ODD ;
935  break ;
936 
937  default:
938  res_def = false ;
939  break ;
940  }
941  break ;
942 
943  default:
944  res_def = false ;
945  break ;
946  }
947  }
948  while (index_1.inc()) ;
949 
950 
951 
952  // Base in r :
953  Index index_0 (a.bases_1d[0]->get_dimensions()) ;
954  res.bases_1d[0] = new Array<int> (a.bases_1d[0]->get_dimensions()) ;
955  do {
956  switch ((*a.bases_1d[0])(index_0)) {
957  case CHEB:
958  switch ((*b.bases_1d[0])(index_0)) {
959  case CHEB:
960  res.bases_1d[0]->set(index_0) = CHEB ;
961  break ;
962  default:
963  res_def = false ;
964  break ;
965  }
966  break ;
967  case LEG:
968  switch ((*b.bases_1d[0])(index_0)) {
969  case LEG:
970  res.bases_1d[0]->set(index_0) = LEG ;
971  break ;
972  default:
973  res_def = false ;
974  break ;
975  }
976  break ;
977  default:
978  res_def = false ;
979  break ;
980  }
981  }
982  while (index_0.inc()) ;
983  }
984 
985  if (!res_def)
986  for (int dim=0 ; dim<a.ndim ; dim++)
987  if (res.bases_1d[dim]!= 0x0) {
988  delete res.bases_1d[dim] ;
989  res.bases_1d[dim] = 0x0 ;
990  }
991  res.def = res_def ;
992  return res ;
993 
994 }
995 
997  int res = -1 ;
998  if (strcmp(p,"R ")==0)
999  res = 0 ;
1000  if (strcmp(p,"T ")==0)
1001  res = 1 ;
1002  if (strcmp(p,"P ")==0)
1003  res = 2 ;
1004  return res ;
1005 }}
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 compactified domain and a symmetry with respect to the plane and a quadrant sy...
virtual Val_domain mult_cos_phi(const Val_domain &) const
Multiplication by .
virtual void set_cheb_base(Base_spectral &) const
Gives the standard base for Chebyshev polynomials.
double alpha
Relates the numerical to the physical radii.
virtual void set_legendre_base(Base_spectral &) const
Gives the standard base for Legendre polynomials.
virtual double integ(const Val_domain &so, int bound) const
Surface integral on a given boundary.
void set_legendre_base_forx_cart(Base_spectral &so) const
Sets the base to the standard one for Legendre polynomials for a field like the component of a vecto...
virtual const Point absol_to_num(const Point &xxx) const
Computes the numerical coordinates from the physical ones.
virtual Base_spectral mult(const Base_spectral &, const Base_spectral &) const
Method for the multiplication of two Base_spectral.
virtual ostream & print(ostream &o) const
Delegate function to virtualize the << operator.
virtual Val_domain mult_cos_theta(const Val_domain &) const
Multiplication by .
virtual void do_radius() const
Computes the generalized radius.
virtual void do_cart_surr() const
Computes the Cartesian coordinates over the radius.
virtual void set_legendre_base_p_spher(Base_spectral &) const
Gives the base using Legendre 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.
void set_legendre_base_forz_cart(Base_spectral &so) const
Sets the base to the standard one for Legendre polynomials for a field like the component of a vecto...
virtual void set_val_inf(Val_domain &so, double xx) const
Sets the value at infinity of a Val_domain : not implemented for this type of Domain.
virtual void save(FILE *) const
Saving function.
virtual Val_domain div_sin_theta(const Val_domain &) const
Division by .
virtual void set_legendre_base_y_cart(Base_spectral &) const
Gives the base using Legendre polynomials, for the component of a vector.
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_base_r_spher(Base_spectral &) const
Gives the base using Chebyshev polynomials, for the radial component of a vector.
virtual void do_cart() const
Computes the Cartesian coordinates.
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_cheb_base_y_cart(Base_spectral &) const
Gives the base using Chebyshev polynomials, for the component of a vector.
virtual void set_legendre_base_x_cart(Base_spectral &) const
Gives the base using Legendre 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_cheb_base_z_cart(Base_spectral &) const
Gives the base using Chebyshev polynomials, for the component of a vector.
void set_cheb_base_forx_cart(Base_spectral &so) const
Sets the base to the standard one for Chebyshev polynomials for a field like the component of a vect...
virtual void set_legendre_base_z_cart(Base_spectral &) const
Gives the base using Legendre 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.
Point center
Absolute coordinates of the center.
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.
void set_legendre_base_fory_cart(Base_spectral &so) const
Sets the base to the standard one for Legendre polynomials for a field like the component of a vecto...
virtual Val_domain mult_xm1(const Val_domain &) const
Multiplication by .
void set_cheb_base_forz_cart(Base_spectral &so) const
Sets the base to the standard one for Chebyshev polynomials for a field like the component of a vect...
virtual void do_coloc()
Computes the colocation points.
virtual bool is_in(const Point &xx, double prec=1e-13) const
Check whether a point lies inside Domain.
virtual void do_absol() const
Computes the absolute coordinates.
virtual void set_cheb_base_t_spher(Base_spectral &) const
Gives the base using Chebyshev polynomials, for the component of a vector.
virtual Val_domain mult_sin_phi(const Val_domain &) const
Multiplication by .
void set_cheb_base_fory_cart(Base_spectral &so) const
Sets the base to the standard one for Chebyshev polynomials for a field like the component of a vect...
Domain_compact_symphi(int num, int ttype, double r_int, const Point &cr, const Dim_array &nbr)
Standard constructor :
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_cheb_base_x_cart(Base_spectral &) const
Gives the base using Chebyshev 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
Dim_array const & get_nbr_coefs() const
Returns the number of coefficients.
Definition: space.hpp:94
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 .
Base_spectral base
Spectral basis of the field.
Definition: val_domain.hpp:72
void set_in_conf()
Destroys the values in the coefficient space.
Definition: val_domain.cpp:197
Val_domain div_xm1() const
Division by .
Val_domain mult_sin_theta() const
Multiplication by .
Val_domain mult_cos_phi() const
Multiplication by .
Array< double > * cf
Pointer on the Array of the values in the coefficients space.
Definition: val_domain.hpp:77
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 .
void coef() const
Computes the coefficients.
Definition: val_domain.cpp:622
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