KADATH
domain_polar_shell.cpp
1 /*
2  Copyright 2017 Philippe Grandclement
3 
4  This file is part of Kadath.
5 
6  Kadath is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  Kadath is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with Kadath. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #include "headcpp.hpp"
21 #include "utilities.hpp"
22 #include "polar.hpp"
23 #include "point.hpp"
24 #include "array_math.hpp"
25 #include "val_domain.hpp"
26 namespace Kadath {
27 // Standard constructor
28 Domain_polar_shell::Domain_polar_shell (int num, int ttype, double rint, double rext, const Point& cr, const Dim_array& nbr) : Domain(num, ttype, nbr),
29  alpha((rext-rint)/2.), beta((rext+rint)/2.), center(cr) {
30 
31  assert (nbr.get_ndim()==2) ;
32  assert (cr.get_ndim()==2) ; // Affectation de type_point :
33  do_coloc() ;
34 
35 }
36 
37 
38 // Constructor by copy
40  beta(so.beta), center(so.center){}
41 
42 
43 
44 Domain_polar_shell::Domain_polar_shell (int num, FILE* fd) : Domain(num, fd), center(fd) {
45  fread_be (&alpha, sizeof(double), 1, fd) ;
46  fread_be (&beta, sizeof(double), 1, fd) ;
47  do_coloc() ;
48 }
49 
50 // Destructor
51 Domain_polar_shell::~Domain_polar_shell() {}
52 
53 void Domain_polar_shell::save (FILE* fd) const {
54  nbr_points.save(fd) ;
55  nbr_coefs.save(fd) ;
56  fwrite_be (&ndim, sizeof(int), 1, fd) ;
57  fwrite_be (&type_base, sizeof(int), 1, fd) ;
58  center.save(fd) ;
59  fwrite_be (&alpha, sizeof(double), 1, fd) ;
60  fwrite_be (&beta, sizeof(double), 1, fd) ;
61 }
62 
63 ostream& Domain_polar_shell::print (ostream& o) const {
64  o << "Polar shell" << endl ;
65  o << beta-alpha << " < r < " << beta+alpha << endl ;
66  o << "Center = " << center << endl ;
67  o << "Nbr pts = " << nbr_points << endl ;
68  o << endl ;
69  return o ;
70 }
71 
72 
73 
75 
76  Val_domain res (so.der_var(1)) ;
77  switch (bound) {
78  case OUTER_BC :
79  res /= alpha ;
80  break ;
81  case INNER_BC :
82  res /= alpha ;
83  break ;
84 
85  default:
86  cerr << "Unknown boundary case in Domain_polar_shell::der_normal" << endl ;
87  abort() ;
88  }
89 return res ;
90 }
91 
92 
93 // Computes the Cartesian coordinates
95  for (int i=0 ; i<2 ; i++)
96  assert (coloc[i] != 0x0) ;
97  for (int i=0 ; i<2 ; i++)
98  assert (absol[i] == 0x0) ;
99  for (int i=0 ; i<2 ; i++) {
100  absol[i] = new Val_domain(this) ;
101  absol[i]->allocate_conf() ;
102  }
103  Index index (nbr_points) ;
104 
105  do {
106  absol[0]->set(index) = (alpha* ((*coloc[0])(index(0))) +beta)*
107  sin((*coloc[1])(index(1))) + center(1) ;
108  absol[1]->set(index) = (alpha* ((*coloc[0])(index(0))) + beta) * cos((*coloc[1])(index(1))) + center(2) ;
109  }
110  while (index.inc()) ;
111 }
112 
113 // Computes the radius
115  for (int i=0 ; i<2 ; i++)
116  assert (coloc[i] != 0x0) ;
117  assert (radius == 0x0) ;
118  radius = new Val_domain(this) ;
119  radius->allocate_conf() ;
120  Index index (nbr_points) ;
121  do
122  radius->set(index) = alpha* ((*coloc[0])(index(0))) + beta ;
123  while (index.inc()) ;
124 }
125 
126 // Computes the Cartesian coordinates
128  for (int i=0 ; i<2 ; i++)
129  assert (coloc[i] != 0x0) ;
130  for (int i=0 ; i<2 ; i++)
131  assert (cart[i] == 0x0) ;
132  for (int i=0 ; i<2 ; i++) {
133  cart[i] = new Val_domain(this) ;
134  cart[i]->allocate_conf() ;
135  }
136  Index index (nbr_points) ;
137 
138  do {
139  cart[0]->set(index) = (alpha* ((*coloc[0])(index(0))) +beta)*
140  sin((*coloc[1])(index(1))) + center(1) ;
141  cart[1]->set(index) = (alpha* ((*coloc[0])(index(0))) + beta) * cos((*coloc[1])(index(1))) + center(2) ;
142  }
143  while (index.inc()) ;
144 }
145 
146 // Computes the Cartesian coordinates
148  for (int i=0 ; i<2 ; i++)
149  assert (coloc[i] != 0x0) ;
150  for (int i=0 ; i<2 ; i++)
151  assert (cart_surr[i] == 0x0) ;
152  for (int i=0 ; i<2 ; i++) {
153  cart_surr[i] = new Val_domain(this) ;
154  cart_surr[i]->allocate_conf() ;
155  }
156  Index index (nbr_points) ;
157 
158  do {
159  cart_surr[0]->set(index) = sin((*coloc[1])(index(1))) + center(1) ;
160  cart_surr[1]->set(index) = cos((*coloc[1])(index(1))) + center(2) ;
161  }
162  while (index.inc()) ;
163 }
164 
165 // Check if a point is inside this domain
166 bool Domain_polar_shell::is_in (const Point& xx, double prec) const {
167 
168  assert (xx.get_ndim()==2) ;
169 
170  double rho_loc = xx(1) - center(1) ;
171  double z_loc = xx(2) - center(2) ;
172  double air_loc = sqrt (rho_loc*rho_loc + z_loc*z_loc) ;
173 
174  bool res = ((air_loc <= alpha+beta+prec) && (air_loc >= beta-alpha-prec)) ? true : false ;
175  return res ;
176 }
177 
178 //Computes the numerical coordinates, as a function of the absolute ones.
180 
181  assert (is_in(abs)) ;
182  Point num(2) ;
183 
184  double rho_loc = fabs(abs(1) - center(1)) ;
185  double z_loc = abs(2) - center(2) ;
186  double air = sqrt(rho_loc*rho_loc+z_loc*z_loc) ;
187  num.set(1) = (air-beta)/alpha ;
188 
189  if (rho_loc==0) {
190  // On the axis ?
191  num.set(2) = (z_loc>=0) ? 0 : M_PI ;
192  }
193  else {
194  num.set(2) = atan(rho_loc/z_loc) ;
195  }
196 
197  if (num(2) <0)
198  num.set(2) = M_PI + num(2) ;
199 
200  return num ;
201 }
202 
203 double coloc_leg (int, int) ;
205 
206  switch (type_base) {
207  case CHEB_TYPE:
209  del_deriv() ;
210  for (int i=0 ; i<ndim ; i++)
211  coloc[i] = new Array<double> (nbr_points(i)) ;
212  for (int i=0 ; i<nbr_points(0) ; i++)
213  coloc[0]->set(i) = -cos(M_PI*i/(nbr_points(0)-1)) ;
214  for (int j=0 ; j<nbr_points(1) ; j++)
215  coloc[1]->set(j) = M_PI/2.*j/(nbr_points(1)-1) ;
216  break ;
217  case LEG_TYPE:
219  del_deriv() ;
220  for (int i=0 ; i<ndim ; i++)
221  coloc[i] = new Array<double> (nbr_points(i)) ;
222  for (int i=0 ; i<nbr_points(0) ; i++)
223  coloc[0]->set(i) = coloc_leg(i, nbr_points(0)) ;
224  for (int j=0 ; j<nbr_points(1) ; j++)
225  coloc[1]->set(j) = M_PI/2.*j/(nbr_points(1)-1) ;
226  break ;
227  default :
228  cerr << "Unknown type of basis in Domain_polar_shell::do_coloc" << endl ;
229  abort() ;
230  }
231 }
232 // standard base for a symetric function in z, using Chebyshev
234  set_cheb_base_with_m(base, 0) ;
235 }
236 
237 // standard base for a anti-symetric function in z, using Chebyshev
239  set_anti_cheb_base_with_m(base, 0) ;
240 }
241 
242 // standard base for a symetric function in z, using Legendre
244  set_legendre_base_with_m(base, 0) ;
245 }
246 
247 // standard base for a anti-symetric function in z, using Legendre
250 }
251 
252 
253 // standard base for a symetric function in z, using Chebyshev
255 
256  assert (type_base == CHEB_TYPE) ;
257 
258  base.allocate(nbr_coefs) ;
259 
260  base.def =true ;
261 
262  base.bases_1d[1]->set(0) = (m%2==0) ? COS_EVEN : SIN_ODD ;
263  for (int j=0 ; j<nbr_coefs(1) ; j++)
264  base.bases_1d[0]->set(j) = CHEB ;
265 }
266 
267 // standard base for a anti-symetric function in z, using Chebyshev
269 
270  assert (type_base == CHEB_TYPE) ;
271 
272  base.allocate(nbr_coefs) ;
273 
274  base.def =true ;
275 
276  base.bases_1d[1]->set(0) = (m%2==0) ? COS_ODD : SIN_EVEN ;
277  for (int j=0 ; j<nbr_coefs(1) ; j++)
278  base.bases_1d[0]->set(j) = CHEB ;
279 }
280 
281 // standard base for a symetric function in z, using Legendre
283 
284  assert (type_base == CHEB_TYPE) ;
285 
286  base.allocate(nbr_coefs) ;
287 
288  base.def =true ;
289 
290  base.bases_1d[1]->set(0) = (m%2==0) ? COS_EVEN : SIN_ODD ;
291  for (int j=0 ; j<nbr_coefs(1) ; j++)
292  base.bases_1d[0]->set(j) = LEG ;
293 }
294 
295 // standard base for a anti-symetric function in z, using Legendre
297 
298  assert (type_base == CHEB_TYPE) ;
299 
300  base.allocate(nbr_coefs) ;
301 
302  base.def =true ;
303 
304  base.bases_1d[1]->set(0) = (m%2==0) ? COS_ODD : SIN_EVEN ;
305  for (int j=0 ; j<nbr_coefs(1) ; j++)
306  base.bases_1d[0]->set(j) = LEG ;
307 }
308 
309 // Computes the derivatives with respect to XYZ as a function of the numerical ones.
310 void Domain_polar_shell::do_der_abs_from_der_var(const Val_domain *const *const der_var, Val_domain **const der_abs) const {
311 
312  Val_domain dr (*der_var[0]/alpha) ;
313  Val_domain dtsr (*der_var[1]/get_radius()) ;
314  dtsr.set_base() = der_var[1]->get_base() ;
315 
316  // D / drho
317  der_abs[0] = new Val_domain (dr.mult_sin_theta() + dtsr.mult_cos_theta()) ;
318  // d/dz :
319  der_abs[1] = new Val_domain (dr.mult_cos_theta() - dtsr.mult_sin_theta()) ;
320 }
321 
322 // Rules for the multiplication of two basis.
324 
325  assert (a.ndim==2) ;
326  assert (b.ndim==2) ;
327 
328  Base_spectral res(2) ;
329  bool res_def = true ;
330 
331  if (!a.def)
332  res_def=false ;
333  if (!b.def)
334  res_def=false ;
335 
336  if (res_def) {
337 
338  // Bases in theta :
339  res.bases_1d[1] = new Array<int> (a.bases_1d[1]->get_dimensions()) ;
340  switch ((*a.bases_1d[1])(0)) {
341  case COS_EVEN:
342  switch ((*b.bases_1d[1])(0)) {
343  case COS_EVEN:
344  res.bases_1d[1]->set(0) = COS_EVEN ;
345  break ;
346  case COS_ODD:
347  res.bases_1d[1]->set(0) = COS_ODD ;
348  break ;
349  case SIN_EVEN:
350  res.bases_1d[1]->set(0) = SIN_EVEN ;
351  break ;
352  case SIN_ODD:
353  res.bases_1d[1]->set(0) = SIN_ODD ;
354  break ;
355  default:
356  res_def = false ;
357  break ;
358  }
359  break ;
360  case COS_ODD:
361  switch ((*b.bases_1d[1])(0)) {
362  case COS_EVEN:
363  res.bases_1d[1]->set(0) = COS_ODD ;
364  break ;
365  case COS_ODD:
366  res.bases_1d[1]->set(0) = COS_EVEN ;
367  break ;
368  case SIN_EVEN:
369  res.bases_1d[1]->set(0) = SIN_ODD ;
370  break ;
371  case SIN_ODD:
372  res.bases_1d[1]->set(0) = SIN_EVEN ;
373  break ;
374  default:
375  res_def = false ;
376  break ;
377  }
378  break ;
379  case SIN_EVEN:
380  switch ((*b.bases_1d[1])(0)) {
381  case COS_EVEN:
382  res.bases_1d[1]->set(0) = SIN_EVEN ;
383  break ;
384  case COS_ODD:
385  res.bases_1d[1]->set(0) = SIN_ODD ;
386  break ;
387  case SIN_EVEN:
388  res.bases_1d[1]->set(0) = COS_EVEN ;
389  break ;
390  case SIN_ODD:
391  res.bases_1d[1]->set(0) = COS_ODD ;
392  break ;
393  default:
394  res_def = false ;
395  break ;
396  }
397  break ;
398  case SIN_ODD:
399  switch ((*b.bases_1d[1])(0)) {
400  case COS_EVEN:
401  res.bases_1d[1]->set(0) = SIN_ODD ;
402  break ;
403  case COS_ODD:
404  res.bases_1d[1]->set(0) = SIN_EVEN ;
405  break ;
406  case SIN_EVEN:
407  res.bases_1d[1]->set(0) = COS_ODD ;
408  break ;
409  case SIN_ODD:
410  res.bases_1d[1]->set(0) = COS_EVEN ;
411  break ;
412  default:
413  res_def = false ;
414  break ;
415  }
416  break ;
417  default:
418  res_def = false ;
419  break ;
420  }
421 
422 
423 
424  // Base in r :
425  Index index_0 (a.bases_1d[0]->get_dimensions()) ;
426  res.bases_1d[0] = new Array<int> (a.bases_1d[0]->get_dimensions()) ;
427  do {
428  switch ((*a.bases_1d[0])(index_0)) {
429  case CHEB:
430  switch ((*b.bases_1d[0])(index_0)) {
431  case CHEB:
432  res.bases_1d[0]->set(index_0) = CHEB ;
433  break ;
434  default:
435  res_def = false ;
436  break ;
437  }
438  break ;
439  case LEG:
440  switch ((*b.bases_1d[0])(index_0)) {
441  case LEG:
442  res.bases_1d[0]->set(index_0) = LEG ;
443  break ;
444  default:
445  res_def = false ;
446  break ;
447  }
448  break ;
449  default:
450  res_def = false ;
451  break ;
452  }
453  }
454  while (index_0.inc()) ;
455  }
456 
457  if (!res_def)
458  for (int dim=0 ; dim<a.ndim ; dim++)
459  if (res.bases_1d[dim]!= 0x0) {
460  delete res.bases_1d[dim] ;
461  res.bases_1d[dim] = 0x0 ;
462  }
463  res.def = res_def ;
464  return res ;
465 }
466 
468  int res = -1 ;
469  if (strcmp(p,"R ")==0)
470  res = 0 ;
471  if (strcmp(p,"T ")==0)
472  res = 1 ;
473  return res ;
474 }
475 
476 }
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 2-dimensional spherical shell and a symmetry with respect to the plane .
Definition: polar.hpp:221
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 do_cart_surr() const
Computes the Cartesian coordinates over the radius.
double beta
Relates the numerical to the physical radii.
Definition: polar.hpp:225
virtual void set_anti_cheb_base(Base_spectral &) const
Gives the base using Chebyshev polynomials, for functions antisymetric with respect to .
Domain_polar_shell(int num, int ttype, double r_int, double r_ext, const Point &cr, const Dim_array &nbr)
Standard constructor :
virtual Base_spectral mult(const Base_spectral &, const Base_spectral &) const
Method for the multiplication of two Base_spectral.
double alpha
Relates the numerical to the physical radii.
Definition: polar.hpp:224
virtual void save(FILE *) const
Saving function.
virtual void do_der_abs_from_der_var(const Val_domain *const *const der_var, Val_domain **const der_abs) const
Computes the derivative with respect to the absolute Cartesian coordinates from the derivative with r...
virtual const Point absol_to_num(const Point &) const
Computes the numerical coordinates from the physical ones.
Point center
Absolute coordinates of the center.
Definition: polar.hpp:226
virtual void do_radius() const
Computes the generalized radius.
virtual bool is_in(const Point &xx, double prec=1e-13) const
Check whether a point lies inside Domain.
virtual void set_anti_legendre_base_with_m(Base_spectral &, int m) const
Gives the base using Legendre polynomials, for functions antisymetric with respect to .
virtual void set_cheb_base(Base_spectral &) const
Gives the standard base for Chebyshev polynomials.
virtual ostream & print(ostream &o) const
Delegate function to virtualize the << operator.
virtual int give_place_var(char *) const
Translates a name of a coordinate into its corresponding numerical name.
virtual void set_cheb_base_with_m(Base_spectral &, int m) const
Gives the standard base using Chebyshev polynomials.
virtual void set_legendre_base(Base_spectral &) const
Gives the standard base for Legendre polynomials.
virtual Val_domain der_normal(const Val_domain &, int) const
Normal derivative with respect to a given surface.
virtual void do_cart() const
Computes the Cartesian coordinates.
virtual void do_coloc()
Computes the colocation points.
virtual void set_anti_legendre_base(Base_spectral &) const
Gives the base using Legendre polynomials, for functions antisymetric with respect to .
virtual void do_absol() const
Computes the absolute coordinates.
Abstract class that implements the fonctionnalities common to all the type of domains.
Definition: space.hpp:60
virtual void del_deriv()
Destroys the derivated members (like coloc, cart and radius), when changing the type of colocation po...
Definition: domain.cpp:77
Val_domain * radius
The generalized radius.
Definition: space.hpp:78
Memory_mapped_array< Val_domain * > cart
Cartesian coordinates.
Definition: space.hpp:77
Memory_mapped_array< Val_domain * > absol
Asbolute coordinates (if defined ; usually Cartesian-like)
Definition: space.hpp:76
int ndim
Number of dimensions.
Definition: space.hpp:64
Memory_mapped_array< Val_domain * > cart_surr
Cartesian coordinates divided by the radius.
Definition: space.hpp:79
Dim_array nbr_coefs
Number of coefficients.
Definition: space.hpp:66
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
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
Class for storing the basis of decompositions of a field and its values on both the configuration and...
Definition: val_domain.hpp:69
Val_domain mult_sin_theta() const
Multiplication by .
double & set(const Index &pos)
Read/write the value of the field in the configuration space.
Definition: val_domain.cpp:171
Val_domain mult_cos_theta() const
Multiplication by .
Val_domain der_var(int i) const
Computes the derivative with respect to a numerical coordinate.
Definition: val_domain.cpp:670
Base_spectral & set_base()
Sets the basis of decomposition.
Definition: val_domain.hpp:126
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