KADATH
domain_compact_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_xm1_1d (int, Array<double>&) ;
29 int mult_xm1_1d (int, Array<double>&) ;
30 
32  so.coef() ;
33  Val_domain res(this) ;
34 
35  res.base.allocate (nbr_coefs) ;
36  *res.base.bases_1d[2] = *so.base.bases_1d[2] ;
37 
38  Index index_t (res.base.bases_1d[1]->get_dimensions()) ;
39  // Inversion in theta :
40  do {
41  switch ((*so.base.bases_1d[1])(index_t)) {
42  case COS_EVEN :
43  res.base.bases_1d[1]->set(index_t) = SIN_ODD ;
44  break ;
45  case COS_ODD :
46  res.base.bases_1d[1]->set(index_t) = SIN_EVEN ;
47  break ;
48  case SIN_EVEN :
49  res.base.bases_1d[1]->set(index_t) = COS_ODD ;
50  break ;
51  case SIN_ODD :
52  res.base.bases_1d[1]->set(index_t) = COS_EVEN ;
53  break ;
54  default :
55  cout << "Unknown case in Domain_compact::mult_cos_phi" << endl ;
56  abort() ;
57  }
58  }
59  while (index_t.inc()) ;
60  *res.base.bases_1d[0] = *so.base.bases_1d[0] ;
61 
62  res.base.def = true ;
63 
64  res.cf = new Array<double> (so.base.ope_1d(mult_cos_1d, 2, *so.cf, res.base)) ;
65  res.in_coef = true ;
66  return res ;
67 }
68 
70  so.coef() ;
71  Val_domain res(this) ;
72 
73  res.base.allocate (nbr_coefs) ;
74  *res.base.bases_1d[2] = *so.base.bases_1d[2] ;
75 
76  Index index_t (res.base.bases_1d[1]->get_dimensions()) ;
77  // Inversion in theta :
78  do {
79  switch ((*so.base.bases_1d[1])(index_t)) {
80  case COS_EVEN :
81  res.base.bases_1d[1]->set(index_t) = SIN_ODD ;
82  break ;
83  case COS_ODD :
84  res.base.bases_1d[1]->set(index_t) = SIN_EVEN ;
85  break ;
86  case SIN_EVEN :
87  res.base.bases_1d[1]->set(index_t) = COS_ODD ;
88  break ;
89  case SIN_ODD :
90  res.base.bases_1d[1]->set(index_t) = COS_EVEN ;
91  break ;
92  default :
93  cout << "Unknown case in Domain_compact::mult_sin_phi" << endl ;
94  abort() ;
95  }
96  }
97  while (index_t.inc()) ;
98  *res.base.bases_1d[0] = *so.base.bases_1d[0] ;
99 
100  res.base.def = true ;
101 
102  res.cf = new Array<double> (so.base.ope_1d(mult_sin_1d, 2, *so.cf, res.base)) ;
103  res.in_coef = true ;
104  return res ;
105 }
106 
108  so.coef() ;
109  Val_domain res(this) ;
110 
111  res.base = so.base ;
112 
113  res.cf = new Array<double> (so.base.ope_1d(mult_cos_1d, 1, *so.cf, res.base)) ;
114  res.in_coef = true ;
115  return res ;
116 }
117 
119  so.coef() ;
120  Val_domain res(this) ;
121 
122  res.base= so.base ;
123 
124  res.cf = new Array<double> (so.base.ope_1d(mult_sin_1d, 1, *so.cf, res.base)) ;
125  res.in_coef = true ;
126  return res ;
127 }
128 
130  so.coef() ;
131  Val_domain res(this) ;
132 
133  res.base = so.base ;
134 
135  res.cf = new Array<double> (so.base.ope_1d(div_sin_1d, 1, *so.cf, res.base)) ;
136  res.in_coef = true ;
137  return res ;
138 }
139 
141  so.coef() ;
142  Val_domain res(this) ;
143 
144  res.base = so.base ;
145 
146  res.cf = new Array<double> (so.base.ope_1d(div_cos_1d, 1, *so.cf, res.base)) ;
147  res.in_coef = true ;
148  return res ;
149 }
150 
152  so.coef() ;
153  Val_domain res(this) ;
154 
155  res.base= so.base ;
156 
157  res.cf = new Array<double> (so.base.ope_1d(mult_xm1_1d, 0, *so.cf, res.base)) ;
158  res.in_coef = true ;
159  return res ;
160 }
161 
163  so.coef() ;
164  Val_domain res(this) ;
165 
166  res.base = so.base ;
167 
168  res.cf = new Array<double> (so.base.ope_1d(div_xm1_1d, 0, *so.cf, res.base)) ;
169  res.in_coef = true ;
170  return res ;
171 }
172 
174  so.coef() ;
175  Val_domain res(div_xm1(so)) ;
176  res /= alpha ;
177  return res ;
178 }
179 
181  so.coef() ;
182  Val_domain res(mult_xm1(so)) ;
183  res *= alpha ;
184  return res ;
185 }
186 
188  return (-alpha*so.der_var(1).mult_xm1().mult_xm1()) ;
189 }
190 
192  return (-so.der_var(1)/alpha) ;
193 }
194 
196  return (so.der_var(2)) ;
197 }
198 
199 
200 Val_domain Domain_compact::der_partial_var (const Val_domain& so, int which_var) const {
201 
202  switch (which_var) {
203  case 0 :
204  return so.der_r() ;
205  break ;
206  case 1 :
207  return so.der_var(2) ;
208  break ;
209  case 2 :
210  return so.der_var(3) ;
211  default:
212  cerr << "Unknown variable in Domain_compact::der_partial_var" << endl ;
213  abort() ;
214  }
215 }
216 
218  Val_domain derr (-alpha*so.der_var(1).mult_xm1().mult_xm1()) ;
219  Val_domain dderr (-alpha*derr.der_var(1).mult_xm1().mult_xm1()) ;
220  Val_domain dert (so.der_var(2)) ;
221  Val_domain res (dderr + div_r(derr + div_r(dert.der_var(2)))) ;
222  if (m!=0)
223  res -= m * m * div_r(div_r(so.div_sin_theta().div_sin_theta())) ;
224  return res ;
225 }
226 
227 double integral_1d (int, const Array<double>&) ;
228 double Domain_compact::integ_volume (const Val_domain& so) const {
229 
230  if (so.check_if_zero())
231  return 0 ;
232  else {
233  Val_domain integrant (-mult_r(mult_r(mult_r(mult_r(mult_sin_theta(so)))))*alpha) ;
234  integrant.coef() ;
235 
236  double val = 0 ;
237  // Only k = 0
238  int baset = (*integrant.get_base().bases_1d[1]) (0) ;
239  assert(baset==SIN_ODD) ;
240  Index pos (nbr_coefs) ;
241  for (int j=0 ; j<nbr_coefs(1) ; j++) {
242  pos.set(1) = j ;
243  int baser = (*integrant.get_base().bases_1d[0]) (j, 0) ;
244  assert (baser==CHEB) ;
245 
246  Array<double> cf (nbr_coefs(0)) ;
247  for (int i=0 ; i<nbr_coefs(0) ; i++) {
248  pos.set(0) = i ;
249  cf.set(i) = integrant.get_coef(pos) ;
250  }
251  val += 2./(2.*j+1) * integral_1d(CHEB, cf) ;
252  }
253 
254  return val * 2*M_PI ;
255 }
256 }
257 }
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_xm1(const Val_domain &) const
Division by .
virtual Val_domain mult_sin_phi(const Val_domain &) const
Multiplication by .
virtual Val_domain der_r_rtwo(const Val_domain &) const
Compute the radial derivative multiplied by of a scalar field.
virtual Val_domain mult_cos_theta(const Val_domain &) const
Multiplication by .
double alpha
Relates the numerical to the physical radii.
Definition: spheric.hpp:1010
virtual Val_domain div_cos_theta(const Val_domain &) const
Division by .
virtual Val_domain div_sin_theta(const Val_domain &) const
Division by .
virtual Val_domain mult_r(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_theta(const Val_domain &) const
Multiplication by .
virtual Val_domain der_partial_var(const Val_domain &, int) const
Partial derivative with respect to a coordinate.
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 double integ_volume(const Val_domain &so) const
Volume integral.
virtual Val_domain mult_xm1(const Val_domain &) const
Multiplication by .
virtual Val_domain div_r(const Val_domain &) const
Division by .
virtual Val_domain der_r(const Val_domain &) const
Compute the radial derivative of a scalar field.
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
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 .
Val_domain mult_xm1() const
Multiplication 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