KADATH
domain_oned_inf.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 "oned.hpp"
23 #include "point.hpp"
24 #include "array_math.hpp"
25 #include "val_domain.hpp"
26 
27 namespace Kadath {
28 void coef_1d (int, Array<double>&) ;
29 void coef_i_1d (int, Array<double>&) ;
30 int der_1d (int, Array<double>&) ;
31 
32 // Standard constructor
33 Domain_oned_inf::Domain_oned_inf (int num, int ttype, double x_int, const Dim_array& nbr) :
34  Domain(num, ttype, nbr), alpha(-0.5/x_int) {
35  assert (nbr.get_ndim()==1) ;
36  do_coloc() ;
37 }
38 
39 // Constructor by copy
40 Domain_oned_inf::Domain_oned_inf (const Domain_oned_inf& so) : Domain(so), alpha(so.alpha) {
41 }
42 
43 Domain_oned_inf::Domain_oned_inf (int num, FILE* fd) : Domain(num, fd) {
44  fread_be (&alpha, sizeof(double), 1, fd) ;
45  do_coloc() ;
46 }
47 
48 // Destructor
49 Domain_oned_inf::~Domain_oned_inf() {}
50 
51 void Domain_oned_inf::save (FILE* fd) const {
52  nbr_points.save(fd) ;
53  nbr_coefs.save(fd) ;
54  fwrite_be (&ndim, sizeof(int), 1, fd) ;
55  fwrite_be (&type_base, sizeof(int), 1, fd) ;
56  fwrite_be (&alpha, sizeof(double), 1, fd) ;
57 }
58 
59 ostream& Domain_oned_inf::print (ostream& o) const {
60  o << "One dimensional domain up to infinity" << endl ;
61  o << -0.5/alpha << " < X " << endl ;
62  o << "Nbr pts = " << nbr_points << endl ;
63  o << endl ;
64  return o ;
65 }
66 
67 
68 Val_domain Domain_oned_inf::der_normal (const Val_domain& so, int bound) const {
69 
70  Val_domain res (so.der_var(1)) ;
71  switch (bound) {
72  case OUTER_BC :
73  res = res.mult_xm1() ;
74  res = res.mult_xm1() ;
75  res *= -alpha ;
76  break ;
77  case INNER_BC :
78  res = res.mult_xm1() ;
79  res = res.mult_xm1() ;
80  res *= -alpha ;
81  break ;
82 
83  default:
84  cerr << "Unknown boundary case in Domain_oned_inf::der_normal" << endl ;
85  abort() ;
86  }
87 return res ;
88 }
89 
90 // Computes the cartesian coordinates
92  assert (coloc[0] != 0x0) ;
93  assert (absol[0] == 0x0) ;
94  absol[0] = new Val_domain(this) ;
95  absol[0]->allocate_conf() ;
96 
97  Index index (nbr_points) ;
98  do {
99  absol[0]->set(index) = 1./alpha / ((*coloc[0])(index(0))-1) ;
100  }
101  while (index.inc()) ;
102 
103 }
104 
106 
107  assert (coloc[0] != 0x0) ;
108  assert (radius == 0x0) ;
109  radius = new Val_domain(this) ;
110  radius->allocate_conf() ;
111  Index index (nbr_points) ;
112  do
113  radius->set(index) = 1./alpha / ((*coloc[0])(index(0))-1) ;
114  while (index.inc()) ;
115 }
116 
117 // Is a point inside this domain ?
118 bool Domain_oned_inf::is_in (const Point& xx, double prec) const {
119 
120  assert (xx.get_ndim()==1) ;
121  bool res = (xx(1)>=-0.5/alpha-prec) ? true : false ;
122  return res ;
123 }
124 
125 // Convert absolute coordinates to numerical ones
126 const Point Domain_oned_inf::absol_to_num(const Point& abs) const {
127 
128  assert (is_in(abs)) ;
129  Point num(1) ;
130  num.set(1) = 1 + 1./abs(1)/alpha ;
131  return num ;
132 }
133 
134 double coloc_leg(int, int) ;
136 
137  switch (type_base) {
138  case CHEB_TYPE:
140  del_deriv() ;
141  coloc[0] = new Array<double> (nbr_points(0)) ;
142  for (int i=0 ; i<nbr_points(0) ; i++)
143  coloc[0]->set(i) = -cos(M_PI*i/(nbr_points(0)-1)) ;
144  break ;
145  case LEG_TYPE:
147  del_deriv() ;
148  coloc[0] = new Array<double> (nbr_points(0)) ;
149  for (int i=0 ; i<nbr_points(0) ; i++)
150  coloc[0]->set(i) = coloc_leg(i, nbr_points(0)) ;
151  break ;
152  default :
153  cerr << "Unknown type of basis in Domain_oned_inf::do_coloc" << endl ;
154  abort() ;
155  }
156 }
157 
158 // Base for a function symetric in z, using Chebyshev
160  assert (type_base == CHEB_TYPE) ;
161  base.allocate(nbr_coefs) ;
162 
163  base.def=true ;
164  base.bases_1d[0]->set(0) = CHEB ;
165 }
166 
167 // Base for a function symetric in z, using Legendre
169  assert (type_base == LEG_TYPE) ;
170  base.allocate(nbr_coefs) ;
171 
172  base.def=true ;
173  base.bases_1d[0]->set(0) = LEG ;
174  }
175  // Base for a function symetric in z, using Chebyshev
177  assert (type_base == CHEB_TYPE) ;
178  base.allocate(nbr_coefs) ;
179 
180  base.def=true ;
181  base.bases_1d[0]->set(0) = CHEB ;
182 }
183 
184 // Base for a function symetric in z, using Legendre
186  assert (type_base == LEG_TYPE) ;
187  base.allocate(nbr_coefs) ;
188 
189  base.def=true ;
190  base.bases_1d[0]->set(0) = LEG ;
191  }
192 // sets the value at infinity
193 void Domain_oned_inf::set_val_inf (Val_domain& so, double x) const {
194 
195  assert (so.get_domain() == this) ;
196 
197  so.coef_i() ;
198  so.set_in_conf() ;
199  Index inf (nbr_points) ;
200  inf.set(0) = nbr_points(0)-1 ;
201  so.set(inf) = x ;
202 }
203 
204 // Computes the derivatives with respect to rho,Z as a function of the numerical ones.
205 void Domain_oned_inf::do_der_abs_from_der_var(const Val_domain *const *const der_var, Val_domain **const der_abs) const {
206  der_abs[0] = new Val_domain (-alpha*der_var[0]->mult_xm1().mult_xm1()) ;
207 }
208 
209 // Rules for the multiplication of two basis.
211 
212  assert (a.ndim==1) ;
213  assert (b.ndim==1) ;
214 
215  Base_spectral res(1) ;
216  bool res_def = true ;
217 
218  if (!a.def)
219  res_def=false ;
220  if (!b.def)
221  res_def=false ;
222 
223  if (res_def) {
224 
225 
226  // Bases in theta :
227  res.bases_1d[0] = new Array<int> (a.bases_1d[0]->get_dimensions()) ;
228  switch ((*a.bases_1d[0])(0)) {
229  case CHEB:
230  switch ((*b.bases_1d[0])(0)) {
231  case CHEB:
232  res.bases_1d[0]->set(0) = CHEB ;
233  break ;
234  default:
235  res_def = false ;
236  break ;
237  }
238  break ;
239 
240  case LEG:
241  switch ((*b.bases_1d[0])(0)) {
242  case LEG:
243  res.bases_1d[0]->set(0) = LEG ;
244  break ;
245  default:
246  res_def = false ;
247  break ;
248  }
249  break ;
250  default:
251  res_def = false ;
252  break ;
253  }
254  }
255  if (!res_def)
256  for (int dim=0 ; dim<a.ndim ; dim++)
257  if (res.bases_1d[dim]!= 0x0) {
258  delete res.bases_1d[dim] ;
259  res.bases_1d[dim] = 0x0 ;
260  }
261  res.def = res_def ;
262  return res ;
263 }
264 
265 int Domain_oned_inf::give_place_var (char* p) const {
266  int res = -1 ;
267  if (strcmp(p,"X ")==0)
268  res = 0 ;
269  return res ;
270 }}
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 1-dimensional compactified spherical domain.
Definition: oned.hpp:319
virtual Val_domain mult_xm1(const Val_domain &) const
Multiplication by .
virtual void set_legendre_base_odd(Base_spectral &) const
Gives the base using odd Legendre polynomials$.
virtual int give_place_var(char *) const
Translates a name of a coordinate into its corresponding numerical name.
virtual void save(FILE *) const
Saving function.
Domain_oned_inf(int num, int ttype, double radius, const Dim_array &nbr)
Standard constructor :
virtual const Point absol_to_num(const Point &) const
Computes the numerical coordinates from the physical ones.
virtual void set_cheb_base_odd(Base_spectral &) const
Gives the base using odd Chebyshev polynomials$.
virtual bool is_in(const Point &xx, double prec=1e-13) const
Check whether a point lies inside Domain.
double alpha
Relates the numerical radius to the physical one.
Definition: oned.hpp:322
virtual void do_coloc()
Computes the colocation points.
virtual Val_domain der_normal(const Val_domain &, int) const
Normal derivative with respect to a given surface.
virtual 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 do_absol() const
Computes the absolute coordinates.
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 do_radius() const
Computes the generalized radius.
virtual void set_legendre_base(Base_spectral &) const
Gives the standard base for Legendre polynomials.
virtual Base_spectral mult(const Base_spectral &, const Base_spectral &) const
Method for the multiplication of two Base_spectral.
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.
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 * > 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
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
void set_in_conf()
Destroys the values in the coefficient space.
Definition: val_domain.cpp:197
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_xm1() const
Multiplication by .
Val_domain der_var(int i) const
Computes the derivative with respect to a numerical coordinate.
Definition: val_domain.cpp:670
void allocate_conf()
Allocates the values in the configuration space and destroys the values in the coefficients space.
Definition: val_domain.cpp:209
const Domain * get_domain() const
Definition: val_domain.hpp:111