KADATH
domain_shell_ope.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 "array.hpp"
21 #include "spheric.hpp"
22 #include "val_domain.hpp"
23 #include "array_math.hpp"
24 
25 namespace Kadath {
26 int mult_cos_1d (int, Array<double>&) ;
27 int mult_sin_1d (int, Array<double>&) ;
28 int div_sin_1d (int, Array<double>&) ;
29 int div_cos_1d (int, Array<double>&) ;
30 int mult_x_1d (int, Array<double>&) ;
31 int div_xp1_1d (int, Array<double>&) ;
32 int div_xm1_1d (int, Array<double>&) ;
33 int mult_xm1_1d (int, Array<double>&) ;
34 int div_1mx2_1d (int, Array<double>&) ;
35 
37  so.coef() ;
38  Val_domain res(this) ;
39 
40  res.base.allocate (nbr_coefs) ;
41  *res.base.bases_1d[2] = *so.base.bases_1d[2] ;
42 
43  Index index_t (res.base.bases_1d[1]->get_dimensions()) ;
44  // Inversion in theta :
45  do {
46  switch ((*so.base.bases_1d[1])(index_t)) {
47  case COS_EVEN :
48  res.base.bases_1d[1]->set(index_t) = SIN_ODD ;
49  break ;
50  case COS_ODD :
51  res.base.bases_1d[1]->set(index_t) = SIN_EVEN ;
52  break ;
53  case SIN_EVEN :
54  res.base.bases_1d[1]->set(index_t) = COS_ODD ;
55  break ;
56  case SIN_ODD :
57  res.base.bases_1d[1]->set(index_t) = COS_EVEN ;
58  break ;
59  default :
60  cout << "Unknown case in Domain_shell::mult_cos_phi" << endl ;
61  abort() ;
62  }
63  }
64  while (index_t.inc()) ;
65  *res.base.bases_1d[0] = *so.base.bases_1d[0] ;
66 
67  res.base.def = true ;
68 
69  res.cf = new Array<double> (so.base.ope_1d(mult_cos_1d, 2, *so.cf, res.base)) ;
70  res.in_coef = true ;
71  return res ;
72 }
73 
75  so.coef() ;
76  Val_domain res(this) ;
77 
78  res.base.allocate (nbr_coefs) ;
79  *res.base.bases_1d[2] = *so.base.bases_1d[2] ;
80 
81  Index index_t (res.base.bases_1d[1]->get_dimensions()) ;
82  // Inversion in theta :
83  do {
84  switch ((*so.base.bases_1d[1])(index_t)) {
85  case COS_EVEN :
86  res.base.bases_1d[1]->set(index_t) = SIN_ODD ;
87  break ;
88  case COS_ODD :
89  res.base.bases_1d[1]->set(index_t) = SIN_EVEN ;
90  break ;
91  case SIN_EVEN :
92  res.base.bases_1d[1]->set(index_t) = COS_ODD ;
93  break ;
94  case SIN_ODD :
95  res.base.bases_1d[1]->set(index_t) = COS_EVEN ;
96  break ;
97  default :
98  cout << "Unknown case in Domain_shell::mult_sin_phi" << endl ;
99  abort() ;
100  }
101  }
102  while (index_t.inc()) ;
103  *res.base.bases_1d[0] = *so.base.bases_1d[0] ;
104 
105  res.base.def = true ;
106 
107  res.cf = new Array<double> (so.base.ope_1d(mult_sin_1d, 2, *so.cf, res.base)) ;
108  res.in_coef = true ;
109  return res ;
110 }
111 
113  so.coef() ;
114  Val_domain res(this) ;
115 
116  res.base = so.base ;
117 
118  res.cf = new Array<double> (so.base.ope_1d(mult_cos_1d, 1, *so.cf, res.base)) ;
119  res.in_coef = true ;
120  return res ;
121 }
122 
124  so.coef() ;
125  Val_domain res(this) ;
126 
127  res.base= so.base ;
128 
129  res.cf = new Array<double> (so.base.ope_1d(mult_sin_1d, 1, *so.cf, res.base)) ;
130  res.in_coef = true ;
131  return res ;
132 }
133 
135  so.coef() ;
136  Val_domain res(this) ;
137 
138  res.base = so.base ;
139 
140  res.cf = new Array<double> (so.base.ope_1d(div_sin_1d, 1, *so.cf, res.base)) ;
141  res.in_coef = true ;
142  return res ;
143 }
144 
146  so.coef() ;
147  Val_domain res(this) ;
148 
149  res.base = so.base ;
150 
151  res.cf = new Array<double> (so.base.ope_1d(div_cos_1d, 1, *so.cf, res.base)) ;
152  res.in_coef = true ;
153  return res ;
154 }
155 
157  so.coef() ;
158  Val_domain res(this) ;
159 
160  res.base= so.base ;
161 
162  res.cf = new Array<double> (so.base.ope_1d(mult_x_1d, 0, *so.cf, res.base)*alpha + (*so.cf)*beta) ;
163  res.in_coef = true ;
164  return res ;
165 }
166 
168  if (so.check_if_zero())
169  return so;
170  Val_domain res(so*(1.-get_radius()/(alpha+beta))) ;
171 
172  res.base= so.base ;
173  return res ;
174 }
175 
177  if (so.check_if_zero())
178  return so;
179  so.coef() ;
180  Val_domain res(this) ;
181 
182  res.base= so.base ;
183 
184  res.cf = new Array<double> (-(alpha+beta)/alpha*so.base.ope_1d(div_xm1_1d, 0, *so.cf, res.base)) ;
185  res.in_coef = true ;
186  return res ;
187 }
188 
190  so.coef() ;
191  Val_domain res(this) ;
192 
193  res.base= so.base ;
194 
195  res.cf = new Array<double> (so.base.ope_1d(div_xp1_1d, 0, *so.cf, res.base)) ;
196  res.in_coef = true ;
197  return res ;
198 }
199 
201  so.coef() ;
202  Val_domain res(this) ;
203 
204  res.base= so.base ;
205 
206  res.cf = new Array<double> (so.base.ope_1d(div_1mx2_1d, 0, *so.cf, res.base)) ;
207  res.in_coef = true ;
208  return res ;
209 }
210 
211 
213  Val_domain res (so / get_radius()) ;
214  res.base = so.base ;
215  return (res) ;
216 }
217 
219  return (so.der_var(1)/alpha) ;
220 }
221 
223  return (so.der_var(3).der_var(3)) ;
224 }
225 
227  so.coef() ;
228  Val_domain res(this) ;
229 
230  res.base= so.base ;
231 
232  res.cf = new Array<double> (so.base.ope_1d(mult_xm1_1d, 0, *so.cf, res.base)) ;
233  res.in_coef = true ;
234  return res ;
235 }
236 
238  so.coef() ;
239  Val_domain res(this) ;
240 
241  res.base = so.base ;
242 
243  res.cf = new Array<double> (so.base.ope_1d(div_xm1_1d, 0, *so.cf, res.base)) ;
244  res.in_coef = true ;
245  return res ;
246 }
247 
249  return (so.der_var(2)) ;
250 }
251 
252 
253 Val_domain Domain_shell::der_partial_var (const Val_domain& so, int which_var) const {
254 
255  switch (which_var) {
256  case 0 :
257  return so.der_r() ;
258  break ;
259  case 1 :
260  return so.der_var(2) ;
261  break ;
262  case 2 :
263  return so.der_var(3) ;
264  default:
265  cerr << "Unknown variable in Domain_shell::der_partial_var" << endl ;
266  abort() ;
267  }
268 }
269 
270 
272  Val_domain derr (so.der_var(1)/alpha) ;
273  Val_domain dert (so.der_var(2)) ;
274  Val_domain res (derr.der_var(1)/alpha + div_r(derr + div_r(dert.der_var(2)))) ;
275  if (m!=0)
276  res -= m * m * div_r(div_r(so.div_sin_theta().div_sin_theta())) ;
277  return res ;
278 }
279 
280 double integral_1d (int, const Array<double>&) ;
281 double Domain_shell::integ_volume (const Val_domain& so) const {
282 
283  if (so.check_if_zero())
284  return 0 ;
285  else {
286 
287  Val_domain integrant (mult_r(mult_r(mult_sin_theta(so)))*alpha) ;
288  integrant.coef() ;
289 
290  double val = 0 ;
291  // Only k = 0
292  int baset = (*integrant.get_base().bases_1d[1]) (0) ;
293  assert(baset==SIN_ODD) ;
294  Index pos (nbr_coefs) ;
295  for (int j=0 ; j<nbr_coefs(1) ; j++) {
296  pos.set(1) = j ;
297  int baser = (*integrant.get_base().bases_1d[0]) (j, 0) ;
298  assert (baser==CHEB) ;
299 
300  Array<double> cf (nbr_coefs(0)) ;
301  for (int i=0 ; i<nbr_coefs(0) ; i++) {
302  pos.set(0) = i ;
303  cf.set(i) = integrant.get_coef(pos) ;
304  }
305  val += 2./(2.*j+1) * integral_1d(CHEB, cf) ;
306  }
307 
308  return val * 2*M_PI ;
309 }
310 }
311 }
reference set(const Index &pos)
Read/write of an element.
Definition: array.hpp:186
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.
Array< double > ope_1d(int(*function)(int, Array< double > &), int var, const Array< double > &so, Base_spectral &base) const
One-dimensional operator acting in the coefficient space.
Definition: ope_1d.cpp:26
virtual Val_domain div_xp1(const Val_domain &) const
Division by .
virtual Val_domain div_r(const Val_domain &) const
Division by .
virtual Val_domain mult_cos_theta(const Val_domain &) const
Multiplication by .
virtual Val_domain div_1mrsL(const Val_domain &) const
Division by .
virtual double integ_volume(const Val_domain &so) const
Volume integral.
double beta
Relates the numerical to the physical radii.
Definition: spheric.hpp:559
virtual Val_domain div_sin_theta(const Val_domain &) const
Division by .
virtual Val_domain ddp(const Val_domain &) const
Compute the second derivative with respect to of a scalar field.
virtual Val_domain der_partial_var(const Val_domain &, int) const
Partial derivative with respect to a coordinate.
virtual Val_domain der_r(const Val_domain &) const
Compute the radial derivative of a scalar field.
double alpha
Relates the numerical to the physical radii.
Definition: spheric.hpp:558
virtual Val_domain div_cos_theta(const Val_domain &) const
Division by .
virtual Val_domain div_xm1(const Val_domain &) const
Division by .
virtual Val_domain mult_cos_phi(const Val_domain &) const
Multiplication by .
virtual Val_domain dt(const Val_domain &) const
Compute the derivative with respect to of a scalar field.
virtual Val_domain mult_sin_phi(const Val_domain &) const
Multiplication by .
virtual Val_domain laplacian2(const Val_domain &, int) const
Computes the ordinary flat 2dè- Laplacian for a scalar field with an harmonic index m.
virtual Val_domain mult_r(const Val_domain &) const
Multiplication by .
virtual Val_domain mult_1mrsL(const Val_domain &) const
Multiplication by .
virtual Val_domain div_1mx2(const Val_domain &) const
Division by .
virtual Val_domain mult_sin_theta(const Val_domain &) const
Multiplication by .
virtual Val_domain mult_xm1(const Val_domain &) const
Multiplication by .
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
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
Class for storing the basis of decompositions of a field and its values on both the configuration and...
Definition: val_domain.hpp:69
Base_spectral base
Spectral basis of the field.
Definition: val_domain.hpp:72
bool check_if_zero() const
Check whether the logical state is zero or not.
Definition: val_domain.hpp:142
Val_domain der_r() const
Definition: val_domain.cpp:726
Array< double > * cf
Pointer on the Array of the values in the coefficients space.
Definition: val_domain.hpp:77
Val_domain div_sin_theta() const
Division by .
bool in_coef
Is the field known in the coefficient space ?
Definition: val_domain.hpp:79
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
Array< double > get_coef() const
Definition: val_domain.hpp:136
const Base_spectral & get_base() const
Returns the basis of decomposition.
Definition: val_domain.hpp:122