KADATH
domain_bispheric_eta_first.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 "bispheric.hpp"
23 #include "param.hpp"
24 #include "val_domain.hpp"
25 
26 namespace Kadath {
27 double chi_lim_eta(double, double, double, double) ;
28 
29 // Standard constructor
30 Domain_bispheric_eta_first::Domain_bispheric_eta_first (int num, int ttype, double a, double air, double etamin, double etamax,const Dim_array& nbr) : Domain(num, ttype, nbr), aa(a), r_ext(air), eta_min(etamin), eta_max(etamax), bound_chi(nullptr),
31 bound_chi_der(nullptr), p_eta(nullptr), p_chi(nullptr), p_phi(nullptr),
32 p_detadx(nullptr), p_detady(nullptr), p_detadz(nullptr), p_dchidx(nullptr), p_dchidy(nullptr), p_dchidz(nullptr), p_dphidy(nullptr), p_dphidz(nullptr) {
33 
34  assert (nbr.get_ndim()==3) ;
35  chi_c = 2*atan(aa/r_ext) ;
36  do_coloc() ;
37 }
38 
39 // Constructor by copy
41  r_ext(so.r_ext), eta_min (so.eta_min), eta_max(so.eta_max) {
42 
43  bound_chi = (so.bound_chi!=nullptr) ? new Val_domain(*so.bound_chi) : nullptr ;
44  bound_chi_der = (so.bound_chi_der!=nullptr) ? new Val_domain(*so.bound_chi_der) : nullptr ;
45  p_eta = (so.p_eta!=nullptr) ? new Val_domain(*so.p_eta) : nullptr ;
46  p_chi = (so.p_chi!=nullptr) ? new Val_domain(*so.p_chi) : nullptr ;
47  p_phi = (so.p_phi!=nullptr) ? new Val_domain(*so.p_phi) : nullptr ;
48  p_detadx = (so.p_detadx!=nullptr) ? new Val_domain(*so.p_detadx) : nullptr ;
49  p_detady = (so.p_detady!=nullptr) ? new Val_domain(*so.p_detady) : nullptr ;
50  p_detadz = (so.p_detadz!=nullptr) ? new Val_domain(*so.p_detadz) : nullptr ;
51  p_dchidx = (so.p_dchidx!=nullptr) ? new Val_domain(*so.p_dchidx) : nullptr ;
52  p_dchidy = (so.p_dchidy!=nullptr) ? new Val_domain(*so.p_dchidy) : nullptr ;
53  p_dchidz = (so.p_dchidz!=nullptr) ? new Val_domain(*so.p_dchidz) : nullptr ;
54  p_dphidy = (so.p_dphidy!=nullptr) ? new Val_domain(*so.p_dphidy) : nullptr ;
55  p_dphidz = (so.p_dphidz!=nullptr) ? new Val_domain(*so.p_dphidz) : nullptr ;
56 }
57 
59  fread_be (&aa, sizeof(double), 1, fd) ;
60  fread_be (&r_ext, sizeof(double), 1, fd) ;
61  fread_be (&eta_min, sizeof(double), 1, fd) ;
62  fread_be (&eta_max, sizeof(double), 1, fd) ;
63  fread_be (&chi_c, sizeof(double), 1, fd) ;
64 
65  bound_chi = nullptr ;
66  bound_chi_der = nullptr ;
67  p_eta = nullptr ;
68  p_chi = nullptr ;
69  p_phi = nullptr ;
70  p_detadx = nullptr ;
71  p_detady = nullptr ;
72  p_detadz = nullptr ;
73  p_dchidx = nullptr ;
74  p_dchidy = nullptr ;
75  p_dchidz = nullptr ;
76  p_dphidy = nullptr ;
77  p_dphidz = nullptr ;
78  do_coloc() ;
79 }
80 
81 // Destructor
82 Domain_bispheric_eta_first::~Domain_bispheric_eta_first() {
83  del_deriv() ;
84 }
85 
86 void Domain_bispheric_eta_first::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 (&aa, sizeof(double), 1, fd) ;
92  fwrite_be (&r_ext, sizeof(double), 1, fd) ;
93  fwrite_be (&eta_min, sizeof(double), 1, fd) ;
94  fwrite_be (&eta_max, sizeof(double), 1, fd) ;
95  fwrite_be (&chi_c, sizeof(double), 1, fd) ;
96 }
97 
98 // Deletes the derived members
100  for (int l=0 ; l<ndim ; l++) {
101  safe_delete(coloc[l]);
102  safe_delete(cart[l]);
103  }
104  safe_delete(radius);
105  safe_delete(bound_chi);
106  safe_delete(bound_chi_der);
107  safe_delete(p_eta);
108  safe_delete(p_chi);
109  safe_delete(p_phi);
110  safe_delete(p_detadx);
111  safe_delete(p_detady);
112  safe_delete(p_detadz);
113  safe_delete(p_dchidx);
114  safe_delete(p_dchidy);
115  safe_delete(p_dchidz);
116  safe_delete(p_dphidy);
117  safe_delete(p_dphidz);
118 }
119 
120 //Display
121 ostream& Domain_bispheric_eta_first::print (ostream& o) const {
122 
123  o << "Bispherical domain, chi fonction of eta" << endl ;
124  o << "aa = " << aa << endl ;
125  o << "Radius = " << r_ext << endl ;
126  o << eta_min << " < eta < " << eta_max << endl ;
127  o << "Nbr pts = " << nbr_points << endl ;
128  o << endl ;
129  return o ;
130 }
131 
132 // Comptes the lower bound for chi as a function of eta
134 
135  assert (p_eta!=nullptr) ;
136  assert (bound_chi==nullptr) ;
137  assert (bound_chi_der==nullptr) ;
138  bound_chi = new Val_domain (this) ;
140  Index index(nbr_points) ;
141  do {
142  bound_chi->set(index) = chi_lim_eta(fabs((*p_eta)(index)), r_ext, aa, chi_c) ;
143  }
144  while (index.inc()) ;
145  bound_chi->std_base() ;
146 
148 }
149 
150 // Comptes chi from chi star
152  for (int i=0 ; i<3 ; i++)
153  assert (coloc[i] != nullptr) ;
154  assert (p_chi==nullptr) ;
155  assert (bound_chi!=nullptr) ;
156  p_chi= new Val_domain(this) ;
157  p_chi->allocate_conf() ;
158  Index index (nbr_points) ;
159  do
160  p_chi->set(index) = ((*bound_chi)(index)-M_PI)*((*coloc[0])(index(0))) + M_PI ;
161  while (index.inc()) ;
162 }
163 
164 // Computes eta from eta star
166  for (int i=0 ; i<3 ; i++)
167  assert (coloc[i] != nullptr) ;
168  assert (p_eta==nullptr) ;
169  p_eta= new Val_domain(this) ;
170  p_eta->allocate_conf() ;
171  Index index (nbr_points) ;
172  do
173  p_eta->set(index) = (eta_max-eta_min)/2.*((*coloc[1])(index(1))) + (eta_min+eta_max)/2. ;
174  while (index.inc()) ;
175 }
176 
177 // Computes phi from phi star
179  for (int i=0 ; i<3 ; i++)
180  assert (coloc[i] != nullptr) ;
181  assert (p_phi==nullptr) ;
182  p_phi= new Val_domain(this) ;
183  p_phi->allocate_conf() ;
184  Index index (nbr_points) ;
185  do
186  p_phi->set(index) = ((*coloc[2])(index(2))) ;
187  while (index.inc()) ;
188 }
189 
191  if (p_chi==nullptr)
192  do_chi() ;
193  return *p_chi ;
194 }
195 
197  if (p_eta==nullptr)
198  do_eta() ;
199  return *p_eta ;
200 }
201 
202 
204  for (int i=0 ; i<3 ; i++)
205  assert (coloc[i] != nullptr) ;
206  for (int i=0 ; i<3 ; i++)
207  assert (absol[i] == nullptr) ;
208  for (int i=0 ; i<3 ; i++) {
209  absol[i] = new Val_domain(this) ;
210  absol[i]->allocate_conf() ;
211  }
212 
213  Index index (nbr_points) ;
214  if (p_chi==nullptr)
215  do_chi() ;
216  if (p_phi==nullptr)
217  do_phi() ;
218  if (bound_chi==nullptr)
219  do_bound_chi() ;
220  if (p_eta==nullptr)
221  do_eta() ;
222 
223  do {
224  absol[0]->set(index) = aa*sinh((*p_eta)(index))/(cosh((*p_eta)(index))-cos((*p_chi)(index))) ;
225  absol[1]->set(index) =
226  aa*sin((*p_chi)(index))*cos((*p_phi)(index))/(cosh((*p_eta)(index))-cos((*p_chi)(index))) ;
227  absol[2]->set(index) =
228  aa*sin((*p_chi)(index))*sin((*p_phi)(index))/(cosh((*p_eta)(index))-cos((*p_chi)(index))) ;
229  }
230  while (index.inc()) ;
231 
232  // Basis
233  absol[0]->std_base() ;
234  absol[1]->std_base() ;
235  absol[2]->std_anti_base() ;
236 }
237 
238 
239 // Computes the generalized radius.
241 
242  for (int i=0 ; i<3 ; i++)
243  assert (coloc[i] != nullptr) ;
244  assert (radius == nullptr) ;
245  radius = new Val_domain(sqrt (get_cart(1)*get_cart(1)+get_cart(2)*get_cart(2)+get_cart(3)*get_cart(3))) ;
246 }
247 
248 // Computes the Cartesian coordinates
250  for (int i=0 ; i<3 ; i++)
251  assert (coloc[i] != nullptr) ;
252  for (int i=0 ; i<3 ; i++)
253  assert (cart[i] == nullptr) ;
254  for (int i=0 ; i<3 ; i++) {
255  cart[i] = new Val_domain(this) ;
256  cart[i]->allocate_conf() ;
257  }
258 
259  Index index (nbr_points) ;
260  if (p_chi==nullptr)
261  do_chi() ;
262  if (p_phi==nullptr)
263  do_phi() ;
264  if (bound_chi==nullptr)
265  do_bound_chi() ;
266  if (p_eta==nullptr)
267  do_eta() ;
268 
269  do {
270  cart[0]->set(index) = aa*sinh((*p_eta)(index))/(cosh((*p_eta)(index))-cos((*p_chi)(index))) ;
271  cart[1]->set(index) =
272  aa*sin((*p_chi)(index))*cos((*p_phi)(index))/(cosh((*p_eta)(index))-cos((*p_chi)(index))) ;
273  cart[2]->set(index) =
274  aa*sin((*p_chi)(index))*sin((*p_phi)(index))/(cosh((*p_eta)(index))-cos((*p_chi)(index))) ;
275  }
276  while (index.inc()) ;
277 
278  // Basis
279  cart[0]->std_base() ;
280  cart[1]->std_base() ;
281  cart[2]->std_anti_base() ;
282 }
283 
284 // Check if the point is inside this domain
285 bool Domain_bispheric_eta_first::is_in (const Point& abs, double prec) const {
286  assert (abs.get_ndim()==3) ;
287 
288  double xx = abs(1) ;
289  double yy = abs(2) ;
290  double zz = abs(3) ;
291  double air = sqrt (xx*xx+yy*yy+zz*zz) ;
292 
293  double chi ;
294  double rho = sqrt(yy*yy+zz*zz) ;
295 
296  double x_out = aa*cosh(eta_max)/sinh(eta_max) ;
297 
298  if (rho<prec)
299  chi = (fabs(abs(1)) < fabs(x_out)) ? M_PI : 0;
300  else
301  chi = atan (2*aa*rho/(air*air-aa*aa)) ;
302 
303  if (chi<0)
304  chi += M_PI ;
305 
306  double eta = 0.5*log((1+(2*aa*xx)/(aa*aa+air*air))/(1-(2*aa*xx)/(aa*aa+air*air))) ;
307 
308  bool res = true ;
309  if (eta>eta_max+prec)
310  res = false ;
311  if (eta<eta_min-prec)
312  res = false ;
313 
314  if (res) {
315  double chi_bound = chi_lim_eta (fabs(eta), r_ext, aa, chi_c) ;
316  if (chi<chi_bound-prec)
317  res = false ;
318  }
319  return res ;
320 }
321 
322 
323 // Converts the absolute coordinates to the numerical ones.
325 
326  assert (is_in(abs, 1e-12)) ;
327  Point num(3) ;
328 
329  double xx = abs(1) ;
330  double yy = abs(2) ;
331  double zz = abs(3) ;
332  double air = sqrt (xx*xx+yy*yy+zz*zz) ;
333 
334  num.set(3) = atan2 (zz, yy) ;
335 
336  if (num(3)<0)
337  num.set(3) += 2*M_PI ;
338 
339  double chi ;
340  double rho = sqrt(yy*yy+zz*zz) ;
341  if (rho<PRECISION)
342  chi = M_PI ;
343  else
344  chi = atan (2*aa*rho/(air*air-aa*aa)) ;
345 
346  if (chi<0)
347  chi += M_PI ;
348 
349  double eta = 0.5*log((1+(2*aa*xx)/(aa*aa+air*air))/(1-(2*aa*xx)/(aa*aa+air*air))) ;
350 
351  num.set(2) = (eta-(eta_max+eta_min)/2.)*2./(eta_max-eta_min) ;
352  double chi_bound = chi_lim_eta (fabs(eta), r_ext, aa, chi_c) ;
353  num.set(1) = (chi-M_PI)/(chi_bound-M_PI);
354 
355  return num ;
356 }
357 
358 const Point Domain_bispheric_eta_first::absol_to_num_bound(const Point& abs, int bound) const {
359 
360  assert (is_in(abs, 1e-3)) ;
361  Point num(3) ;
362 
363  double xx = abs(1) ;
364  double yy = abs(2) ;
365  double zz = abs(3) ;
366  double air = sqrt (xx*xx+yy*yy+zz*zz) ;
367 
368  num.set(3) = atan2 (zz, yy) ;
369 
370  if (num(3)<0)
371  num.set(3) += 2*M_PI ;
372 
373  double chi ;
374  double rho = sqrt(yy*yy+zz*zz) ;
375  if (rho<PRECISION)
376  chi = M_PI ;
377  else
378  chi = atan (2*aa*rho/(air*air-aa*aa)) ;
379 
380  if (chi<0)
381  chi += M_PI ;
382 
383  double eta = 0.5*log((1+(2*aa*xx)/(aa*aa+air*air))/(1-(2*aa*xx)/(aa*aa+air*air))) ;
384 
385  num.set(2) = (eta-(eta_max+eta_min)/2.)*2./(eta_max-eta_min) ;
386  double chi_bound = chi_lim_eta (fabs(eta), r_ext, aa, chi_c) ;
387  num.set(1) = (chi-M_PI)/(chi_bound-M_PI);
388 
389  switch (bound) {
390  case ETA_PLUS_BC :
391  num.set(2) = 1 ;
392  break ;
393  case ETA_MINUS_BC :
394  num.set(2) = -1 ;
395  break ;
396  case OUTER_BC :
397  num.set(1) = 1 ;
398  break ;
399  default:
400  cerr << "Unknown case in Domain_bispheric_eta_first::absol_to_num_bound" << endl ;
401  abort() ;
402  }
403 
404  return num ;
405 }
406 
407 double coloc_leg(int,int) ;
408 double coloc_leg_parity(int,int) ;
410 
411  switch (type_base) {
412  case CHEB_TYPE:
414  del_deriv() ;
415  for (int i=0 ; i<ndim ; i++)
416  coloc[i] = new Array<double> (nbr_points(i)) ;
417  for (int i=0 ; i<nbr_points(0) ; i++)
418  coloc[0]->set(i) = sin(M_PI*i/2./(nbr_points(0)-1)) ;
419  for (int j=0 ; j<nbr_points(1) ; j++)
420  coloc[1]->set(j) = -cos(M_PI*j/(nbr_points(1)-1)) ;
421  for (int k=0 ; k<nbr_points(2) ; k++)
422  coloc[2]->set(k) = M_PI*k/(nbr_points(2)-1) ;
423  do_phi() ;
424  do_eta() ;
425  do_bound_chi() ;
426  do_chi() ;
427  break ;
428  case LEG_TYPE:
430  del_deriv() ;
431  for (int i=0 ; i<ndim ; i++)
432  coloc[i] = new Array<double> (nbr_points(i)) ;
433  for (int i=0 ; i<nbr_points(0) ; i++)
434  coloc[0]->set(i) = coloc_leg_parity(i,nbr_points(0)) ;
435  for (int j=0 ; j<nbr_points(1) ; j++)
436  coloc[1]->set(j) = coloc_leg(j,nbr_points(1)) ;
437  for (int k=0 ; k<nbr_points(2) ; k++)
438  coloc[2]->set(k) = M_PI*k/(nbr_points(2)-1) ;
439  do_phi() ;
440  do_eta() ;
441  do_bound_chi() ;
442  do_chi() ;
443  break ;
444  default :
445  cerr << "Unknown type of basis in Domain_bispheric_eta_first::do_coloc" << endl ;
446  abort() ;
447  }
448 }
449 // Standard basis for Chebyshev
451 
452  assert (type_base == CHEB_TYPE) ;
453  base.allocate(nbr_coefs) ;
454 
455  Index index(base.bases_1d[0]->get_dimensions()) ;
456 
457  base.def =true ;
458  base.bases_1d[2]->set(0) = COS ;
459  for (int k=0 ; k<nbr_coefs(2) ; k++) {
460  base.bases_1d[1]->set(k) = CHEB ;
461  for (int j=0 ; j<nbr_coefs(1) ; j++) {
462  index.set(0) = j ; index.set(1) = k ;
463  base.bases_1d[0]->set(index) = (k%2==0) ? CHEB_EVEN : CHEB_ODD ;
464  }
465  }
466 }
467 
468 // Standard basis for Legendre
470 
471 
472  assert (type_base == LEG_TYPE) ;
473  base.allocate(nbr_coefs) ;
474 
475  Index index(base.bases_1d[0]->get_dimensions()) ;
476 
477  base.def=true ;
478  base.bases_1d[2]->set(0) = COS ;
479  for (int k=0 ; k<nbr_coefs(2) ; k++) {
480  base.bases_1d[1]->set(k) = LEG ;
481  for (int j=0 ; j<nbr_coefs(1) ; j++) {
482  index.set(0) = j ; index.set(1) = k ;
483  base.bases_1d[0]->set(index) = (k%2==0) ? LEG_EVEN : LEG_ODD ;
484  }
485  }
486 }
487 
488 // Antisymetric basis for Chebyshev
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 ;
498  for (int k=0 ; k<nbr_coefs(2) ; k++) {
499  base.bases_1d[1]->set(k) = CHEB ;
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) = (k%2==0) ? CHEB_EVEN : CHEB_ODD ;
503  }
504  }
505 }
506 
507 // Antisymetric fo Legendre
509  assert (type_base == LEG_TYPE) ;
510  base.allocate(nbr_coefs) ;
511 
512  Index index(base.bases_1d[0]->get_dimensions()) ;
513 
514  base.def=true ;
515  base.bases_1d[2]->set(0) = SIN ;
516  for (int k=0 ; k<nbr_coefs(2) ; k++) {
517  base.bases_1d[1]->set(k) = LEG ;
518  for (int j=0 ; j<nbr_coefs(1) ; j++) {
519  index.set(0) = j ; index.set(1) = k ;
520  base.bases_1d[0]->set(index) = (k%2==0) ? LEG_EVEN : LEG_ODD ;
521  }
522  }
523 }
524 
525 // Computes the derivatives of the numerical coordinates with respect to the Cartesian ones.
527 
528  if (cart[0]==nullptr)
529  do_cart() ;
530  if (radius==nullptr)
531  do_radius() ;
532  // Partial derivatives of eta
533  Val_domain denom_eta
534  ((eta_max-eta_min)/2.*((aa*aa+(*radius)*(*radius))*((aa*aa+(*radius)*(*radius))) -
535  4.*aa*aa*(*cart[0])*(*cart[0]))) ;
536  p_detadx = new Val_domain ((2.*aa*(aa*aa+(*radius)*(*radius)-2.*(*cart[0])*(*cart[0])))/denom_eta) ;
537  p_detady = new Val_domain (-4.*aa*(*cart[0])*(*cart[1])/denom_eta) ;
538  p_detadz = new Val_domain (-4.*aa*(*cart[0])*(*cart[2])/denom_eta) ;
539 
540  // Partial derivatives of phi :
541  Val_domain phiyz (((exp(*p_eta)+exp(-*p_eta))/2.-cos(*p_chi))/aa) ;
542 
543  // Derivative eta_bound :
544  Val_domain dgdx ((*bound_chi_der)*(*p_detadx)) ;
545  Val_domain dgdy ((*bound_chi_der)*(*p_detady)) ;
546  Val_domain dgdz ((*bound_chi_der)*(*p_detadz)) ;
547 
548  // Partial derivatives of chi
549  Val_domain rho (sqrt((*cart[1])*(*cart[1])+(*cart[2])*(*cart[2]))) ;
550  Val_domain denom_chi (((*radius)*(*radius)-aa*aa)*((*radius)*(*radius)-aa*aa) +
551  4.*aa*aa*rho*rho) ;
552 
553  Val_domain auchi_chi (2.*aa*((*radius)*(*radius)-aa*aa-2*rho*rho)/denom_chi) ;
554  // The basis :
555  p_detadx->std_base() ;
556  p_detady->std_base() ;
558  phiyz.std_base() ;
559  auchi_chi.std_base() ;
560 
561  p_dphidy = new Val_domain (-phiyz.mult_sin_phi()) ;
562  p_dphidz = new Val_domain (phiyz.mult_cos_phi()) ;
563 
564  Val_domain dchidx (-4.*aa*(*cart[0])*rho/denom_chi) ;
565  Val_domain dchidy (auchi_chi.mult_cos_phi()) ;
566  Val_domain dchidz (auchi_chi.mult_sin_phi()) ;
567 
568  p_dchidx = new Val_domain ((dchidx*((*bound_chi)-M_PI)-dgdx*((*p_chi)-M_PI))/pow((*bound_chi)-M_PI, 2.)) ;
569  p_dchidy = new Val_domain ((dchidy*((*bound_chi)-M_PI)-dgdy*((*p_chi)-M_PI))/pow((*bound_chi)-M_PI, 2.)) ;
570  p_dchidz = new Val_domain ((dchidz*((*bound_chi)-M_PI)-dgdz*((*p_chi)-M_PI))/pow((*bound_chi)-M_PI, 2.)) ;
571 
572  p_dchidx->base = auchi_chi.der_var(1).base ;
573  p_dchidy->base = auchi_chi.mult_cos_phi().base ;
574  p_dchidz->base = auchi_chi.mult_sin_phi().base ;
575 }
576 
577 // Computes the derivatives with respect to the Cartesian coordinates giving the ones with respect to the numerical ones.
578 void Domain_bispheric_eta_first::do_der_abs_from_der_var(const Val_domain *const *const der_var, Val_domain **const der_abs) const {
579 
580  if (p_detadx==nullptr)
581  do_for_der() ;
582 
583  // d/dx :
584  der_abs[0] = new Val_domain((*der_var[1])*(*p_detadx) + (*der_var[0])*(*p_dchidx)) ;
585 
586  // d/dy :
587  Val_domain auchi_y ((*der_var[2])*(*p_dphidy)) ;
588  Val_domain part_y_phi (auchi_y.div_sin_chi()) ;
589 
590  der_abs[1] = new Val_domain((*der_var[1])*(*p_detady) + (*der_var[0])*(*p_dchidy) + part_y_phi) ;
591 
592  // d/dz :
593  Val_domain auchi_z ((*der_var[2])*(*p_dphidz)) ;
594  Val_domain part_z_phi (auchi_z.div_sin_chi()) ;
595  der_abs[2] = new Val_domain((*der_var[1])*(*p_detadz) + (*der_var[0])*(*p_dchidz) + part_z_phi) ;
596 }
597 
598 // Multiplication rule for the basis.
600 
601  assert (a.ndim==3) ;
602  assert (b.ndim==3) ;
603 
604  Base_spectral res(3) ;
605  bool res_def = true ;
606 
607  if (!a.def)
608  res_def=false ;
609  if (!b.def)
610  res_def=false ;
611 
612  if (res_def) {
613  // Base in phi :
614  res.bases_1d[2] = new Array<int> (a.bases_1d[2]->get_dimensions()) ;
615  switch ((*a.bases_1d[2])(0)) {
616  case COS:
617  switch ((*b.bases_1d[2])(0)) {
618  case COS:
619  res.bases_1d[2]->set(0) = COS ;
620  break ;
621  case SIN:
622  res.bases_1d[2]->set(0) = SIN ;
623  break ;
624  default:
625  res_def = false ;
626  break ;
627  }
628  break ;
629  case SIN:
630  switch ((*b.bases_1d[2])(0)) {
631  case COS:
632  res.bases_1d[2]->set(0) = SIN ;
633  break ;
634  case SIN:
635  res.bases_1d[2]->set(0) = COS ;
636  break ;
637  default:
638  res_def = false ;
639  break ;
640  }
641  break ;
642  default:
643  res_def = false ;
644  break ;
645  }
646 
647  // Base in eta :
648  Index index_1 (a.bases_1d[1]->get_dimensions()) ;
649  res.bases_1d[1] = new Array<int> (a.bases_1d[1]->get_dimensions()) ;
650  do {
651  switch ((*a.bases_1d[1])(index_1)) {
652  case CHEB:
653  switch ((*b.bases_1d[1])(index_1)) {
654  case CHEB:
655  res.bases_1d[1]->set(index_1) = CHEB ;
656  break ;
657  default:
658  res_def = false ;
659  break ;
660  }
661  break ;
662  case LEG:
663  switch ((*b.bases_1d[1])(index_1)) {
664  case LEG:
665  res.bases_1d[1]->set(index_1) = LEG ;
666  break ;
667  default:
668  res_def = false ;
669  break ;
670  }
671  break ;
672  default:
673  res_def = false ;
674  break ;
675  }
676  }
677  while (index_1.inc()) ;
678 
679  // Bases in chi :
680  Index index_0 (a.bases_1d[0]->get_dimensions()) ;
681  res.bases_1d[0] = new Array<int> (a.bases_1d[0]->get_dimensions()) ;
682  do {
683  switch ((*a.bases_1d[0])(index_0)) {
684  case CHEB_EVEN:
685  switch ((*b.bases_1d[0])(index_0)) {
686  case CHEB_EVEN:
687  res.bases_1d[0]->set(index_0) = (index_0(1)%2==0) ? CHEB_EVEN : CHEB_ODD ;
688  break ;
689  case CHEB_ODD:
690  res.bases_1d[0]->set(index_0) = (index_0(1)%2==0) ? CHEB_ODD : CHEB_EVEN ;
691  break ;
692  default:
693  res_def = false ;
694  break ;
695  }
696  break ;
697  case CHEB_ODD:
698  switch ((*b.bases_1d[0])(index_0)) {
699  case CHEB_EVEN:
700  res.bases_1d[0]->set(index_0) = (index_0(1)%2==0) ? CHEB_ODD : CHEB_EVEN ;
701  break ;
702  case CHEB_ODD:
703  res.bases_1d[0]->set(index_0) = (index_0(1)%2==0) ? CHEB_EVEN : CHEB_ODD ;
704  break ;
705  default:
706  res_def = false ;
707  break ;
708  }
709  break ;
710  case LEG_EVEN:
711  switch ((*b.bases_1d[0])(index_0)) {
712  case LEG_EVEN:
713  res.bases_1d[0]->set(index_0) = (index_0(1)%2==0) ? LEG_EVEN : LEG_ODD ;
714  break ;
715  case LEG_ODD:
716  res.bases_1d[0]->set(index_0) = (index_0(1)%2==0) ? LEG_ODD : LEG_EVEN ;
717  break ;
718  default:
719  res_def = false ;
720  break ;
721  }
722  break ;
723  case LEG_ODD:
724  switch ((*b.bases_1d[0])(index_0)) {
725  case LEG_EVEN:
726  res.bases_1d[0]->set(index_0) = (index_0(1)%2==0) ? LEG_ODD : LEG_EVEN ;
727  break ;
728  case LEG_ODD:
729  res.bases_1d[0]->set(index_0) = (index_0(1)%2==0) ? LEG_EVEN : LEG_ODD ;
730  break ;
731  default:
732  res_def = false ;
733  break ;
734  }
735  break ;
736  default:
737  res_def = false ;
738  break ;
739  }
740  }
741  while (index_0.inc()) ;
742  }
743 
744  if (!res_def)
745  for (int dim=0 ; dim<a.ndim ; dim++)
746  if (res.bases_1d[dim]!= nullptr) {
747  delete res.bases_1d[dim] ;
748  res.bases_1d[dim] = nullptr ;
749  }
750  res.def = res_def ;
751  return res ;
752 }
753 
754 
756 
757  switch (bound) {
758  case OUTER_BC :
759  return Val_domain(so.der_abs(1)*get_cart(1)/r_ext + so.der_abs(2)*get_cart(2)/r_ext +
760  so.der_abs(3)*get_cart(3)/r_ext) ;
761  case ETA_MINUS_BC : {
762  Val_domain res (so.der_var(2) - (get_chi()-M_PI)/(*bound_chi-M_PI)/(*bound_chi-M_PI)
763  * (*bound_chi_der) * so.der_var(1)) ;
764  res *= 2./(eta_max-eta_min) ;
765  res.set_base() = so.der_var(2).get_base() ;
766  return res ;
767  }
768  case ETA_PLUS_BC : {
769  Val_domain res (so.der_var(2) - (get_chi()-M_PI)/(*bound_chi-M_PI)/(*bound_chi-M_PI)
770  * (*bound_chi_der) * so.der_var(1)) ;
771  res *= 2./(eta_max-eta_min) ;
772  res.set_base() = so.der_var(2).get_base() ;
773  return res ;
774  }
775  default:
776  cerr << "Unknown boundary case in Domain_bispheric_eta_first::der_normal" << endl ;
777  abort() ;
778  }
779 }
780 
782  int res = -1 ;
783  if (strcmp(p,"CHI ")==0)
784  res = 0 ;
785  if (strcmp(p,"ETA ")==0)
786  res = 1 ;
787  if (strcmp(p,"P ")==0)
788  res = 2 ;
789  return res ;
790 }
791 }
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 bispherical coordinates with a symmetry with respect to the plane .
Definition: bispheric.hpp:878
virtual void do_radius() const
Computes the generalized radius.
Val_domain * p_dchidz
Pointer on a Val_domain containing .
Definition: bispheric.hpp:979
Domain_bispheric_eta_first(int num, int ttype, double aa, double rr, double eta_min, double eta_max, const Dim_array &nbr)
Standard constructor :
virtual void do_cart() const
Computes the Cartesian coordinates.
virtual void do_coloc()
Computes the colocation points.
void do_for_der() const
Computes the partial derivatives of the numerical coordinates with respect to the Cartesian ones like...
virtual void set_anti_legendre_base(Base_spectral &so) const
Sets the base to the standard one for Legendre polynomials and an astisymetric function with respect ...
void do_bound_chi() const
Computes and its first derivative stored respectively in and .
virtual void save(FILE *) const
Saving function.
Val_domain * p_chi
Pointer on a Val_domain containing .
Definition: bispheric.hpp:901
virtual ostream & print(ostream &o) const
Delegate function to virtualize the << operator.
Val_domain * p_detadz
Pointer on a Val_domain containing The explicit expression are : .
Definition: bispheric.hpp:937
virtual const Val_domain & get_eta() const
Returns the variable .
Val_domain * p_detady
Pointer on a Val_domain containing The explicit expression are : .
Definition: bispheric.hpp:926
Val_domain * p_eta
Pointer on a Val_domain containing .
Definition: bispheric.hpp:900
virtual void set_legendre_base(Base_spectral &so) const
Sets the base to the standard one for Chebyshev polynomials.
void del_deriv() override
Destroys the derivated members (like coloc, cart and radius), when changing the type of colocation po...
virtual const Val_domain & get_chi() const
Returns the variable .
virtual void set_anti_cheb_base(Base_spectral &so) const
Sets the base to the standard one for Chebyshev polynomials and an astisymetric function with respect...
virtual int give_place_var(char *) const
Translates a name of a coordinate into its corresponding numerical name.
double r_ext
Radius of the outer boundary.
Definition: bispheric.hpp:882
Val_domain * p_dphidy
Pointer on a Val_domain containing The explicit expression is : .
Definition: bispheric.hpp:986
virtual void set_cheb_base(Base_spectral &so) const
Sets the base to the standard one for Chebyshev polynomials.
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.
Val_domain * p_dphidz
Pointer on a Val_domain containing The explicit expression is : .
Definition: bispheric.hpp:993
virtual Val_domain der_normal(const Val_domain &, int) const
Normal derivative with respect to a given surface.
virtual const Point absol_to_num(const Point &xxx) const
Computes the numerical coordinates from the physical ones.
Val_domain * p_dchidx
Pointer on a Val_domain containing .
Definition: bispheric.hpp:951
double aa
Distance scale .
Definition: bispheric.hpp:881
Val_domain * p_detadx
Pointer on a Val_domain containing The explicit expression are : .
Definition: bispheric.hpp:915
virtual void do_absol() const
Computes the absolute coordinates.
Val_domain * p_dchidy
Pointer on a Val_domain containing .
Definition: bispheric.hpp:965
virtual Base_spectral mult(const Base_spectral &, const Base_spectral &) const
Method for the multiplication of two Base_spectral.
Val_domain * bound_chi
Pointer on a Val_domain containing the values of .
Definition: bispheric.hpp:894
virtual bool is_in(const Point &xx, double prec=1e-13) const
Check whether a point lies inside Domain.
double eta_max
Upper bound for .
Definition: bispheric.hpp:884
Val_domain * bound_chi_der
Pointer on a Val_domain containing the values of the derivative with respect to .
Definition: bispheric.hpp:899
Val_domain * p_phi
Pointer on a Val_domain containing .
Definition: bispheric.hpp:902
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...
double eta_min
Lower bound for .
Definition: bispheric.hpp:883
Abstract class that implements the fonctionnalities common to all the type of domains.
Definition: space.hpp:60
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 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
Val_domain const & get_cart(int i) const
Returns a Cartesian coordinates.
Definition: space.hpp:1471
Memory_mapped_array< Array< double > * > coloc
Colocation points in each dimension (stored in ndim 1d- arrays)
Definition: space.hpp:75
Class that gives the position inside a multi-dimensional Array.
Definition: index.hpp:38
int & set(int i)
Read/write of the position in a given dimension.
Definition: index.hpp:72
bool inc(int increm, int var=0)
Increments the position of the Index.
Definition: index.hpp:99
The class Point is used to store the coordinates of a point.
Definition: point.hpp:30
const int & get_ndim() const
Returns the number of dimensions.
Definition: point.hpp:51
double & set(int i)
Read/write of a coordinate.
Definition: point.hpp:47
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
Val_domain mult_cos_phi() const
Multiplication by .
double & set(const Index &pos)
Read/write the value of the field in the configuration space.
Definition: val_domain.cpp:171
void std_base()
Sets the standard basis of decomposition.
Definition: val_domain.cpp:246
Val_domain der_var(int i) const
Computes the derivative with respect to a numerical coordinate.
Definition: val_domain.cpp:670
Base_spectral & set_base()
Sets the basis of decomposition.
Definition: val_domain.hpp:126
void std_anti_base()
Sets the standard, anti-symetric, basis of decomposition.
Definition: val_domain.cpp:279
Val_domain der_abs(int i) const
Computes the derivative with respect to an absolute coordinate (typically Cartesian).
Definition: val_domain.cpp:681
void allocate_conf()
Allocates the values in the configuration space and destroys the values in the coefficients space.
Definition: val_domain.cpp:209
Val_domain div_sin_chi() const
Division by .
const Base_spectral & get_base() const
Returns the basis of decomposition.
Definition: val_domain.hpp:122