KADATH
fitwaves_nonflat.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_nonflat (const Val_domain& so, double masse, 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 cor = 2*expo*expo*ome*ome - 1 ;
56  double res ;
57  double rmax = alpha + beta ;
58 
59  if (lambda2>0)
60  res = AA/exp(-sqrt(lambda2)*rmax)*pow(rmax, double(dim-1)/2.) ;
61  else
62  res = AA/cos(sqrt(-lambda2)*rmax+masse/sqrt(-lambda2)*cor*log(rmax)+phase)* pow(rmax, double(dim-1)/2.) ;
63  return res ;
64 }
65 
66 // Term_eq version
67 Term_eq Domain_spheric_periodic_shell::fitwaves_nonflat (const Term_eq& so, const Term_eq& field, const Array<double>& phases, int dim, double factor) const {
68 
69 
70  // Verifications
71  if ((field.get_type_data()!=TERM_T) || (so.get_type_data()!=TERM_T)) {
72  cerr << "Domain_spheric_periodic_shell::fitwaves_nonflat only defined with respect to tensors" << endl ;
73  abort() ;
74  }
75 
76  if ((field.get_val_t().get_valence()!=0) || (so.get_val_t().get_valence()!=0)) {
77  cerr << "Domain_spheric_periodic_shell::fitwaves_nonflat only defined with respect to scalars" << endl ;
78  abort() ;
79  }
80 
81  bool doder = ((so.get_p_der_t()==0x0) || (field.get_p_der_t()==0x0)) ? false : true ;
82 
83  int dom = so.get_dom() ;
84 
85  Index ppp(nbr_coefs) ;
86  double masse_val = val_boundary (OUTER_BC, mult_r(field.get_val_t()()(dom)-1)/2., ppp) ;
87  double masse_der = (doder) ? val_boundary (OUTER_BC, mult_r(field.get_der_t()()(dom)-1)/2., ppp) : 0 ;
88 
89  double rmax = alpha + beta ;
90 
91  int max = 0;
92  int baset = (*so.get_val_t()()(dom).get_base().bases_1d[1])(0) ;
93  switch (baset) {
94  case COS :
95  max = nbr_coefs(1) ;
96  break ;
97  case COS_EVEN :
98  max = nbr_coefs(1) ;
99  break ;
100  case COS_ODD :
101  max = nbr_coefs(1)-1 ;
102  break ;
103  default :
104  cerr << "Unknown case in Domain_spheric_periodic_shell::fitwaves" << endl ;
105  break ;
106  }
107 
108  Index pos (nbr_coefs) ;
109 
110  Val_domain resval (this) ;
111  resval.allocate_coef() ;
112  Val_domain resder (this) ;
113  resder.allocate_coef() ;
114  do {
115  resval.set_coef(pos) = 0 ;
116  resder.set_coef(pos) = 0 ;
117  }
118  while (pos.inc()) ;
119  pos.set_start() ;
120 
121  for (int nn=0 ; nn<max ; nn++) {
122 
123  pos.set(1) = nn ;
124 
125  // Correspond to what ?
126  int expo = 0;
127  switch (baset) {
128  case COS :
129  expo = nn ;
130  break ;
131  case COS_EVEN :
132  expo = 2*nn ;
133  break ;
134  case COS_ODD :
135  expo = 2*nn+1 ;
136  break ;
137  default :
138  cerr << "Unknown case in Domain_spheric_periodic_shell::fitwaves" << endl ;
139  break ;
140  }
141  double lambda2 = factor - expo*expo*ome*ome ;
142  double cor = 2*expo*expo*ome*ome - 1 ;
143 
144  Term_eq* sh ;
145  Term_eq* dsh ;
146  double la = sqrt(fabs(lambda2)) ;
147  double arg = (lambda2>0) ? la*rmax : la*rmax+masse_val*cor*log(rmax)/la+phases(nn) ;
148  double shval = (lambda2>0) ? exp(-arg)/rmax : cos(arg)/rmax ;
149  double dshval = (lambda2>0) ? -la*exp(-arg)/rmax - exp(-arg)/rmax/rmax : -sin(arg)/rmax*(la+masse_val*cor/la/rmax) - cos(arg)/rmax/rmax ;
150 
151  if (doder) {
152  double shder = (lambda2>0) ? 0 : -sin(arg)/rmax*log(rmax)/la*cor*masse_der ;
153  sh = new Term_eq (dom, shval, shder) ;
154  double dshder = (lambda2>0) ? 0 : (-cos(arg)/rmax*(la+masse_val*cor/la/rmax)*cor*log(rmax)/la + sin(arg)/rmax/rmax*(cor*log(rmax)/la-cor/la))*masse_der ;
155  dsh = new Term_eq (dom, dshval, dshder) ;
156  }
157  else {
158  sh = new Term_eq (dom, shval) ;
159  dsh = new Term_eq (dom, dshval) ;
160  }
161 
162  Term_eq* ff ;
163  Term_eq* dff ;
164 
165  double ffval = val_boundary (OUTER_BC, so.get_val_t()()(dom), pos) ;
166  double dffval = val_boundary (OUTER_BC, so.get_val_t()()(dom).der_r(), pos) ;
167  if (doder) {
168  double ffder = val_boundary (OUTER_BC, so.get_der_t()()(dom), pos) ;
169  double dffder = val_boundary (OUTER_BC, so.get_der_t()()(dom).der_r(), pos) ;
170  ff = new Term_eq (dom, ffval, ffder) ;
171  dff = new Term_eq (dom, dffval, dffder) ;
172  }
173  else {
174  ff = new Term_eq (dom, ffval) ;
175  dff = new Term_eq (dom, dffval) ;
176  }
177 
178  Term_eq auxi (rmax*rmax*((*sh)*(*dff)-(*dsh)*(*ff))) ;
179  resval.set_coef(pos) = auxi.get_val_d() ;
180  if (doder)
181  resder.set_coef(pos) = auxi.get_der_d() ;
182 
183 
184  delete sh ;
185  delete dsh ;
186  delete ff ;
187  delete dff ;
188  }
189 
190 
191 
192  // Put the basis and the result in a term_eq
193  if (so.get_val_t()()(dom).check_if_zero()) {
194  resval.set_zero() ;
195  }
196  else {
197  resval.set_base() = so.get_val_t()()(dom).get_base() ;
198  }
199  if (doder) {
200  if (so.get_der_t()()(dom).check_if_zero()) {
201  resder.set_zero() ;
202  }
203  else {
204  resder.set_base() = so.get_der_t()()(dom).get_base() ;
205  }
206  }
207  Scalar res (so.get_val_t()(), false) ;
208  res.set_domain(dom) = resval ;
209 
210 
211 
212  if (doder) {
213  Scalar der (so.get_der_t()(), false) ;
214  der.set_domain(dom) = resder ;
215  return Term_eq (dom, res, der) ;
216  }
217  else
218  return Term_eq (dom, res) ;
219 }
220 
221  }
Bases_container bases_1d
Arrays containing the various basis of decomposition.
double give_harmonique_nonflat(const Val_domain &so, double mass, 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...
double alpha
Relates the numerical to the physical radii.
Term_eq fitwaves_nonflat(const Term_eq &so, const Term_eq &field, const Array< double > &phases, int dim, double factor) const
Fit some field with homogenous solutions of the wave equation (Term_eq version).
double ome
Relates the numerical time to the physical one.
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 mult_r(const Val_domain &) const
Multiplication 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
void set_start()
Sets the position to zero in all dimensions.
Definition: index.hpp:88
bool inc(int increm, int var=0)
Increments the position of the Index.
Definition: index.hpp:99
The class Scalar does not really implements scalars in the mathematical sense but rather tensorial co...
Definition: scalar.hpp:67
Val_domain & set_domain(int)
Read/write of a particular Val_domain.
Definition: scalar.hpp:555
int get_valence() const
Returns the valence.
Definition: tensor.hpp:509
This class is intended to describe the manage objects appearing in the equations.
Definition: term_eq.hpp:62
double get_der_d() const
Definition: term_eq.hpp:341
double get_val_d() const
Definition: term_eq.hpp:327
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
void coef() const
Computes the coefficients.
Definition: val_domain.cpp:622
Base_spectral & set_base()
Sets the basis of decomposition.
Definition: val_domain.hpp:126