KADATH
domain_nucleus_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 "spheric.hpp"
21 #include "val_domain.hpp"
22 #include "array_math.hpp"
23 namespace Kadath {
24 int mult_cos_1d (int, Array<double>&) ;
25 int mult_sin_1d (int, Array<double>&) ;
26 int div_sin_1d (int, Array<double>&) ;
27 int div_cos_1d (int, Array<double>&) ;
28 int div_x_1d (int, Array<double>&) ;
29 int mult_x_1d (int, Array<double>&) ;
30 int div_1mx2_1d (int, Array<double>&) ;
31 
33  so.coef() ;
34  Val_domain res(this) ;
35 
36  res.base.allocate (nbr_coefs) ;
37  *res.base.bases_1d[2] = *so.base.bases_1d[2] ;
38 
39  Index index_t (res.base.bases_1d[1]->get_dimensions()) ;
40  // Inversion in theta :
41  do {
42  switch ((*so.base.bases_1d[1])(index_t)) {
43  case COS_EVEN :
44  res.base.bases_1d[1]->set(index_t) = SIN_ODD ;
45  break ;
46  case COS_ODD :
47  res.base.bases_1d[1]->set(index_t) = SIN_EVEN ;
48  break ;
49  case SIN_EVEN :
50  res.base.bases_1d[1]->set(index_t) = COS_ODD ;
51  break ;
52  case SIN_ODD :
53  res.base.bases_1d[1]->set(index_t) = COS_EVEN ;
54  break ;
55  default :
56  cout << "Unknown case in Domain_nucleus::mult_cos_phi" << endl ;
57  abort() ;
58  }
59  }
60  while (index_t.inc()) ;
61 
62  Index index_r (res.base.bases_1d[0]->get_dimensions()) ;
63  // Inversion in r :
64  do {
65  switch ((*so.base.bases_1d[0])(index_r)) {
66  case CHEB_EVEN :
67  res.base.bases_1d[0]->set(index_r) = CHEB_ODD ;
68  break ;
69  case CHEB_ODD :
70  res.base.bases_1d[0]->set(index_r) = CHEB_EVEN ;
71  break ;
72  case LEG_EVEN :
73  res.base.bases_1d[0]->set(index_r) = LEG_ODD ;
74  break ;
75  case LEG_ODD :
76  res.base.bases_1d[0]->set(index_r) = LEG_EVEN ;
77  break ;
78  default :
79  cout << "Unknown case in Domain_nucleus::mult_cos_phi" << endl ;
80  abort() ;
81  }
82  }
83  while (index_r.inc()) ;
84  res.base.def = true ;
85 
86  res.cf = new Array<double> (so.base.ope_1d(mult_cos_1d, 2, *so.cf, res.base)) ;
87  res.in_coef = true ;
88  return res ;
89 }
90 
92  so.coef() ;
93  Val_domain res(this) ;
94 
95  res.base.allocate (nbr_coefs) ;
96  *res.base.bases_1d[2] = *so.base.bases_1d[2] ;
97 
98  Index index_t (res.base.bases_1d[1]->get_dimensions()) ;
99  // Inversion in theta :
100  do {
101  switch ((*so.base.bases_1d[1])(index_t)) {
102  case COS_EVEN :
103  res.base.bases_1d[1]->set(index_t) = SIN_ODD ;
104  break ;
105  case COS_ODD :
106  res.base.bases_1d[1]->set(index_t) = SIN_EVEN ;
107  break ;
108  case SIN_EVEN :
109  res.base.bases_1d[1]->set(index_t) = COS_ODD ;
110  break ;
111  case SIN_ODD :
112  res.base.bases_1d[1]->set(index_t) = COS_EVEN ;
113  break ;
114  default :
115  cout << "Unknown case in Domain_nucleus::mult_sin_phi" << endl ;
116  abort() ;
117  }
118  }
119  while (index_t.inc()) ;
120 
121  Index index_r (res.base.bases_1d[0]->get_dimensions()) ;
122  // Inversion in r :
123  do {
124  switch ((*so.base.bases_1d[0])(index_r)) {
125  case CHEB_EVEN :
126  res.base.bases_1d[0]->set(index_r) = CHEB_ODD ;
127  break ;
128  case CHEB_ODD :
129  res.base.bases_1d[0]->set(index_r) = CHEB_EVEN ;
130  break ;
131  case LEG_EVEN :
132  res.base.bases_1d[0]->set(index_r) = LEG_ODD ;
133  break ;
134  case LEG_ODD :
135  res.base.bases_1d[0]->set(index_r) = LEG_EVEN ;
136  break ;
137  default :
138  cout << "Unknown case in Domain_nucleus::mult_sin_phi" << endl ;
139  abort() ;
140  }
141  }
142  while (index_r.inc()) ;
143  res.base.def = true ;
144 
145  res.cf = new Array<double> (so.base.ope_1d(mult_sin_1d, 2, *so.cf, res.base)) ;
146  res.in_coef = true ;
147  return res ;
148 }
149 
151  so.coef() ;
152  Val_domain res(this) ;
153  res.base = so.base ;
154  res.cf = new Array<double> (so.base.ope_1d(mult_cos_1d, 1, *so.cf, res.base)) ;
155  res.in_coef = true ;
156  return res ;
157 }
158 
160 
161  so.coef() ;
162  Val_domain res(this) ;
163 
164  res.base= so.base ;
165  res.cf = new Array<double> (so.base.ope_1d(mult_sin_1d, 1, *so.cf, res.base)) ;
166  res.in_coef = true ;
167  return res ;
168 }
169 
171  so.coef() ;
172  Val_domain res(this) ;
173 
174  res.base = so.base ;
175 
176  res.cf = new Array<double> (so.base.ope_1d(div_sin_1d, 1, *so.cf, res.base)) ;
177  res.in_coef = true ;
178  return res ;
179 }
180 
182  so.coef() ;
183  Val_domain res(this) ;
184 
185  res.base = so.base ;
186 
187  res.cf = new Array<double> (so.base.ope_1d(div_cos_1d, 1, *so.cf, res.base)) ;
188  res.in_coef = true ;
189  return res ;
190 }
191 
193  so.coef() ;
194  Val_domain res(this) ;
195 
196  res.base= so.base ;
197 
198  res.cf = new Array<double> (so.base.ope_1d(div_x_1d, 0, *so.cf, res.base)) ;
199  res.in_coef = true ;
200  return res ;
201 }
202 
204  so.coef() ;
205  Val_domain res(this) ;
206 
207  res.base= so.base ;
208 
209  res.cf = new Array<double> (so.base.ope_1d(div_1mx2_1d, 0, *so.cf, res.base)) ;
210  res.in_coef = true ;
211  return res ;
212 }
213 
215  so.coef() ;
216  Val_domain res(this) ;
217 
218  res.base= so.base ;
219 
220  res.cf = new Array<double> (so.base.ope_1d(mult_x_1d, 0, *so.cf, res.base)) ;
221  *res.cf *= alpha ;
222  res.in_coef = true ;
223  return res ;
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(div_x_1d, 0, *so.cf, res.base)) ;
233  *res.cf /= alpha ;
234  res.in_coef = true ;
235  return res ;
236 }
237 
239  return (so.der_var(1)/alpha) ;
240 }
241 
243  return (so.der_var(3).der_var(3)) ;
244 }
245 
247  return (div_x(so.der_var(1)) / alpha / alpha) ;
248 }
249 
251  Val_domain derr (so.der_var(1)/alpha) ;
252  Val_domain dert (so.der_var(2)) ;
253  Val_domain res (derr.der_var(1)/alpha + div_r(derr + div_r(dert.der_var(2)))) ;
254  if (m!=0)
255  res -= m * m * div_r(div_r(so.div_sin_theta().div_sin_theta())) ;
256  return res ;
257 }
258 
259 double integral_1d (int, const Array<double>&) ;
260 double Domain_nucleus::integ_volume (const Val_domain& so) const {
261 
262  if (so.check_if_zero())
263  return 0 ;
264  else {
265 
266  Val_domain integrant (mult_r(mult_r(mult_sin_theta(so)))*alpha) ;
267  integrant.coef() ;
268 
269  double val = 0 ;
270  // Only k = 0
271  int baset = (*integrant.get_base().bases_1d[1]) (0) ;
272  assert(baset==SIN_ODD) ;
273  Index pos (nbr_coefs) ;
274  for (int j=0 ; j<nbr_coefs(1) ; j++) {
275  pos.set(1) = j ;
276  int baser = (*integrant.get_base().bases_1d[0]) (j, 0) ;
277  assert (baser==CHEB_EVEN) ;
278 
279  Array<double> cf (nbr_coefs(0)) ;
280  for (int i=0 ; i<nbr_coefs(0) ; i++) {
281  pos.set(0) = i ;
282  cf.set(i) = integrant.get_coef(pos) ;
283  }
284  val += 2./(2.*j+1) * integral_1d(CHEB_EVEN, cf) ;
285  }
286 
287  return val * 2*M_PI ;
288 }
289 }
290 }
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_x(const Val_domain &) const
Division by .
virtual Val_domain der_r(const Val_domain &) const
Compute the radial derivative of a scalar field.
virtual Val_domain div_r(const Val_domain &) const
Division by .
virtual Val_domain srdr(const Val_domain &) const
Compute the of a scalar field .
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 mult_sin_theta(const Val_domain &) const
Multiplication by .
virtual Val_domain mult_cos_theta(const Val_domain &) const
Multiplication by .
virtual double integ_volume(const Val_domain &so) const
Volume integral.
virtual Val_domain div_cos_theta(const Val_domain &) const
Division by .
virtual Val_domain mult_sin_phi(const Val_domain &) const
Multiplication by .
virtual Val_domain mult_r(const Val_domain &) const
Multiplication by .
double alpha
Relates the numerical to the physical radii.
Definition: spheric.hpp:69
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_cos_phi(const Val_domain &) const
Multiplication by .
virtual Val_domain div_1mx2(const Val_domain &) const
Division by .
Dim_array nbr_coefs
Number of coefficients.
Definition: space.hpp:66
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
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