KADATH
domain_shell_inner_adapted_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 "adapted.hpp"
22 #include "array_math.hpp"
23 #include "scalar.hpp"
24 #include "tensor_impl.hpp"
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 
33  if (so.check_if_zero())
34  return so ;
35  else {
36  so.coef() ;
37  Val_domain res(this) ;
38 
39  res.base.allocate (nbr_coefs) ;
40  *res.base.bases_1d[2] = *so.base.bases_1d[2] ;
41 
42  Array_iterator index_t (res.base.bases_1d[1]->get_dimensions()) ;
43  // Inversion in theta :
44  do {
45  switch ((*so.base.bases_1d[1])(index_t)) {
46  case COS_EVEN :
47  res.base.bases_1d[1]->set(index_t) = SIN_ODD ;
48  break ;
49  case COS_ODD :
50  res.base.bases_1d[1]->set(index_t) = SIN_EVEN ;
51  break ;
52  case SIN_EVEN :
53  res.base.bases_1d[1]->set(index_t) = COS_ODD ;
54  break ;
55  case SIN_ODD :
56  res.base.bases_1d[1]->set(index_t) = COS_EVEN ;
57  break ;
58  default :
59  cout << "Unknown case in Domain_shell_inner_adapted::mult_cos_phi" << endl ;
60  abort() ;
61  }
62  }
63  while (index_t.inc()) ;
64  *res.base.bases_1d[0] = *so.base.bases_1d[0] ;
65 
66  res.base.def = true ;
67 
68  res.cf = new Array<double> (so.base.ope_1d(mult_cos_1d, 2, *so.cf, res.base)) ;
69  res.in_coef = true ;
70  return res ; }
71 }
72 
74  if (so.check_if_zero())
75  return so ;
76  else {so.coef() ;
77  Val_domain res(this) ;
78 
79  res.base.allocate (nbr_coefs) ;
80  *res.base.bases_1d[2] = *so.base.bases_1d[2] ;
81 
82  Index index_t (res.base.bases_1d[1]->get_dimensions()) ;
83  // Inversion in theta :
84  do {
85  switch ((*so.base.bases_1d[1])(index_t)) {
86  case COS_EVEN :
87  res.base.bases_1d[1]->set(index_t) = SIN_ODD ;
88  break ;
89  case COS_ODD :
90  res.base.bases_1d[1]->set(index_t) = SIN_EVEN ;
91  break ;
92  case SIN_EVEN :
93  res.base.bases_1d[1]->set(index_t) = COS_ODD ;
94  break ;
95  case SIN_ODD :
96  res.base.bases_1d[1]->set(index_t) = COS_EVEN ;
97  break ;
98  default :
99  cout << "Unknown case in Domain_shell_inner_adapted::mult_sin_phi" << endl ;
100  abort() ;
101  }
102  }
103  while (index_t.inc()) ;
104  *res.base.bases_1d[0] = *so.base.bases_1d[0] ;
105 
106  res.base.def = true ;
107 
108  res.cf = new Array<double> (so.base.ope_1d(mult_sin_1d, 2, *so.cf, res.base)) ;
109  res.in_coef = true ;
110  return res ;}
111 }
112 
114  if (so.check_if_zero())
115  return so ;
116  else {so.coef() ;
117  Val_domain res(this) ;
118 
119  res.base = so.base ;
120 
121  res.cf = new Array<double> (so.base.ope_1d(mult_cos_1d, 1, *so.cf, res.base)) ;
122  res.in_coef = true ;
123  return res ;}
124 }
125 
127  if (so.check_if_zero())
128  return so ;
129  else {so.coef() ;
130  Val_domain res(this) ;
131 
132  res.base= so.base ;
133 
134  res.cf = new Array<double> (so.base.ope_1d(mult_sin_1d, 1, *so.cf, res.base)) ;
135  res.in_coef = true ;
136  return res ;}
137 }
138 
140  if (so.check_if_zero())
141  return so ;
142  else {so.coef() ;
143  Val_domain res(this) ;
144 
145  res.base = so.base ;
146 
147  res.cf = new Array<double> (so.base.ope_1d(div_sin_1d, 1, *so.cf, res.base)) ;
148  res.in_coef = true ;
149  return res ;}
150 }
151 
153  if (so.check_if_zero())
154  return so ;
155  else {so.coef() ;
156  Val_domain res(this) ;
157 
158  res.base = so.base ;
159 
160  res.cf = new Array<double> (so.base.ope_1d(div_cos_1d, 1, *so.cf, res.base)) ;
161  res.in_coef = true ;
162  return res ;}
163 }
164 
165 
167  if (so.check_if_zero())
168  return so ;
169  else {
170  return (so.der_var(3).der_var(3)) ;}
171 }
172 
173 
175  if (so.check_if_zero())
176  return so ;
177  else {
178 
179  return (so.der_var(1) * 2. / (outer_radius - *inner_radius)) ;
180 
181  }
182 }
183 
185  if (so.check_if_zero())
186  return so ;
187  else {
188 
189  return (so/ get_radius()) ;
190 
191  }
192 }
193 
195  Val_domain derr (so.der_r()) ;
196  Val_domain dert (so.der_var(2)) ;
197  Val_domain res (derr.der_r() + div_r(2*derr + div_r(dert.der_var(2) + dert.mult_cos_theta().div_sin_theta()))) ;
198  if (m!=0)
199  res -= m * m * div_r(div_r(so.div_sin_theta().div_sin_theta())) ;
200  return res ;
201 }
202 
204  Val_domain derr (so.der_r()) ;
205  Val_domain dert (so.der_var(2)) ;
206  Val_domain res (derr.der_r() + div_r(derr + div_r(dert.der_var(2)))) ;
207  if (m!=0)
208  res -= m * m * div_r(div_r(so.div_sin_theta().div_sin_theta())) ;
209  return res ;
210 }
211 
212 double integral_1d (int, const Array<double>&) ;
214 
215  if (so.check_if_zero())
216  return 0 ;
217  else {
218  Val_domain r2 (get_radius()*get_radius()) ;
219  r2.std_base() ;
220  Val_domain integrant (r2*mult_sin_theta(so)*(*der_rad_term_eq->val_t)()(num_dom)) ;
221  integrant.coef() ;
222 
223  double val = 0 ;
224  // Only k = 0
225  int baset = (*integrant.get_base().bases_1d[1]) (0) ;
226  assert(baset==SIN_ODD) ;
227  Index pos (nbr_coefs) ;
228  for (int j=0 ; j<nbr_coefs(1) ; j++) {
229  pos.set(1) = j ;
230  int baser = (*integrant.get_base().bases_1d[0]) (j, 0) ;
231  assert (baser==CHEB) ;
232 
233  Array<double> cf (nbr_coefs(0)) ;
234  for (int i=0 ; i<nbr_coefs(0) ; i++) {
235  pos.set(0) = i ;
236  cf.set(i) = integrant.get_coef(pos) ;
237  }
238  val += 2./(2.*j+1) * integral_1d(CHEB, cf) ;
239  }
240 
241  return val * 2*M_PI ;
242 }
243 }
244 }
Version of the Index class optimized for incremental access to Array components.
bool inc(int increm, int var=0)
Increments the position of the Array_iterator.
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_sin_theta(const Val_domain &) const
Division by .
Term_eq * der_rad_term_eq
Pointer on the Term_eq containing the .
Definition: adapted.hpp:76
virtual Val_domain div_cos_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.
double outer_radius
The outer radius .
Definition: adapted.hpp:60
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 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.
Val_domain * inner_radius
Pointer on the inner boundary , as a Val_domain.
Definition: adapted.hpp:58
virtual Val_domain mult_sin_theta(const Val_domain &) const
Multiplication by .
virtual Val_domain laplacian(const Val_domain &, int) const
Computes the ordinary flat 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 &) const
Volume integral.
virtual Val_domain mult_sin_phi(const Val_domain &) const
Multiplication by .
virtual Val_domain mult_cos_theta(const Val_domain &) const
Multiplication by .
int num_dom
Number of the current domain (used by the Space)
Definition: space.hpp:63
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
Tensor * val_t
Pointer on the value, if the Term_eq is a Tensor.
Definition: term_eq.hpp:68
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
void std_base()
Sets the standard basis of decomposition.
Definition: val_domain.cpp:246
Val_domain div_sin_theta() const
Division by .
Val_domain mult_cos_theta() 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