KADATH
fitwaves.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 "spheric_periodic.hpp"
22 #include "term_eq.hpp"
23 #include "scalar.hpp"
24 #include "tensor_impl.hpp"
25 #include "tensor.hpp"
26 #include "array_math.hpp"
27 namespace Kadath {
28 void coef_1d (int, Array<double>&) ;
29 
30 double Domain_spheric_periodic_shell::give_harmonique (const Val_domain& so, int nn, double phase, int dim, double factor) const {
31  so.coef() ;
32  Index pos (nbr_coefs) ;
33  pos.set(1) = nn ;
34  int expo = 0;
35  switch ((*so.base.bases_1d[1])(0)) {
36  case COS :
37  expo = nn ;
38  break ;
39  case COS_EVEN :
40  expo = 2*nn ;
41  break ;
42  case COS_ODD :
43  expo = 2*nn+1 ;
44  break ;
45  default :
46  cerr << "Unknown case in Domain_spheric_periodic_shell::fitwaves" << endl ;
47  break ;
48  }
49 
50 
51 
52  // Get the value at rmax of this harmonic
53  double AA = val_boundary (OUTER_BC, so, pos) ;
54  double lambda2 = factor - expo*expo*ome*ome ;
55  double res ;
56  double rmax = alpha + beta ;
57 
58  if (lambda2>0)
59  res = AA/exp(-sqrt(lambda2)*rmax)*pow(rmax, double(dim-1)/2.) ;
60  else
61  res = AA/sin(sqrt(-lambda2)*rmax+phase)* pow(rmax, double(dim-1)/2.) ;
62  return res ;
63 }
64 
65 // Val_domain version
66 Val_domain Domain_spheric_periodic_shell::fitwaves (const Val_domain& so, const Array<double>& phases, int dim, double factor) const {
67 
68  so.coef() ;
69 
70  Val_domain dso (der_normal(so, OUTER_BC)) ;
71 
72  Val_domain res(this) ;
73  res.base = so.base ;
74  res.allocate_coef() ;
75 
76  double rmax = alpha + beta ;
77 
78  Index pos (nbr_coefs) ;
79 
80  int max = 0;
81  switch ((*so.base.bases_1d[1])(0)) {
82  case COS :
83  max = nbr_coefs(1) ;
84  break ;
85  case COS_EVEN :
86  max = nbr_coefs(1) ;
87  break ;
88  case COS_ODD :
89  max = nbr_coefs(1)-1 ;
90  break ;
91  default :
92  cerr << "Unknown case in Domain_spheric_periodic_shell::fitwaves" << endl ;
93  break ;
94  }
95 
96  // Loop on harmonic
97  for (int nn=0 ; nn<max ; nn++) {
98 
99  pos.set(1) = nn ;
100 
101  // Correspond to what ?
102  int expo = 0;
103  switch ((*so.base.bases_1d[1])(0)) {
104  case COS :
105  expo = nn ;
106  break ;
107  case COS_EVEN :
108  expo = 2*nn ;
109  break ;
110  case COS_ODD :
111  expo = 2*nn+1 ;
112  break ;
113  default :
114  cerr << "Unknown case in Domain_spheric_periodic_shell::fitwaves" << endl ;
115  break ;
116  }
117 
118  double lambda2 = factor - expo*expo*ome*ome ;
119  // Various cases :
120  double sh = (lambda2>0) ? exp(-sqrt(lambda2)*rmax)/pow(rmax, double(dim-1)/2.) :
121  sin(sqrt(-lambda2)*rmax+phases(nn))/ pow(rmax, double(dim-1)/2.) ;
122 
123  double dsh = (lambda2>0) ? exp(-sqrt(lambda2)*rmax)/pow(rmax, double(dim-1)/2.)*(-sqrt(lambda2)-double(dim-1)/2./rmax) :
124  sqrt(-lambda2)*cos(sqrt(-lambda2)*rmax+phases(nn))/ pow(rmax, double(dim-1)/2.) - double(dim-1)/2.*sin(sqrt(-lambda2)*rmax+phases(nn))/ pow(rmax, double(dim+1)/2.) ;
125 
126  // Affecte to res
127  for (int i=0 ; i<nbr_coefs(0) ; i++) {
128  pos.set(0) = i ;
129  res.set_coef(pos) = rmax*rmax*(so.get_coef(pos)*dsh - dso.get_coef(pos)*sh) ;
130  }
131 
132  }
133  return res ;
134 }
135 
136 // Term_eq version
137 Term_eq Domain_spheric_periodic_shell::fitwaves (const Term_eq& so, const Array<double>& phases, int dim, double factor) const {
138 
139  // Check it is a tensor
140  if (so.get_type_data() != TERM_T) {
141  cerr << "fitwaves only defined with respect for a tensor" << endl ;
142  abort() ;
143  }
144 
145  // Right domain ?
146  int dom = so.get_dom() ;
147  if (this != so.get_val_t().get_space().get_domain(dom)) {
148  cerr << "Domain mismatch in Domain_spheric_periodic_shell::fitwaves (Term_eq version)" << endl ;
149  abort() ;
150  }
151 
152  Tensor resval (so.get_val_t(), false) ;
153  for (int i=0 ; i<so.get_val_t().get_n_comp() ; i++) {
154  Array<int> ind (so.get_val_t().indices(i)) ;
155  Val_domain value (so.get_val_t()(ind)(dom)) ;
156  if (value.check_if_zero())
157  resval.set(ind).set_domain(dom).set_zero() ;
158  else {
159  resval.set(ind).set_domain(dom) = fitwaves(value, phases, dim, factor) ;
160  }
161  }
162 
163  if (so.get_p_der_t() !=0x0) {
164  Tensor resder (so.get_val_t(), false) ;
165  for (int i=0 ; i<so.get_der_t().get_n_comp() ; i++) {
166  Array<int> ind (so.get_der_t().indices(i)) ;
167  Val_domain valder (so.get_der_t()(ind)(dom)) ;
168  if (valder.check_if_zero())
169  resder.set(ind).set_domain(dom).set_zero() ;
170  else {
171  resder.set(ind).set_domain(dom) = fitwaves(valder, phases, dim, factor) ;
172  }
173  }
174  return Term_eq (dom, resval, resder) ;
175  }
176  else return Term_eq (dom, resval) ;
177 }
178 
179  }
Bases_container bases_1d
Arrays containing the various basis of decomposition.
double alpha
Relates the numerical to the physical radii.
Val_domain fitwaves(const Val_domain &so, const Array< double > &phases, int dim, double fact) const
Fit some field with homogenous solutions of the wave equation (Val_domain version).
Definition: fitwaves.cpp:66
double ome
Relates the numerical time to the physical one.
double give_harmonique(const Val_domain &so, int nn, double phase, int dim, double fact) const
Computes the coefficient of a given outgoing wave harmonique inside some field, at the outer boundary...
Definition: fitwaves.cpp:30
double beta
Relates the numerical to the physical radii.
virtual double val_boundary(int, const Val_domain &, const Index &) const
Computes the value of a field at a boundary.
virtual Val_domain der_normal(const Val_domain &, int) const
Normal derivative with respect to a given surface.
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
Val_domain & set_domain(int)
Read/write of a particular Val_domain.
Definition: scalar.hpp:555
const Domain * get_domain(int i) const
returns a pointer on the domain.
Definition: space.hpp:1385
Tensor handling.
Definition: tensor.hpp:149
Scalar & set(const Array< int > &ind)
Returns the value of a component (read/write version).
Definition: tensor_impl.hpp:91
virtual Array< int > indices(int pos) const
Gives the values of the indices corresponding to a location in the array used for storage of the comp...
Definition: tensor.hpp:484
const Space & get_space() const
Returns the Space.
Definition: tensor.hpp:499
This class is intended to describe the manage objects appearing in the equations.
Definition: term_eq.hpp:62
int get_dom() const
Definition: term_eq.hpp:135
int get_type_data() const
Definition: term_eq.hpp:131
const Tensor * get_p_der_t() const
Definition: term_eq.hpp:127
Tensor const & get_val_t() const
Definition: term_eq.hpp:355
Tensor const & get_der_t() const
Definition: term_eq.hpp:369
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
double & set_coef(const Index &pos)
Read/write the value of the field in the coefficient space.
Definition: val_domain.cpp:177
void set_zero()
Sets the Val_domain to zero (logical state to zero and arrays destroyed).
Definition: val_domain.cpp:223
void allocate_coef()
Allocates the values in the coefficient space and destroys the values in the configuration space.
Definition: val_domain.cpp:216
bool check_if_zero() const
Check whether the logical state is zero or not.
Definition: val_domain.hpp:142
void coef() const
Computes the coefficients.
Definition: val_domain.cpp:622
Array< double > get_coef() const
Definition: val_domain.hpp:136