KADATH
domain_polar_outer_adapted.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 "adapted_polar.hpp"
23 #include "point.hpp"
24 #include "array_math.hpp"
25 #include "val_domain.hpp"
26 #include "scalar.hpp"
27 #include "tensor_impl.hpp"
28 
29 namespace Kadath {
30 void coef_1d (int, Array<double>&) ;
31 void coef_i_1d (int, Array<double>&) ;
32 int der_1d (int, Array<double>&) ;
33 
34 // Standard constructor
35 Domain_polar_shell_outer_adapted::Domain_polar_shell_outer_adapted (const Space& sss, int num, int ttype, double rin, double rout, const Point& cr, const Dim_array& nbr) :
36  Domain(num, ttype, nbr), sp(sss), inner_radius(rin), center(cr) {
37  assert (nbr.get_ndim()==2) ;
38  assert (cr.get_ndim()==2) ;
39 
40 
41  outer_radius_term_eq = nullptr ;
42  rad_term_eq = nullptr ;
43  der_rad_term_eq = nullptr ;
44  dt_rad_term_eq = nullptr ;
45  normal_spher = nullptr ;
46  normal_cart = nullptr ;
47 
48  do_coloc() ;
49  outer_radius = new Val_domain (this) ;
50  *outer_radius = rout ;
52 }
53 
54 Domain_polar_shell_outer_adapted::Domain_polar_shell_outer_adapted (const Space& sss, int num, int ttype, double rin, const Val_domain& rout, const Point& cr, const Dim_array& nbr) :
55  Domain(num, ttype, nbr), sp(sss), inner_radius(rin), center(cr) {
56  assert (nbr.get_ndim()==2) ;
57  assert (cr.get_ndim()==2) ;
58 
59 
60  outer_radius_term_eq = nullptr ;
61  rad_term_eq = nullptr ;
62  der_rad_term_eq = nullptr ;
63  dt_rad_term_eq = nullptr ;
64  normal_spher = nullptr ;
65  normal_cart = nullptr ;
66 
67  do_coloc() ;
68  outer_radius = new Val_domain(rout) ;
69 }
70 
71 // Constructor by copy
73  inner_radius (so.inner_radius), center(so.center) {
74 
76  if (so.outer_radius_term_eq != nullptr)
78  if (so.rad_term_eq !=nullptr)
79  rad_term_eq = new Term_eq (*so.rad_term_eq) ;
80  if (so.der_rad_term_eq !=nullptr)
82  if (so.dt_rad_term_eq !=nullptr)
84  if (so.normal_spher !=nullptr)
85  normal_spher = new Term_eq (*so.normal_spher) ;
86  if (so.normal_cart !=nullptr)
87  normal_cart = new Term_eq (*so.normal_cart) ;
88 }
89 
90 Domain_polar_shell_outer_adapted::Domain_polar_shell_outer_adapted (const Space& sss, int num, FILE* fd) : Domain(num, fd), sp(sss), center(fd) {
91  fread_be (&inner_radius, sizeof(double), 1, fd) ;
92  outer_radius = new Val_domain(this, fd) ;
93 
94  outer_radius_term_eq = nullptr ;
95  rad_term_eq = nullptr ;
96  der_rad_term_eq = nullptr ;
97  dt_rad_term_eq = nullptr ;
98  normal_spher = nullptr ;
99  normal_cart = nullptr ;
100 
101  do_coloc() ;
102 }
103 
105  for (int i=0 ; i<2 ; i++)
106  assert (coloc[i] != nullptr) ;
107  assert (radius == nullptr) ;
108  radius = new Val_domain(this) ;
109  radius->allocate_conf() ;
110  Index index (nbr_points) ;
111  do
112  radius->set(index) = ((*outer_radius)(index) - inner_radius)/2.* ((*coloc[0])(index(0))) + ((*outer_radius)(index) + inner_radius)/2. ;
113  while (index.inc()) ;
114  radius->std_r_base() ;
115 }
116 
117 // Destructor
118 Domain_polar_shell_outer_adapted::~Domain_polar_shell_outer_adapted() {
119 
120  delete outer_radius ;
121  if (outer_radius_term_eq != nullptr)
122  delete outer_radius_term_eq ;
123  if (rad_term_eq != nullptr)
124  delete rad_term_eq ;
125  if (der_rad_term_eq != nullptr)
126  delete der_rad_term_eq ;
127  if (normal_spher != nullptr)
128  delete normal_spher ;
129  if (normal_cart != nullptr)
130  delete normal_cart ;
131  if (dt_rad_term_eq != nullptr)
132  delete dt_rad_term_eq ;
133 }
134 
136  safe_delete(outer_radius_term_eq);
137  safe_delete(rad_term_eq);
138  safe_delete(der_rad_term_eq);
139  safe_delete(normal_spher);
140  safe_delete(normal_cart);
141  safe_delete(dt_rad_term_eq);
142 }
143 
144 
146  return nbr_coefs(1) ;
147 }
148 
150 
151  if (outer_radius_term_eq != nullptr)
152  delete outer_radius_term_eq ;
153  Scalar val (sp) ;
155 
156  outer_radius_term_eq = new Term_eq (num_dom, val) ;
157  update() ;
158 }
159 
160 void Domain_polar_shell_outer_adapted::affecte_coef(int& conte, int cc, bool& found) const {
161 
162  Val_domain auxi (this) ;
163  auxi.std_base() ;
164  auxi.set_in_coef() ;
165  auxi.allocate_coef() ;
166  *auxi.cf = 0 ;
167 
168  found = false ;
169 
170 
171  for (int j=0 ; j<nbr_coefs(1) ; j++) {
172  if (conte==cc) {
173  Index pos_cf (nbr_coefs) ;
174  pos_cf.set(0) = 0 ;
175  pos_cf.set(1) = j ;
176  auxi.cf->set(pos_cf) = 1 ;
177  found = true ;
178  }
179  conte ++ ;
180  }
181 
182  if (found) {
183  Scalar auxi_scal (sp) ;
184  auxi_scal.set_domain(num_dom) = auxi ;
185  outer_radius_term_eq->set_der_t(auxi_scal) ;
186  }
187  else {
189  }
190  update() ;
191 }
192 
193 void Domain_polar_shell_outer_adapted::xx_to_vars_from_adapted(Val_domain& new_outer_radius, const Array<double>& xx, int& pos) const {
194 
195  new_outer_radius.allocate_coef() ;
196  *new_outer_radius.cf = 0 ;
197 
198  Index pos_cf (nbr_coefs) ;
199  pos_cf.set(0) = 0 ;
200 
201  for (int j=0 ; j<nbr_coefs(1) ; j++) {
202  pos_cf.set(1)= j ;
203  new_outer_radius.cf->set(pos_cf) -= xx(pos) ;
204  pos ++ ;
205  }
206 
207  new_outer_radius.set_base() = outer_radius->get_base() ;
208 }
209 
211 
212  *outer_radius += cor ;
213  for (int l=0 ; l<ndim ; l++) {
214  if (absol[l] !=nullptr) delete absol[l] ;
215  if (cart[l] !=nullptr) delete cart[l] ;
216  if (cart_surr[l] !=nullptr) delete cart_surr[l] ;
217  absol[l] = nullptr ;
218  cart_surr[l] = nullptr ;
219  cart[l]= nullptr ;
220  }
221  if (radius !=nullptr)
222  delete radius ;
223  radius = nullptr ;
224  update() ;
225 }
226 
228 
229  *outer_radius = cor ;
230  for (int l=0 ; l<ndim ; l++) {
231  if (absol[l] !=nullptr) delete absol[l] ;
232  if (cart[l] !=nullptr) delete cart[l] ;
233  if (cart_surr[l] !=nullptr) delete cart_surr[l] ;
234  absol[l] = nullptr ;
235  cart_surr[l] = nullptr ;
236  cart[l]= nullptr ;
237  }
238  if (radius !=nullptr)
239  delete radius ;
240  radius = nullptr ;
241  vars_to_terms() ;
242 }
243 
244 void Domain_polar_shell_outer_adapted::update_variable (const Val_domain& cor_outer_radius, const Scalar& old, Scalar& res) const {
245 
246  Val_domain dr (old(num_dom).der_r()) ;
247  if (dr.check_if_zero())
248  res.set_domain(num_dom) = 0 ;
249  else {
250 
251  Index pos(nbr_points) ;
253  do {
254  res.set_domain(num_dom).set(pos) = dr(pos) * (1+(*coloc[0])(pos(0))) / 2. ;
255  }
256  while (pos.inc()) ;
257 
258  res.set_domain(num_dom) = cor_outer_radius * res(num_dom) + old(num_dom) ;
259  res.set_domain(num_dom).set_base() = old(num_dom).get_base() ;
260  }
261 }
262 
263 
265 
266  Val_domain auxi (this) ;
267  auxi.std_base() ;
268  auxi.set_in_coef() ;
269  auxi.allocate_coef() ;
270  *auxi.cf = 0 ;
271 
272  Index pos_cf (nbr_coefs) ;
273  pos_cf.set(0) = 0 ;
274 
275  for (int j=0 ; j<nbr_coefs(1) ; j++) {
276  pos_cf.set(1)= j ;
277  auxi.cf->set(pos_cf) = xx(pos) ;
278  pos ++ ;
279  }
280 
281  Scalar auxi_scal (sp) ;
282  auxi_scal.set_domain(num_dom) = auxi ;
283  outer_radius_term_eq->set_der_t(auxi_scal) ;
284  update() ;
285 }
286 
287 
289 
290  if (rad_term_eq != nullptr)
291  delete rad_term_eq ;
292  if (der_rad_term_eq != nullptr)
293  delete der_rad_term_eq ;
294  if (dt_rad_term_eq != nullptr)
295  delete dt_rad_term_eq ;
296 
297  // Computation of rad_term_eq
298  Scalar val_res (sp) ;
299  val_res.set_domain(num_dom).allocate_conf() ;
300  Index index (nbr_points) ;
301  do {
302  val_res.set_domain(num_dom).set(index) = (((*outer_radius_term_eq->val_t)()(num_dom))(index) - inner_radius )/2. * ((*coloc[0])(index(0))) +
303  (((*outer_radius_term_eq->val_t)()(num_dom))(index) + inner_radius )/2. ;
304  }
305  while (index.inc()) ;
306  val_res.set_domain(num_dom).std_r_base() ;
307 
308  bool doder = (outer_radius_term_eq->der_t ==nullptr) ? false : true ;
309  if (doder) {
310  Scalar der_res (sp) ;
311  if ((*outer_radius_term_eq->der_t)()(num_dom).check_if_zero()) {
312  der_res.set_domain(num_dom).set_zero() ;
313  }
314  else {
315  der_res.set_domain(num_dom).allocate_conf() ;
316  index.set_start() ;
317  do {
318  der_res.set_domain(num_dom).set(index) = ((*outer_radius_term_eq->der_t)()(num_dom))(index)/2. * ((*coloc[0])(index(0))) +
319  ((*outer_radius_term_eq->der_t)()(num_dom))(index)/2. ;
320  }
321  while (index.inc()) ;
322  der_res.set_domain(num_dom).std_r_base() ;
323  }
324  rad_term_eq = new Term_eq (num_dom, val_res, der_res) ;
325  }
326  else
327  rad_term_eq = new Term_eq (num_dom, val_res) ;
328 
329  // Computation of der_rad_term_eq which is dr / dxi
331  if (doder) {
332  Scalar der_res (sp) ;
333  der_res.set_domain(num_dom) = (*outer_radius_term_eq->der_t)()(num_dom) / 2. ;
334  der_rad_term_eq = new Term_eq (num_dom, val_res, der_res) ;
335  }
336  else
337  der_rad_term_eq = new Term_eq (num_dom, val_res) ;
338 
339  // Computation of dt_rad_term_eq which is dr / d theta
340  val_res.set_domain(num_dom) = (*rad_term_eq->val_t)()(num_dom).der_var(2) ;
341  if (doder) {
342  Scalar der_res (sp) ;
343  der_res.set_domain(num_dom) = (*rad_term_eq->der_t)()(num_dom).der_var(2) ;
344  dt_rad_term_eq = new Term_eq (num_dom, val_res, der_res) ;
345  }
346  else
347  dt_rad_term_eq = new Term_eq (num_dom, val_res) ;
348 
349  do_normal_cart() ;
350 }
351 
353  nbr_points.save(fd) ;
354  nbr_coefs.save(fd) ;
355  fwrite_be (&ndim, sizeof(int), 1, fd) ;
356  fwrite_be (&type_base, sizeof(int), 1, fd) ;
357  center.save(fd) ;
358  fwrite_be (&inner_radius, sizeof(double), 1, fd) ;
359  outer_radius->save(fd) ;
360 }
361 
362 ostream& Domain_polar_shell_outer_adapted::print (ostream& o) const {
363  o << "Adapted polar shell on the inside boundary" << endl ;
364  o << "Center = " << center << endl ;
365  o << "Nbr pts = " << nbr_points << endl ;
366  o << "Inner radius " << inner_radius << endl ;
367  o << "Outer radius " << endl ;
368  o << *outer_radius << endl ;
369  o << endl ;
370  return o ;
371 }
372 
373 
374 
376  cerr << "Domain_polar_shell_outer_adapted::der_normal not implemeted" << endl ;
377  abort() ;
378 }
379 
380 // Computes the cartesian coordinates
382  for (int i=0 ; i<2 ; i++)
383  assert (coloc[i] != nullptr) ;
384  for (int i=0 ; i<2 ; i++)
385  assert (absol[i] == nullptr) ;
386  for (int i=0 ; i<2 ; i++) {
387  absol[i] = new Val_domain(this) ;
388  absol[i]->allocate_conf() ;
389  }
390  Index index (nbr_points) ;
391  do {
392 
393  double rr = ((*outer_radius)(index) - inner_radius)/2. * ((*coloc[0])(index(0))) +
394  ((*outer_radius)(index) + inner_radius)/2. ;
395  absol[0]->set(index) = rr *
396  sin((*coloc[1])(index(1))) + center(1);
397  absol[1]->set(index) = rr * cos((*coloc[1])(index(1))) + center(2) ;
398  }
399  while (index.inc()) ;
400 
401 }
402 
403 // Computes the cartesian coordinates
405  for (int i=0 ; i<2 ; i++)
406  assert (coloc[i] != nullptr) ;
407  for (int i=0 ; i<2 ; i++)
408  assert (cart[i] == nullptr) ;
409  for (int i=0 ; i<2 ; i++) {
410  cart[i] = new Val_domain(this) ;
411  cart[i]->allocate_conf() ;
412  }
413  Index index (nbr_points) ;
414  do {
415  double rr = ((*outer_radius)(index) - inner_radius)/2. * ((*coloc[0])(index(0))) +
416  ((*outer_radius)(index) + inner_radius)/2. ;
417  cart[0]->set(index) = rr *
418  sin((*coloc[1])(index(1))) + center(1);
419  cart[1]->set(index) = rr * cos((*coloc[1])(index(1))) + center(2) ;
420  }
421  while (index.inc()) ;
422 
423 }
424 
425 
426 // Computes the cartesian coordinates over the radius
428  for (int i=0 ; i<2 ; i++)
429  assert (coloc[i] != nullptr) ;
430  for (int i=0 ; i<2 ; i++)
431  assert (cart_surr[i] == nullptr) ;
432  for (int i=0 ; i<2 ; i++) {
433  cart_surr[i] = new Val_domain(this) ;
434  cart_surr[i]->allocate_conf() ;
435  }
436  Index index (nbr_points) ;
437  do {
438  cart_surr[0]->set(index) = sin((*coloc[1])(index(1))) ;
439  cart_surr[1]->set(index) = cos((*coloc[1])(index(1))) ;
440  }
441  while (index.inc()) ;
442 
443 }
444 
445 
446 // Is a point inside this domain ?
447 bool Domain_polar_shell_outer_adapted::is_in (const Point& xx, double prec) const {
448 
449  assert (xx.get_ndim()==2) ;
450  Point num (absol_to_num(xx)) ;
451  bool res = ((num(1)>-1-prec) && (num(1)<1+prec)) ? true : false ;
452  return res ;
453 }
454 
455 
456 // Convert absolute coordinates to numerical ones
458  Point num(2) ;
459 
460  double rho_loc = fabs(abs(1) - center(1)) ;
461  double z_loc = abs(2) - center(2) ;
462  double air = sqrt(rho_loc*rho_loc+z_loc*z_loc) ;
463 
464  if (rho_loc==0) {
465  // On the axis ?
466  num.set(2) = (z_loc>=0) ? 0 : M_PI ;
467  }
468  else {
469  num.set(2) = atan(rho_loc/z_loc) ;
470  }
471 
472  if (num(2) <0)
473  num.set(2) = M_PI + num(2) ;
474 
475  // Get the boundary for those angles
476  num.set(1) = 1 ;
477  outer_radius->coef() ;
478  double outer = outer_radius->get_base().summation(num, outer_radius->get_coef()) ;
479  num.set(1) = (2./(outer-inner_radius)) * (air - (outer + inner_radius)/2.) ;
480 
481  return num ;
482 }
483 
484 
485 double coloc_leg(int, int) ;
487 
488  switch (type_base) {
489  case CHEB_TYPE:
491  del_deriv() ;
492  for (int i=0 ; i<ndim ; i++)
493  coloc[i] = new Array<double> (nbr_points(i)) ;
494  for (int i=0 ; i<nbr_points(0) ; i++)
495  coloc[0]->set(i) = -cos(M_PI*i/(nbr_points(0)-1)) ;
496  for (int j=0 ; j<nbr_points(1) ; j++)
497  coloc[1]->set(j) = M_PI/2.*j/(nbr_points(1)-1) ;
498  break ;
499  case LEG_TYPE:
501  del_deriv() ;
502  for (int i=0 ; i<ndim ; i++)
503  coloc[i] = new Array<double> (nbr_points(i)) ;
504  for (int i=0 ; i<nbr_points(0) ; i++)
505  coloc[0]->set(i) = coloc_leg(i, nbr_points(0)) ;
506  for (int j=0 ; j<nbr_points(1) ; j++)
507  coloc[1]->set(j) = M_PI/2.*j/(nbr_points(1)-1) ;
508  break ;
509  default :
510  cerr << "Unknown type of basis in Domain_polar_shell_outer_adapted::do_coloc" << endl ;
511  abort() ;
512  }
513 }
514 
516  set_cheb_base_with_m(base, 0) ;
517 }
518 
519 // standard base for a anti-symetric function in z, using Chebyshev
521  set_anti_cheb_base_with_m(base, 0) ;
522 }
523 
524 // standard base for a symetric function in z, using Legendre
526  set_legendre_base_with_m(base, 0) ;
527 }
528 
529 // standard base for a anti-symetric function in z, using Legendre
532 }
533 
534 
535 // standard base for a symetric function in z, using Chebyshev
537 
538  assert (type_base == CHEB_TYPE) ;
539 
540  base.allocate(nbr_coefs) ;
541 
542  base.def =true ;
543 
544  base.bases_1d[1]->set(0) = (m%2==0) ? COS_EVEN : SIN_ODD ;
545  for (int j=0 ; j<nbr_coefs(1) ; j++)
546  base.bases_1d[0]->set(j) = CHEB ;
547 }
548 
549 // standard base for a anti-symetric function in z, using Chebyshev
551 
552  assert (type_base == CHEB_TYPE) ;
553 
554  base.allocate(nbr_coefs) ;
555 
556  base.def =true ;
557 
558  base.bases_1d[1]->set(0) = (m%2==0) ? COS_ODD : SIN_EVEN ;
559  for (int j=0 ; j<nbr_coefs(1) ; j++)
560  base.bases_1d[0]->set(j) = CHEB ;
561 }
562 
563 // standard base for a symetric function in z, using Legendre
565 
566  assert (type_base == LEG_TYPE) ;
567 
568  base.allocate(nbr_coefs) ;
569 
570  base.def =true ;
571 
572  base.bases_1d[1]->set(0) = (m%2==0) ? COS_EVEN : SIN_ODD ;
573  for (int j=0 ; j<nbr_coefs(1) ; j++)
574  base.bases_1d[0]->set(j) = LEG ;
575 }
576 
577 // standard base for a anti-symetric function in z, using Legendre
579 
580  assert (type_base == LEG_TYPE) ;
581 
582  base.allocate(nbr_coefs) ;
583 
584  base.def =true ;
585 
586  base.bases_1d[1]->set(0) = (m%2==0) ? COS_ODD : SIN_EVEN ;
587  for (int j=0 ; j<nbr_coefs(1) ; j++)
588  base.bases_1d[0]->set(j) = LEG ;
589 }
590 
591 
593  set_cheb_base_with_m(base, 0) ;
594 }
595 
597  set_legendre_base_with_m(base, 0) ;
598 }
599 
600 // Computes the derivatives with respect to XYZ as a function of the numerical ones.
601 void Domain_polar_shell_outer_adapted::do_der_abs_from_der_var(const Val_domain *const *const der_var, Val_domain **const der_abs) const {
602  Val_domain rr (get_radius()) ;
603  Val_domain dr (*der_var[0] / (*der_rad_term_eq->val_t)()(num_dom)) ;
604  Val_domain dtsr ((*der_var[1] - rr.der_var(2) * dr) / rr);
605  dtsr.set_base() = der_var[1]->get_base() ;
606 
607  // d/dx :
608  Val_domain sintdr (dr.mult_sin_theta()) ;
609  Val_domain costdtsr (dtsr.mult_cos_theta()) ;
610 
611  der_abs[0] = new Val_domain (sintdr+costdtsr) ;
612 
613  // d/dz :
614  der_abs[1] = new Val_domain (dr.mult_cos_theta() - dtsr.mult_sin_theta()) ;
615 }
616 
617 // Rules for the multiplication of two basis.
619 
620  assert (a.ndim==2) ;
621  assert (b.ndim==2) ;
622 
623  Base_spectral res(2) ;
624  bool res_def = true ;
625 
626  if (!a.def)
627  res_def=false ;
628  if (!b.def)
629  res_def=false ;
630 
631  if (res_def) {
632 
633  // Bases in theta :
634  res.bases_1d[1] = new Array<int> (a.bases_1d[1]->get_dimensions()) ;
635  switch ((*a.bases_1d[1])(0)) {
636  case COS_EVEN:
637  switch ((*b.bases_1d[1])(0)) {
638  case COS_EVEN:
639  res.bases_1d[1]->set(0) = COS_EVEN ;
640  break ;
641  case COS_ODD:
642  res.bases_1d[1]->set(0) = COS_ODD ;
643  break ;
644  case SIN_EVEN:
645  res.bases_1d[1]->set(0) = SIN_EVEN ;
646  break ;
647  case SIN_ODD:
648  res.bases_1d[1]->set(0) = SIN_ODD ;
649  break ;
650  default:
651  res_def = false ;
652  break ;
653  }
654  break ;
655  case COS_ODD:
656  switch ((*b.bases_1d[1])(0)) {
657  case COS_EVEN:
658  res.bases_1d[1]->set(0) = COS_ODD ;
659  break ;
660  case COS_ODD:
661  res.bases_1d[1]->set(0) = COS_EVEN ;
662  break ;
663  case SIN_EVEN:
664  res.bases_1d[1]->set(0) = SIN_ODD ;
665  break ;
666  case SIN_ODD:
667  res.bases_1d[1]->set(0) = SIN_EVEN ;
668  break ;
669  default:
670  res_def = false ;
671  break ;
672  }
673  break ;
674  case SIN_EVEN:
675  switch ((*b.bases_1d[1])(0)) {
676  case COS_EVEN:
677  res.bases_1d[1]->set(0) = SIN_EVEN ;
678  break ;
679  case COS_ODD:
680  res.bases_1d[1]->set(0) = SIN_ODD ;
681  break ;
682  case SIN_EVEN:
683  res.bases_1d[1]->set(0) = COS_EVEN ;
684  break ;
685  case SIN_ODD:
686  res.bases_1d[1]->set(0) = COS_ODD ;
687  break ;
688  default:
689  res_def = false ;
690  break ;
691  }
692  break ;
693  case SIN_ODD:
694  switch ((*b.bases_1d[1])(0)) {
695  case COS_EVEN:
696  res.bases_1d[1]->set(0) = SIN_ODD ;
697  break ;
698  case COS_ODD:
699  res.bases_1d[1]->set(0) = SIN_EVEN ;
700  break ;
701  case SIN_EVEN:
702  res.bases_1d[1]->set(0) = COS_ODD ;
703  break ;
704  case SIN_ODD:
705  res.bases_1d[1]->set(0) = COS_EVEN ;
706  break ;
707  default:
708  res_def = false ;
709  break ;
710  }
711  break ;
712  default:
713  res_def = false ;
714  break ;
715  }
716 
717 
718 
719  // Base in r :
720  Index index_0 (a.bases_1d[0]->get_dimensions()) ;
721  res.bases_1d[0] = new Array<int> (a.bases_1d[0]->get_dimensions()) ;
722  do {
723  switch ((*a.bases_1d[0])(index_0)) {
724  case CHEB:
725  switch ((*b.bases_1d[0])(index_0)) {
726  case CHEB:
727  res.bases_1d[0]->set(index_0) = CHEB ;
728  break ;
729  default:
730  res_def = false ;
731  break ;
732  }
733  break ;
734  case LEG:
735  switch ((*b.bases_1d[0])(index_0)) {
736  case LEG:
737  res.bases_1d[0]->set(index_0) = LEG ;
738  break ;
739  default:
740  res_def = false ;
741  break ;
742  }
743  break ;
744  default:
745  res_def = false ;
746  break ;
747  }
748  }
749  while (index_0.inc()) ;
750  }
751 
752  if (!res_def)
753  for (int dim=0 ; dim<a.ndim ; dim++)
754  if (res.bases_1d[dim]!= nullptr) {
755  delete res.bases_1d[dim] ;
756  res.bases_1d[dim] = nullptr ;
757  }
758  res.def = res_def ;
759  return res ;
760 }
761 
762 
763 
764 void Domain_polar_shell_outer_adapted::update_constante (const Val_domain& cor_outer_radius, const Scalar& old, Scalar& res) const {
765 
766  Point MM(2) ;
767  Index pos(nbr_points) ;
769  do {
770 
771  double rr = ((*outer_radius)(pos)+ cor_outer_radius(pos) - inner_radius) * (*coloc[0])(pos(0)) / 2.
772  + ((*outer_radius)(pos)+ cor_outer_radius(pos) + inner_radius) /2.;
773  double theta = (*coloc[1])(pos(1)) ;
774 
775  MM.set(1) = rr*sin(theta) + center(1);
776  MM.set(2) = rr*cos(theta) + center(2);
777 
778  res.set_domain(num_dom).set(pos) = old.val_point(MM, -1) ;
779 
780  }
781  while (pos.inc()) ;
782 
783  res.set_domain(num_dom).set_base() = old(num_dom).get_base() ;
784 }
785 
786 
788  int res = -1 ;
789  if (strcmp(p,"R ")==0)
790  res = 0 ;
791  if (strcmp(p,"T ")==0)
792  res = 1 ;
793  return res ;
794 }
795 }
reference set(const Index &pos)
Read/write of an element.
Definition: array.hpp:186
Class for storing the basis of decompositions of a field.
Bases_container bases_1d
Arrays containing the various basis of decomposition.
double summation(const Point &num, const Array< double > &tab) const
Computes the spectral summation.
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-like domain, having a symmetry with respect to the plane .
virtual void vars_to_terms() const
The Term_eq describing the variable shape of the Domain are updated.
virtual ostream & print(ostream &o) const
Delegate function to virtualize the << operator.
Term_eq * normal_cart
Pointer on the Term_eq containing the normal vector to the outer boundary, in Cartesian coordinates.
virtual void set_legendre_base(Base_spectral &) const
Gives the standard base for Legendre polynomials.
Point center
Absolute coordinates of the center.
virtual void update_variable(const Val_domain &, const Scalar &, Scalar &) const
Update the value of a scalar, after the shape of the Domain has been changed by the system.
void do_normal_cart() const
Computes the normal wrt the inner boundary, in Cartesian coordinates.
const Space & sp
The corresponding Space ; required for updating fields whene the mapping changes.
virtual void do_coloc()
Computes the colocation points.
virtual const Point absol_to_num(const Point &) const
Computes the numerical coordinates from the physical ones.
virtual void set_anti_cheb_base(Base_spectral &) const
Gives the base using Chebyshev polynomials, for functions antisymetric with respect to .
virtual void xx_to_ders_from_adapted(const Array< double > &, int &) const
Affects the derivative part of variable a Domain from a set of values.
virtual void save(FILE *) const
Saving function.
Domain_polar_shell_outer_adapted(const Space &sp, int num, int ttype, double rin, double rout, const Point &cr, const Dim_array &nbr)
Constructor :
virtual void update_mapping(const Val_domain &)
Updates the variables parts of the Domain.
Term_eq * dt_rad_term_eq
Pointer on the Term_eq containing the .
void del_deriv() override
Destroys the derivated members (like coloc, cart and radius), when changing the type of colocation po...
virtual void set_anti_legendre_base(Base_spectral &) const
Gives the base using Legendre polynomials, for functions antisymetric with respect to .
virtual int give_place_var(char *) const
Translates a name of a coordinate into its corresponding numerical name.
virtual void set_anti_legendre_base_with_m(Base_spectral &, int m) const
Gives the base using Legendre polynomials, for functions antisymetric with respect to .
Term_eq * normal_spher
Pointer on the Term_eq containing the normal vector to the outer boundary, in orthonormal spherical c...
virtual Val_domain der_normal(const Val_domain &, int) const
Normal derivative with respect to a given surface.
virtual Base_spectral mult(const Base_spectral &, const Base_spectral &) const
Method for the multiplication of two Base_spectral.
virtual void set_anti_cheb_base_with_m(Base_spectral &, int m) const
Gives the base using Chebyshev polynomials, for functions antisymetric with respect to .
virtual void set_legendre_base_with_m(Base_spectral &, int m) const
Gives the stnadard base using Legendre polynomials.
virtual void xx_to_vars_from_adapted(Val_domain &, const Array< double > &, int &) const
Computes the new boundary of a Domain from a set of values.
virtual void set_cheb_base(Base_spectral &) const
Gives the standard base for Chebyshev polynomials.
virtual Val_domain der_r(const Val_domain &) const
Compute the radial derivative of a scalar field.
virtual void do_radius() const
Computes the generalized radius.
virtual void set_cheb_r_base(Base_spectral &) const
Gives the base using odd Chebyshev polynomials$ for the radius.
virtual void do_der_abs_from_der_var(const Val_domain *const *const der_var, Val_domain **const der_abs) const
Computes the derivative with respect to the absolute Cartesian coordinates from the derivative with r...
virtual int nbr_unknowns_from_adapted() const
Gives the number of unknowns coming from the variable shape of the domain.
virtual void do_absol() const
Computes the absolute coordinates.
Val_domain * outer_radius
Pointer on the outer boundary , as a Val_domain.
virtual void do_cart_surr() const
Computes the Cartesian coordinates over the radius.
void update() const
Updates all the quantities that depend on the inner radius (like the normal vectors).
virtual void do_cart() const
Computes the Cartesian coordinates.
Term_eq * rad_term_eq
Pointer on the Term_eq containing the radius.
virtual void set_cheb_base_with_m(Base_spectral &, int m) const
Gives the standard base using Chebyshev polynomials.
void set_mapping(const Val_domain &so) const
Affects the outer radius.
virtual bool is_in(const Point &xx, double prec=1e-13) const
Check whether a point lies inside Domain.
Term_eq * der_rad_term_eq
Pointer on the Term_eq containing the .
virtual void update_constante(const Val_domain &, const Scalar &, Scalar &) const
Update the value of a scalar, after the shape of the Domain has been changed by the system.
virtual void affecte_coef(int &, int, bool &) const
The variation of the functions describing the shape of the Domain are affected from the unknowns of t...
Term_eq * outer_radius_term_eq
Pointer on the outer boundary , as a Term_eq.
virtual void set_legendre_r_base(Base_spectral &) const
Gives the base using odd Legendre polynomials$ for the radius.
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
Memory_mapped_array< Val_domain * > cart_surr
Cartesian coordinates divided by the radius.
Definition: space.hpp:79
int num_dom
Number of the current domain (used by the Space)
Definition: space.hpp:63
Dim_array nbr_coefs
Number of coefficients.
Definition: space.hpp:66
Val_domain const & get_radius() const
Returns the generalized radius.
Definition: space.hpp:1465
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
void set_start()
Sets the position to zero in all dimensions.
Definition: index.hpp:88
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
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
The class Scalar does not really implements scalars in the mathematical sense but rather tensorial co...
Definition: scalar.hpp:67
Val_domain & set_domain(int)
Read/write of a particular Val_domain.
Definition: scalar.hpp:555
double val_point(const Point &xxx, int sens=-1) const
Computes the value of the field at a given point, by doing the spectral summation.
Definition: scalar.cpp:62
The Space class is an ensemble of domains describing the whole space of the computation.
Definition: space.hpp:1362
This class is intended to describe the manage objects appearing in the equations.
Definition: term_eq.hpp:62
Tensor * der_t
Pointer on the variation, if the Term_eq is a Tensor.
Definition: term_eq.hpp:69
void set_der_t(Tensor)
Sets the tensorial variation (only the values in the pertinent Domain are copied).
Definition: term_eq.cpp:171
void set_der_zero()
Sets the variation of the approriate type to zero.
Definition: term_eq.cpp:187
Tensor * val_t
Pointer on the value, if the Term_eq is a Tensor.
Definition: term_eq.hpp:68
Class for storing the basis of decompositions of a field and its values on both the configuration and...
Definition: val_domain.hpp:69
void save(FILE *) const
Saving on a file.
Definition: val_domain.cpp:110
void set_in_coef()
Destroys the values in the configuration space.
Definition: val_domain.cpp:203
void set_zero()
Sets the Val_domain to zero (logical state to zero and arrays destroyed).
Definition: val_domain.cpp:223
void allocate_coef()
Allocates the values in the coefficient space and destroys the values in the configuration space.
Definition: val_domain.cpp:216
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 .
Array< double > * cf
Pointer on the Array of the values in the coefficients space.
Definition: val_domain.hpp:77
void std_r_base()
Sets the basis for the radius.
Definition: val_domain.cpp:262
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 mult_cos_theta() 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
Base_spectral & set_base()
Sets the basis of decomposition.
Definition: val_domain.hpp:126
Array< double > get_coef() const
Definition: val_domain.hpp:136
void allocate_conf()
Allocates the values in the configuration space and destroys the values in the coefficients space.
Definition: val_domain.cpp:209
const Base_spectral & get_base() const
Returns the basis of decomposition.
Definition: val_domain.hpp:122