MercuryDPM  0.11
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
NormalisedPolynomial.hcc
Go to the documentation of this file.
1 //Copyright (c) 2013-2014, The MercuryDPM Developers Team. All rights reserved.
2 //For the list of developers, see <http://www.MercuryDPM.org/Team>.
3 //
4 //Redistribution and use in source and binary forms, with or without
5 //modification, are permitted provided that the following conditions are met:
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above copyright
9 // notice, this list of conditions and the following disclaimer in the
10 // documentation and/or other materials provided with the distribution.
11 // * Neither the name MercuryDPM nor the
12 // names of its contributors may be used to endorse or promote products
13 // derived from this software without specific prior written permission.
14 //
15 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16 //ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 //WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 //DISCLAIMED. IN NO EVENT SHALL THE MERCURYDPM DEVELOPERS TEAM BE LIABLE FOR ANY
19 //DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 //(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 //LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 //ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 //(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 //SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 
26 template<StatType T>
27 void NORMALIZED_POLYNOMIAL<T>::set_polynomial(std::vector<double> new_coefficients, unsigned int new_dim)
28 {
29  coefficients = new_coefficients;
30  dim = new_dim;
32 }
33 
34 template<StatType T>
35 void NORMALIZED_POLYNOMIAL<T>::set_polynomial(double* new_coefficients, unsigned int num_coeff, unsigned int new_dim)
36 {
37  coefficients.resize(num_coeff);
38  for (unsigned int i = 0; i < num_coeff; i++)
39  coefficients[i] = new_coefficients[i];
40  dim = new_dim;
42 }
43 
44 template<StatType T>
46 {
47  //normalizes the Polynomial.
48  double volume = get_volume();
49  if (fabs(volume - 1.0) > 1e-12)
50  std::cout << "Warning: Polynomial has to be normalized by " << volume << std::endl;
51  for (unsigned int i = 0; i < coefficients.size(); i++)
52  coefficients[i] /= volume;
53 
54  //sets #averaged_coefficients
55  set_average();
56 
57  //std::couts the Polynomial
58  std::stringstream sstr;
59  sstr << *this;
60  setName(sstr.str().c_str());
61  std::cout << "p=" << *this << std::endl;
62 }
63 
64 template<StatType T>
66 {
67  double volume = 0;
68  unsigned int N = coefficients.size();
69  if (dim == 3)
70  {
71  for (unsigned int i = 0; i < N; i++)
72  volume += coefficients[i] / (2. + N - i);
73  volume *= 4. * constants::pi;
74  }
75  else if (dim == 2)
76  {
77  std::cerr << "dim=2 is not working yet" << std::endl;
78  exit(-1);
79  for (unsigned int i = 0; i < coefficients.size(); i++)
80  volume += coefficients[i] / (1. + N - i);
81  volume *= 2. * constants::pi;
82  }
83  else if (dim == 1)
84  {
85  std::cerr << "dim=1 is not working yet" << std::endl;
86  exit(-1);
87  for (unsigned int i = 0; i < coefficients.size(); i++)
88  volume += coefficients[i] / (0. + N - i);
89  volume *= 2.;
90  }
91  else
92  {
93  std::cerr << "Error in get_volume: dim=" << dim << std::endl;
94  exit(-1);
95  }
96  return volume;
97 }
98 
99 template<StatType T>
101 {
102  std::cout << "set_average" << std::endl;
103 }
104 
105 template<StatType T>
107 {
108  std::cout << "set_average_1D" << std::endl;
109  unsigned int N = coefficients.size();
110  averaged_coefficients.resize(N + 2);
111  for (unsigned int i = 0; i < N + 2; i++)
112  {
113  averaged_coefficients[i] = 0;
114  }
115  for (unsigned int i = 0; i < N; i++)
116  {
117  averaged_coefficients[N + 1] += coefficients[i] * 2 * constants::pi / (N - 1 - i + 2);
118  averaged_coefficients[i] -= coefficients[i] * 2 * constants::pi / (N - 1 - i + 2);
119  }
120 }
121 
122 //not needed
123 template<StatType T>
125 {
126 }
127 
128 //Returns the value of the Polynomial \f$p(r)=\sum_{i=0}^{N-1) c_i r^{N-1-i}\f$.
129 template<StatType T>
131 {
132  unsigned int N = coefficients.size();
133  double value = coefficients[0];
134  for (unsigned int i = 1; i < N; i++)
135  value = value * r + coefficients[i];
137  return value;
138 }
139 
140 //Returns the value of the Polynomial \f$p(r)=\sum_{i=0}^{N-1) (N-1-i) c_i r^{N-2-i}\f$.
141 template<StatType T>
143 {
144  unsigned int N = coefficients.size();
145  double value = (N - 1) * coefficients[0];
146  for (unsigned int i = 1; i < N - 1; i++)
147  value = value * r + (N - 1 - i) * coefficients[i];
148  return value;
149 }
150 
151 template<StatType T>
153 {
154  unsigned int N = averaged_coefficients.size();
155  double value = averaged_coefficients[0];
156  for (unsigned int i = 1; i < N; i++)
157  value = value * r + averaged_coefficients[i];
158  return value;
159 }
160 
161 template<StatType T>
163 {
164  unsigned int N = coefficients.size();
165  double value = coefficients[0];
166  double value2 = coefficients[0];
167  for (unsigned int i = 1; i < N - 1; i++)
168  {
169  value = value * r + coefficients[i];
170  value2 += coefficients[i];
171  }
172  return 2. * constants::pi * r * (value2 - value * r);
173 }
174 
175 template<StatType T>
177 {
179  return 0.0;
180 }
181 
182 template<StatType T>
184 {
185  //~ std::cout << "eval_2D" << std::endl;
186  unsigned int N = coefficients.size();
187  double value1 = 2. * coefficients[N - 1];
188  double value2 = 0;
189  double r2 = r * r;
190  switch (N)
191  {
192  case 7:
193  value1 += coefficients[N - 7] * 2. / 35. * (5. + r2 * (6. + r2 * (8 * r2 + 16)));
194  //[[clang::fallthrough]];
195  case 6:
196  value1 += coefficients[N - 6] * (8. + (10. + 15. * r2) * r2) / 24.;
197  value2 += coefficients[N - 6] * (15. * r2 * r2 * r2) / 24.;
198  //[[clang::fallthrough]];
199  case 5:
200  value1 += coefficients[N - 5] * .4 * (1. + r2 * (4. / 3. + r2 * 8. / 3.));
201  //[[clang::fallthrough]];
202  case 4:
203  value1 += coefficients[N - 4] * (2. + r2 * 3.) / 4.;
204  value2 += coefficients[N - 4] * .75 * r2 * r2;
205  //[[clang::fallthrough]];
206  case 3:
207  value1 += coefficients[N - 3] * 2. / 3. * (1. + r2 * 2.);
208  //[[clang::fallthrough]];
209  case 2:
210  value1 += coefficients[N - 2] * 1.;
211  value2 += coefficients[N - 2] * r2;
212  //[[clang::fallthrough]];
213  case 1:
214  break;
215  default:
216  std::cerr << "Error: no rules set for high-order polynomials" << std::endl;
217  exit(-1);
218  }
219  double root = sqrt(1 - r2);
220  double invz = root / r;
221  double arccsch = log(sqrt(1. + invz * invz) + invz);
222  return value1 * root + value2 * arccsch;
223 }
224 
225 template<StatType T>
226 double NORMALIZED_POLYNOMIAL<T>::evaluateIntegral(double a, double b, double t)
227 {
228  unsigned int N = coefficients.size();
229  double value1 = coefficients[N - 1] * (b - a);
230  double value2 = 0;
231  double t2 = t * t;
232  double a2 = a * a;
233  double b2 = b * b;
234  double roota = sqrt(a * a + t2);
235  double rootb = sqrt(b * b + t2);
236  switch (N)
237  {
238  case 7:
239  value1 += coefficients[N - 7] * (b * (b2 * b2 * b2 / 7.0 + 0.6 * b2 * b2 * t2 + b2 * t2 * t2 + t2 * t2 * t2) - a * (a2 * a2 * a2 / 7.0 + 0.6 * a2 * a2 * t2 + a2 * t2 * t2 + t2 * t2 * t2));
240  //[[clang::fallthrough]];
241  case 6:
242  value1 += coefficients[N - 6] * (b * rootb * (8. * b2 * b2 + 26. * b2 * t2 + 33. * t2 * t2) - a * roota * (8. * a2 * a2 + 26. * a2 * t2 + 33. * t2 * t2)) / 48.;
243  value2 += coefficients[N - 6] * 15. / 48. * t2 * t2 * t2;
244  //[[clang::fallthrough]];
245  case 5:
246  value1 += coefficients[N - 5] * (b * (b2 * b2 / 5. + 2. / 3. * b2 * t2 + t2 * t2) - a * (a2 * a2 / 5. + 2. / 3. * a2 * t2 + t2 * t2));
247  //[[clang::fallthrough]];
248  case 4:
249  value1 += coefficients[N - 4] * (b * rootb * (2. * b2 + 5. * t2) - a * roota * (2. * a2 + 5. * t2)) / 8.;
250  value2 += coefficients[N - 4] * 3. / 8. * t2 * t2;
251  //[[clang::fallthrough]];
252  case 3:
253  value1 += coefficients[N - 3] * (b * (b2 / 3. + t2) - a * (a2 / 3. + t2));
254  //[[clang::fallthrough]];
255  case 2:
256  value1 += coefficients[N - 2] * (b * rootb - a * roota) / 2.;
257  value2 += coefficients[N - 2] * t2 / 2.;
258  //[[clang::fallthrough]];
259  case 1:
260  break;
261  default:
262  std::cerr << "Error: no rules set for high-order polynomials" << std::endl;
263  exit(-1);
264  }
265  double A = a / t;
266  double B = b / t;
267  double arcsinh = t < 1e-12 ? 0.0 : log(B + sqrt(1. + B * B)) - log(A + sqrt(1. + A * A));
268  //~ std::cout
269  //~ << "value1 " << value1 << std::endl
270  //~ << "value2 " << value2 << std::endl
271  //~ << "arcsinh " << arcsinh << std::endl
272  //~ << "a " << a << std::endl
273  //~ << "b " << b << std::endl
274  //~ << "t " << t << std::endl;
275  return value1 + value2 * arcsinh;
276 }
277 
279 template <StatType T>
280 double NORMALIZED_POLYNOMIAL<T>::evaluateIntegral_2D(double a UNUSED, double b UNUSED, double t UNUSED)
281 {
282  std::cerr << "evaluateIntegral_2D is not implemented yet" << std::endl;
283  exit(-1);
284 }
285 
286 template<StatType T>
287 double NORMALIZED_POLYNOMIAL<T>::evaluateIntegral_1D(double a, double b, double t)
288 {
289  unsigned int N = averaged_coefficients.size();
290  double value1 = averaged_coefficients[N - 1] * (b - a);
291  double value2 = 0;
292  double t2 = t * t;
293  double a2 = a * a;
294  double b2 = b * b;
295  double roota = sqrt(a * a + t2);
296  double rootb = sqrt(b * b + t2);
297  switch (N)
298  {
299  case 7:
300  value1 += averaged_coefficients[N - 7] * (b * (b2 * b2 * b2 / 7.0 + 0.6 * b2 * b2 * t2 + b2 * t2 * t2 + t2 * t2 * t2) - a * (a2 * a2 * a2 / 7.0 + 0.6 * a2 * a2 * t2 + a2 * t2 * t2 + t2 * t2 * t2));
301  //[[clang::fallthrough]];
302  case 6:
303  value1 += averaged_coefficients[N - 6] * (b * rootb * (8. * b2 * b2 + 26. * b2 * t2 + 33. * t2 * t2) - a * roota * (8. * a2 * a2 + 26. * a2 * t2 + 33. * t2 * t2)) / 48.;
304  value2 += averaged_coefficients[N - 6] * 15. / 48. * t2 * t2 * t2;
305  //[[clang::fallthrough]];
306  case 5:
307  value1 += averaged_coefficients[N - 5] * (b * (b2 * b2 / 5. + 2. / 3. * b2 * t2 + t2 * t2) - a * (a2 * a2 / 5. + 2. / 3. * a2 * t2 + t2 * t2));
308  //[[clang::fallthrough]];
309  case 4:
310  value1 += averaged_coefficients[N - 4] * (b * rootb * (2. * b2 + 5. * t2) - a * roota * (2. * a2 + 5. * t2)) / 8.;
311  value2 += averaged_coefficients[N - 4] * 3. / 8. * t2 * t2;
312  //[[clang::fallthrough]];
313  case 3:
314  value1 += averaged_coefficients[N - 3] * (b * (b2 / 3. + t2) - a * (a2 / 3. + t2));
315  //[[clang::fallthrough]];
316  case 2:
317  value1 += averaged_coefficients[N - 2] * (b * rootb - a * roota) / 2.;
318  value2 += averaged_coefficients[N - 2] * t2 / 2.;
319  //[[clang::fallthrough]];
320  case 1:
321  break;
322  default:
323  std::cerr << "Error: no rules set for high-order polynomials" << std::endl;
324  exit(-1);
325  }
326  double A = a / t;
327  double B = b / t;
328  double arcsinh = t < 1e-12 ? 0.0 : log(B + sqrt(1. + B * B)) - log(A + sqrt(1. + A * A));
329  return value1 + value2 * arcsinh;
330 
331  // 3D Heaviside: ( b-a );
332  // 3D Polynomial: evaluateIntegral(max(a,-wn)/w,min(b,wn)/w,tangential.GetLength()/w)*w;
333  // 1D Polynomial: evaluateIntegral(max(a,-wn)/w,min(b,wn)/w,tangential.GetLength()/w)*w;
334  // 1D Heaviside: ((b*pi*(wn2-mathsFunc::square(b)/3.0)))-((a*pi*(wn2-mathsFunc::square(a)/3.0)));
335  //~ averaged_coefficients[N+1] += coefficients[i]*2*pi/(N-1-i+2);
336  //~ averaged_coefficients[i] -= coefficients[i]*2*pi/(N-1-i+2);
337 
338 }
339 
341 {
342  set_average_1D();
343 }
345 {
346  set_average_1D();
347 }
349 {
350  set_average_1D();
351 }
353 {
354  set_average_2D();
355 }
357 {
358  set_average_2D();
359 }
361 {
362  set_average_2D();
363 }
364 
365 template<> double NORMALIZED_POLYNOMIAL<X>::evaluate(double r)
366 {
367  return evaluate_1D(r);
368 }
369 template<> double NORMALIZED_POLYNOMIAL<Y>::evaluate(double r)
370 {
371  return evaluate_1D(r);
372 }
373 template<> double NORMALIZED_POLYNOMIAL<Z>::evaluate(double r)
374 {
375  return evaluate_1D(r);
376 }
377 template<> double NORMALIZED_POLYNOMIAL<XY>::evaluate(double r)
378 {
379  return evaluate_2D(r);
380 }
381 template<> double NORMALIZED_POLYNOMIAL<XZ>::evaluate(double r)
382 {
383  return evaluate_2D(r);
384 }
385 template<> double NORMALIZED_POLYNOMIAL<YZ>::evaluate(double r)
386 {
387  return evaluate_2D(r);
388 }
389 
391 {
392  return evaluateGradient_1D(r);
393 }
395 {
396  return evaluateGradient_1D(r);
397 }
399 {
400  return evaluateGradient_1D(r);
401 }
403 {
404  return evaluateGradient_2D(r);
405 }
407 {
408  return evaluateGradient_2D(r);
409 }
411 {
412  return evaluateGradient_2D(r);
413 }
414 
415 template<> double NORMALIZED_POLYNOMIAL<X>::evaluateIntegral(double a, double b, double t)
416 {
417  return evaluateIntegral_1D(a, b, t);
418 }
419 template<> double NORMALIZED_POLYNOMIAL<Y>::evaluateIntegral(double a, double b, double t)
420 {
421  return evaluateIntegral_1D(a, b, t);
422 }
423 template<> double NORMALIZED_POLYNOMIAL<Z>::evaluateIntegral(double a, double b, double t)
424 {
425  return evaluateIntegral_1D(a, b, t);
426 }
427 template<> double NORMALIZED_POLYNOMIAL<XY>::evaluateIntegral(double a, double b, double t)
428 {
429  return evaluateIntegral_2D(a, b, t);
430 }
431 template<> double NORMALIZED_POLYNOMIAL<XZ>::evaluateIntegral(double a, double b, double t)
432 {
433  return evaluateIntegral_2D(a, b, t);
434 }
435 template<> double NORMALIZED_POLYNOMIAL<YZ>::evaluateIntegral(double a, double b, double t)
436 {
437  return evaluateIntegral_2D(a, b, t);
438 }
void setName(const char *new_name)
Use this function to change the name of the polynomial.
Mdouble evaluate_2D(Mdouble r)
Returns the value of the polynomial averaged over 1 dimension. For StatType=XY, . ...
Mdouble evaluateGradient_1D(Mdouble r)
Returns the value of the gradient averaged over 2 dimensions.
Mdouble evaluateIntegral(Mdouble a, Mdouble b, Mdouble t)
Returns the value of the line integral along the normal P1P2 "from a to b" over the axisymmetric func...
Mdouble evaluateGradient_2D(Mdouble r)
Returns the value of the gradient averaged over 1 dimensions.
unsigned int dim
The system dimension.
void set_average()
Sets averaged_coefficients.
void finish_set_polynomial()
Normalizes the polynomial coefficients such that the integral over the unit sphere of the axisymmetr...
const Mdouble pi
Definition: ExtendedMath.h:42
void set_polynomial(std::vector< Mdouble > new_coefficients, unsigned int new_dim)
Use this function to set the polynomial coefficients . This function calls finish_set_polynomial to n...
void set_average_1D()
Sets averaged_coefficients for StatType=X,Y,Z such that . See evaluate_1D.
#define UNUSED
Definition: GeneralDefine.h:37
void set_average_2D()
For StatType=XY,XZ,XZ, averaged_coefficients is not used since can be evaluated as a function of ...
std::vector< Mdouble > averaged_coefficients
Stores some coefficients used in evaluate and evaluateIntegral for StatTypes different from XYZ...
Mdouble evaluateIntegral_1D(Mdouble a, Mdouble b, Mdouble t)
Returns the value of the line integral along the normal P1P2 "from a to b" over the axisymmetric func...
Mdouble evaluate_1D(Mdouble r)
Returns the value of the polynomial averaged over 2 dimensions. For StatType=X, . See also set_averag...
Mdouble evaluateGradient(Mdouble r)
Returns the gradient of the polynomial, .
std::vector< Mdouble > coefficients
Stores the coefficients .
Mdouble get_volume()
Returns the integral over the unit sphere of the axisymmetric function .
Mdouble evaluate(Mdouble r)
Returns the value of the polynomial, .
Mdouble evaluateIntegral_2D(Mdouble a, Mdouble b, Mdouble t)
Returns the value of the line integral along the normal P1P2 "from a to b" over the axisymmetric func...