KADATH
domain_critic_inner.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 "critic.hpp"
23 #include "point.hpp"
24 #include "array_math.hpp"
25 #include "val_domain.hpp"
26 namespace Kadath {
27 // Standard constructor
28 Domain_critic_inner::Domain_critic_inner (int num, int ttype, const Dim_array& nbr, double xx) : Domain(num, ttype, nbr), p_X(nullptr), p_T(nullptr), xlim(xx) {
29  do_coloc() ;
30 }
31 
32 
33 // Constructor by copy
35  p_X = (so.p_X!=nullptr) ? new Val_domain(*so.p_X) : nullptr ;
36  p_T = (so.p_T!=nullptr) ? new Val_domain(*so.p_T) : nullptr ;
37  xlim = so.xlim ;
38 }
39 
40 
41 Domain_critic_inner::Domain_critic_inner (int num, FILE* fd) : Domain(num, fd) {
42  do_coloc() ;
43  p_X = nullptr ;
44  p_T = nullptr ;
45  fread_be (&xlim, sizeof(double), 1, fd) ;
46 }
47 
48 // Destructor
49 Domain_critic_inner::~Domain_critic_inner() {
50  del_deriv() ;
51 }
52 
54  for (int l=0 ; l<ndim ; l++) safe_delete(coloc[l]);
55  safe_delete(p_X);
56  safe_delete(p_T);
57 }
58 
59 void Domain_critic_inner::save (FILE* fd) const {
60  nbr_points.save(fd) ;
61  nbr_coefs.save(fd) ;
62  fwrite_be (&ndim, sizeof(int), 1, fd) ;
63  fwrite_be (&type_base, sizeof(int), 1, fd) ;
64  fwrite_be (&xlim, sizeof(double), 1, fd) ;
65 }
66 
67 ostream& Domain_critic_inner::print (ostream& o) const {
68  o << "Inner critic domain (cylindric)" << endl ;
69  o << "Nbr pts = " << nbr_points << endl ;
70  o << "X max = " << xlim << endl ;
71  o << endl ;
72  return o ;
73 }
74 
75 double coloc_leg_parity (int, int) ;
77 
78  switch (type_base) {
79  case CHEB_TYPE:
81  nbr_coefs.set(1) += 2 ;
82  del_deriv() ;
83  for (int i=0 ; i<ndim ; i++)
84  coloc[i] = new Array<double> (nbr_points(i)) ;
85  for (int i=0 ; i<nbr_points(0) ; i++)
86  coloc[0]->set(i) = xlim*sin(M_PI*i/(nbr_points(0)-1)/2.) ;
87  for (int j=0 ; j<nbr_points(1) ; j++)
88  coloc[1]->set(j) = M_PI*j/nbr_points(1) ;
89  break ;
90  case LEG_TYPE:
92  nbr_coefs.set(1) += 2 ;
93  del_deriv() ;
94  for (int i=0 ; i<ndim ; i++)
95  coloc[i] = new Array<double> (nbr_points(i)) ;
96  for (int i=0 ; i<nbr_points(0) ; i++)
97  coloc[0]->set(i) = xlim*coloc_leg_parity(i, nbr_points(0)) ;
98  for (int j=0 ; j<nbr_points(1) ; j++)
99  coloc[1]->set(j) = M_PI*j/nbr_points(1) ;
100  break ;
101  default :
102  cerr << "Unknown type of basis in Domain_critic_inner::do_coloc" << endl ;
103  abort() ;
104  }
105 }
106 
108  for (int i=0 ; i<2 ; i++)
109  assert (coloc[i] != nullptr) ;
110  assert (p_X==nullptr) ;
111  p_X= new Val_domain(this) ;
112  p_X->allocate_conf() ;
113  Index index (nbr_points) ;
114  do
115  p_X->set(index) = (*coloc[0])(index(0)) ;
116  while (index.inc()) ;
117 }
118 
120  for (int i=0 ; i<2 ; i++)
121  assert (coloc[i] != nullptr) ;
122  assert (p_T==nullptr) ;
123  p_T= new Val_domain(this) ;
124  p_T->allocate_conf() ;
125  Index index (nbr_points) ;
126  do
127  p_T->set(index) = (*coloc[1])(index(1)) ;
128  while (index.inc()) ;
129 }
130 
131 
132 
134  if (p_X==nullptr)
135  do_X() ;
136  return *p_X ;
137 }
138 
140  if (p_T==nullptr)
141  do_T() ;
142  return *p_T ;
143 }
144 
145 // Computes the Cartesian coordinates
147  for (int i=0 ; i<2 ; i++)
148  assert (coloc[i] != nullptr) ;
149  for (int i=0 ; i<2 ; i++)
150  assert (absol[i] == nullptr) ;
151  for (int i=0 ; i<2 ; i++) {
152  absol[i] = new Val_domain(this) ;
153  absol[i]->allocate_conf() ;
154  }
155  Index index (nbr_points) ;
156 
157  do {
158  absol[0]->set(index) = (*coloc[0])(index(0)) ;
159  absol[1]->set(index) = (*coloc[1])(index(1)) ;
160  }
161  while (index.inc()) ;
162 }
163 
164 bool Domain_critic_inner::is_in (const Point& xx, double prec) const {
165 
166  assert (xx.get_ndim()==2) ;
167  bool res = true ;
168  if ((xx(1)<-prec) || (xx(1)>xlim+prec))
169  res = false ;
170  if ((xx(2)<-prec) || (xx(2)>M_PI+prec))
171  res = false ;
172  return res ;
173 }
174 
176 
177  Point res(2) ;
178  res.set(1) = so(1)/xlim ;
179  res.set(2) = so(2) ;
180 
181  return res ;
182 }
183 
184 // standard base
186  assert (type_base == CHEB_TYPE) ;
187 
188  base.allocate(nbr_coefs) ;
189  base.def =true ;
190  base.bases_1d[1]->set(0) = COSSIN_EVEN ;
191  for (int k=0 ; k<nbr_coefs(1) ; k++)
192  base.bases_1d[0]->set(k) = CHEB_EVEN ;
193 }
194 
195 // standard base
197  assert (type_base == CHEB_TYPE) ;
198 
199  base.allocate(nbr_coefs) ;
200  base.def =true ;
201  base.bases_1d[1]->set(0) = COSSIN_EVEN ;
202  for (int k=0 ; k<nbr_coefs(1) ; k++)
203  base.bases_1d[0]->set(k) = LEG_EVEN ;
204 }
205 
206 
207 // standard base
209 
210  assert (type_base == CHEB_TYPE) ;
211 
212  base.allocate(nbr_coefs) ;
213  base.def =true ;
214  base.bases_1d[1]->set(0) = COSSIN_EVEN ;
215  for (int k=0 ; k<nbr_coefs(1) ; k++)
216  base.bases_1d[0]->set(k) = CHEB_ODD ;
217 }
218 
219 // standard base
221  assert (type_base == LEG_TYPE) ;
222 
223  base.allocate(nbr_coefs) ;
224  base.def =true ;
225  base.bases_1d[1]->set(0) = COSSIN_EVEN ;
226  for (int k=0 ; k<nbr_coefs(1) ; k++)
227  base.bases_1d[0]->set(k) = LEG_ODD ;
228 }
229 
230 // standard base
232 
233  assert (type_base == CHEB_TYPE) ;
234 
235  base.allocate(nbr_coefs) ;
236  base.def =true ;
237  base.bases_1d[1]->set(0) = COSSIN_ODD ;
238  for (int k=0 ; k<nbr_coefs(1) ; k++)
239  base.bases_1d[0]->set(k) = CHEB_EVEN ;
240 }
241 
242 // standard base
244  assert (type_base == LEG_TYPE) ;
245 
246  base.allocate(nbr_coefs) ;
247  base.def =true ;
248  base.bases_1d[1]->set(0) = COSSIN_ODD ;
249  for (int k=0 ; k<nbr_coefs(1) ; k++)
250  base.bases_1d[0]->set(k) = LEG_EVEN ;
251 }
252 // standard base
254 
255  assert (type_base == CHEB_TYPE) ;
256 
257  base.allocate(nbr_coefs) ;
258  base.def =true ;
259  base.bases_1d[1]->set(0) = COSSIN_ODD ;
260  for (int k=0 ; k<nbr_coefs(1) ; k++)
261  base.bases_1d[0]->set(k) = CHEB_ODD ;
262 }
263 
264 // standard base
266  assert (type_base == LEG_TYPE) ;
267 
268  base.allocate(nbr_coefs) ;
269  base.def =true ;
270  base.bases_1d[1]->set(0) = COSSIN_ODD ;
271  for (int k=0 ; k<nbr_coefs(1) ; k++)
272  base.bases_1d[0]->set(k) = LEG_ODD ;
273 }
274 
275 // Rules for the multiplication of two basis.
277 
278  assert (a.ndim==2) ;
279  assert (b.ndim==2) ;
280 
281  Base_spectral res(2) ;
282  bool res_def = true ;
283 
284  if (!a.def)
285  res_def=false ;
286  if (!b.def)
287  res_def=false ;
288 
289  if (res_def) {
290 
291  // Base in phi :
292  res.bases_1d[1] = new Array<int> (a.bases_1d[1]->get_dimensions()) ;
293  switch ((*a.bases_1d[1])(0)) {
294  case COSSIN_EVEN:
295  switch ((*b.bases_1d[1])(0)) {
296  case COSSIN_EVEN:
297  res.bases_1d[1]->set(0) = COSSIN_EVEN ;
298  break ;
299  case COSSIN_ODD:
300  res.bases_1d[1]->set(0) = COSSIN_ODD ;
301  break ;
302  default:
303  res_def = false ;
304  break ;
305  }
306  break ;
307  case COSSIN_ODD:
308  switch ((*b.bases_1d[1])(0)) {
309  case COSSIN_EVEN:
310  res.bases_1d[1]->set(0) = COSSIN_ODD ;
311  break ;
312  case COSSIN_ODD:
313  res.bases_1d[1]->set(0) = COSSIN_EVEN ;
314  break ;
315  default:
316  res_def = false ;
317  break ;
318  }
319  break ;
320  default:
321  res_def = false ;
322  break ;
323  }
324 
325  res.bases_1d[0] = new Array<int> (a.bases_1d[0]->get_dimensions()) ;
326  for (int k=0 ; k<nbr_coefs(1) ; k++) {
327  switch ((*a.bases_1d[0])(k)) {
328  case CHEB_EVEN :
329  switch ((*b.bases_1d[0])(k)) {
330  case CHEB_EVEN :
331  res.bases_1d[0]->set(k) = CHEB_EVEN ;
332  break ;
333  case CHEB_ODD :
334  res.bases_1d[0]->set(k) = CHEB_ODD ;
335  break ;
336  default :
337  res_def = false ;
338  break ;
339  }
340  break ;
341  case LEG_EVEN :
342  switch ((*b.bases_1d[0])(k)) {
343  case LEG_EVEN :
344  res.bases_1d[0]->set(k) = LEG_EVEN ;
345  break ;
346  case LEG_ODD :
347  res.bases_1d[0]->set(k) = LEG_ODD ;
348  break ;
349  default :
350  res_def = false ;
351  break ;
352  }
353  break ;
354  case CHEB_ODD :
355  switch ((*b.bases_1d[0])(k)) {
356  case CHEB_EVEN :
357  res.bases_1d[0]->set(k) = CHEB_ODD ;
358  break ;
359  case CHEB_ODD :
360  res.bases_1d[0]->set(k) = CHEB_EVEN ;
361  break ;
362  default :
363  res_def = false ;
364  break ;
365  }
366  break ;
367  case LEG_ODD :
368  switch ((*b.bases_1d[0])(k)) {
369  case LEG_EVEN :
370  res.bases_1d[0]->set(k) = LEG_ODD ;
371  break ;
372  case LEG_ODD :
373  res.bases_1d[0]->set(k) = LEG_EVEN ;
374  break ;
375  default :
376  res_def = false ;
377  break ;
378  }
379  break ;
380 
381  default :
382  res_def = false ;
383  break ;
384  }
385  }
386  }
387 
388  if (!res_def)
389  for (int dim=0 ; dim<a.ndim ; dim++)
390  if (res.bases_1d[dim]!= nullptr) {
391  delete res.bases_1d[dim] ;
392  res.bases_1d[dim] = nullptr ;
393  }
394  res.def = res_def ;
395  return res ;
396 }
397 
399  int res = -1 ;
400  if (strcmp(p,"X ")==0)
401  res = 0 ;
402  if (strcmp(p,"T ")==0)
403  res = 1 ;
404  return res ;
405 }}
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 & set(int i)
Read/write of the size of a given dimension.
Definition: dim_array.hpp:54
void save(FILE *) const
Save function.
Definition: dim_array.cpp:32
Class for a 2-dimensional cylindrical type domain.
Definition: critic.hpp:45
virtual const Val_domain & get_T() const
Returns the variable .
virtual void set_legendre_todd_base(Base_spectral &) const
Gives the base using Legendre polynomials, for odd functions in (critic space case)
double xlim
Relates the numerical to the variable.
Definition: critic.hpp:50
void del_deriv() override
Destroys the derivated members (like coloc, cart and radius), when changing the type of colocation po...
virtual void set_cheb_xodd_base(Base_spectral &so) const
Gives the base using Chebyshev polynomials, for odd functions in (critic space case)
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 set_cheb_xodd_todd_base(Base_spectral &so) const
Gives the base using Chebyshev polynomials, for odd functions in and in (critic space case)
virtual void save(FILE *) const
Saving function.
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 const Val_domain & get_X() const
Returns the variable .
virtual void set_legendre_xodd_base(Base_spectral &) const
Gives the base using Legendre polynomials, for odd functions in (critic space case)
virtual int give_place_var(char *) const
Translates a name of a coordinate into its corresponding numerical name.
virtual ostream & print(ostream &o) const
Delegate function to virtualize the << operator.
virtual const Point absol_to_num(const Point &xxx) const
Computes the numerical coordinates from the physical ones.
Domain_critic_inner(int num, int ttype, const Dim_array &nbr, double xl)
Standard constructor :
virtual void set_cheb_base(Base_spectral &so) const
Gives the standard base for Chebyshev polynomials.
virtual void set_cheb_todd_base(Base_spectral &so) const
Gives the base using Chebyshev polynomials, for odd functions in (critic space case)
virtual void set_legendre_xodd_todd_base(Base_spectral &) const
Gives the base using Chebyshev polynomials, for odd functions in and in (critic space case)
virtual void do_absol() const
Computes the absolute coordinates.
Val_domain * p_X
Pointer on the variable.
Definition: critic.hpp:48
Val_domain * p_T
Pointer on the variable.
Definition: critic.hpp:49
Abstract class that implements the fonctionnalities common to all the type of domains.
Definition: space.hpp:60
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
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
double & set(const Index &pos)
Read/write the value of the field in the configuration space.
Definition: val_domain.cpp:171
void allocate_conf()
Allocates the values in the configuration space and destroys the values in the coefficients space.
Definition: val_domain.cpp:209