MercuryDPM  0.10
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Polynomial.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  coefficients = new_coefficients;
29  dim = new_dim;
30  finish_set_polynomial();
31 }
32 
33 template <StatType T>
34 void NORMALIZED_POLYNOMIAL<T>::set_polynomial(double* new_coefficients, unsigned int num_coeff, unsigned int new_dim) {
35  coefficients.resize(num_coeff);
36  for (unsigned int i=0; i<num_coeff; i++)
37  coefficients[i] = new_coefficients[i];
38  dim = new_dim;
39  finish_set_polynomial();
40 }
41 
42 template <StatType T>
44  //normalizes the Polynomial.
45  double volume = get_volume();
46  if (fabs(volume-1.0)>1e-12)
47  std::cout << "Warning: Polynomial has to be normalized by " << volume << std::endl;
48  for (unsigned int i=0; i<coefficients.size(); i++)
49  coefficients[i] /= volume;
50 
51  //sets #averaged_coefficients
52  set_average();
53 
54  //std::couts the Polynomial
55  std::stringstream sstr;
56  sstr << *this;
57  set_name(sstr.str().c_str());
58  std::cout << "p=" << *this << std::endl;
59 }
60 
61 template <StatType T>
63  double volume = 0;
64  unsigned int N = coefficients.size();
65  if (dim==3) {
66  for (unsigned int i=0; i<N; i++)
67  volume += coefficients[i]/(2.+N-i);
68  volume *= 4.*constants::pi;
69  } else if (dim==2) {
70  std::cerr << "dim=2 is not working yet" << std::endl; exit(-1);
71  for (unsigned int i=0; i<coefficients.size(); i++)
72  volume += coefficients[i]/(1.+N-i);
73  volume *= 2.*constants::pi;
74  } else if (dim==1) {
75  std::cerr << "dim=1 is not working yet" << std::endl; exit(-1);
76  for (unsigned int i=0; i<coefficients.size(); i++)
77  volume += coefficients[i]/(0.+N-i);
78  volume *= 2.;
79  } else {
80  std::cerr << "Error in get_volume: dim=" << dim << std::endl; exit(-1);
81  }
82  return volume;
83 }
84 
85 template <StatType T>
86 void NORMALIZED_POLYNOMIAL<T>::set_average() {std::cout << "set_average" << std::endl;}
87 
88 template <StatType T>
90  std::cout << "set_average_1D" << std::endl;
91  unsigned int N = coefficients.size();
92  averaged_coefficients.resize(N+2);
93  for (unsigned int i=0; i<N+2; i++) {
94  averaged_coefficients[i] = 0;
95  }
96  for (unsigned int i=0; i<N; i++) {
97  averaged_coefficients[N+1] += coefficients[i]*2*constants::pi/(N-1-i+2);
98  averaged_coefficients[i] -= coefficients[i]*2*constants::pi/(N-1-i+2);
99  }
100 }
101 
102 //not needed
103 template <StatType T>
105 }
106 
107 //Returns the value of the Polynomial \f$p(r)=\sum_{i=0}^{N-1) c_i r^{N-1-i}\f$.
108 template <StatType T>
110  unsigned int N = coefficients.size();
111  double value = coefficients[0];
112  for (unsigned int i=1; i<N; i++)
113  value = value*r+coefficients[i];
115  return value;
116 }
117 
118 //Returns the value of the Polynomial \f$p(r)=\sum_{i=0}^{N-1) (N-1-i) c_i r^{N-2-i}\f$.
119 template <StatType T>
121  unsigned int N = coefficients.size();
122  double value = (N-1)*coefficients[0];
123  for (unsigned int i=1; i<N-1; i++)
124  value = value*r+(N-1-i)*coefficients[i];
125  return value;
126 }
127 
128 template <StatType T>
130  unsigned int N = averaged_coefficients.size();
131  double value = averaged_coefficients[0];
132  for (unsigned int i=1; i<N; i++)
133  value = value*r+averaged_coefficients[i];
134  return value;
135 }
136 
137 template <StatType T>
139  unsigned int N = coefficients.size();
140  double value = coefficients[0];
141  double value2 = coefficients[0];
142  for (unsigned int i=1; i<N-1; i++) {
143  value = value*r+coefficients[i];
144  value2 += coefficients[i];
145  }
146  return 2.*constants::pi*r*(value2-value*r);
147 }
148 
149 template <StatType T>
152  return 0.0;
153 }
154 
155 
156 template <StatType T>
158  //~ std::cout << "eval_2D" << std::endl;
159  unsigned int N = coefficients.size();
160  double value1 = 2.*coefficients[N-1];
161  double value2 = 0;
162  double r2 = r*r;
163  switch (N) {
164  case 7:
165  value1 += coefficients[N-7]*2./35.*(5.+r2*(6.+r2*(8*r2+16)));
166  case 6:
167  value1 += coefficients[N-6]*(8.+(10.+15.*r2)*r2)/24.;
168  value2 += coefficients[N-6]*(15.*r2*r2*r2)/24.;
169  case 5:
170  value1 += coefficients[N-5]*.4*(1.+r2*(4./3.+r2*8./3.));
171  case 4:
172  value1 += coefficients[N-4]*(2.+r2*3.)/4.;
173  value2 += coefficients[N-4]*.75*r2*r2;
174  case 3:
175  value1 += coefficients[N-3]*2./3.*(1.+r2*2.);
176  case 2:
177  value1 += coefficients[N-2]*1.;
178  value2 += coefficients[N-2]*r2;
179  case 1:
180  break;
181  default:
182  std::cerr << "Error: no rules set for high-order polynomials" << std::endl; exit(-1);
183  }
184  double root = sqrt(1-r2);
185  double invz = root/r;
186  double arccsch = log(sqrt(1.+invz*invz)+invz);
187  return value1*root+value2*arccsch;
188 }
189 
190 template <StatType T>
191 double NORMALIZED_POLYNOMIAL<T>::evaluateIntegral(double a, double b, double t) {
192  unsigned int N = coefficients.size();
193  double value1 = coefficients[N-1]*(b-a);
194  double value2 = 0;
195  double t2 = t*t;
196  double a2 = a*a;
197  double b2 = b*b;
198  double roota = sqrt(a*a+t2);
199  double rootb = sqrt(b*b+t2);
200  switch (N) {
201  case 7:
202  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));
203  case 6:
204  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.;
205  value2 += coefficients[N-6]*15./48.*t2*t2*t2;
206  case 5:
207  value1 += coefficients[N-5]*(b*(b2*b2/5.+2./3.*b2*t2+t2*t2)-a*(a2*a2/5.+2./3.*a2*t2+t2*t2));
208  case 4:
209  value1 += coefficients[N-4]*(b*rootb*(2.*b2+5.*t2)-a*roota*(2.*a2+5.*t2))/8.;
210  value2 += coefficients[N-4]*3./8.*t2*t2;
211  case 3:
212  value1 += coefficients[N-3]*(b*(b2/3.+t2)-a*(a2/3.+t2));
213  case 2:
214  value1 += coefficients[N-2]*(b*rootb-a*roota)/2.;
215  value2 += coefficients[N-2]*t2/2.;
216  case 1:
217  break;
218  default:
219  std::cerr << "Error: no rules set for high-order polynomials" << std::endl; exit(-1);
220  }
221  double A = a/t;
222  double B = b/t;
223  double arcsinh = t<1e-12 ? 0.0 : log(B+sqrt(1.+B*B))-log(A+sqrt(1.+A*A));
224  //~ std::cout
225  //~ << "value1 " << value1 << std::endl
226  //~ << "value2 " << value2 << std::endl
227  //~ << "arcsinh " << arcsinh << std::endl
228  //~ << "a " << a << std::endl
229  //~ << "b " << b << std::endl
230  //~ << "t " << t << std::endl;
231  return value1+value2*arcsinh;
232 }
233 
235 template <StatType T>
236 double NORMALIZED_POLYNOMIAL<T>::evaluateIntegral_2D(double a UNUSED, double b UNUSED, double t UNUSED) {
237  std::cerr << "evaluateIntegral_2D is not implemented yet" << std::endl;
238  exit(-1);
239 }
240 
241 template <StatType T>
242 double NORMALIZED_POLYNOMIAL<T>::evaluateIntegral_1D(double a, double b, double t) {
243  unsigned int N = averaged_coefficients.size();
244  double value1 = averaged_coefficients[N-1]*(b-a);
245  double value2 = 0;
246  double t2 = t*t;
247  double a2 = a*a;
248  double b2 = b*b;
249  double roota = sqrt(a*a+t2);
250  double rootb = sqrt(b*b+t2);
251  switch (N) {
252  case 7:
253  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));
254  case 6:
255  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.;
256  value2 += averaged_coefficients[N-6]*15./48.*t2*t2*t2;
257  case 5:
258  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));
259  case 4:
260  value1 += averaged_coefficients[N-4]*(b*rootb*(2.*b2+5.*t2)-a*roota*(2.*a2+5.*t2))/8.;
261  value2 += averaged_coefficients[N-4]*3./8.*t2*t2;
262  case 3:
263  value1 += averaged_coefficients[N-3]*(b*(b2/3.+t2)-a*(a2/3.+t2));
264  case 2:
265  value1 += averaged_coefficients[N-2]*(b*rootb-a*roota)/2.;
266  value2 += averaged_coefficients[N-2]*t2/2.;
267  case 1:
268  break;
269  default:
270  std::cerr << "Error: no rules set for high-order polynomials" << std::endl; exit(-1);
271  }
272  double A = a/t;
273  double B = b/t;
274  double arcsinh = t<1e-12 ? 0.0 : log(B+sqrt(1.+B*B))-log(A+sqrt(1.+A*A));
275  return value1+value2*arcsinh;
276 
277  // 3D Heaviside: ( b-a );
278  // 3D Polynomial: evaluateIntegral(max(a,-wn)/w,min(b,wn)/w,tangential.GetLength()/w)*w;
279  // 1D Polynomial: evaluateIntegral(max(a,-wn)/w,min(b,wn)/w,tangential.GetLength()/w)*w;
280  // 1D Heaviside: ((b*pi*(wn2-sqr(b)/3.0)))-((a*pi*(wn2-sqr(a)/3.0)));
281  //~ averaged_coefficients[N+1] += coefficients[i]*2*pi/(N-1-i+2);
282  //~ averaged_coefficients[i] -= coefficients[i]*2*pi/(N-1-i+2);
283 
284 }
285 
286 template<> void NORMALIZED_POLYNOMIAL<X>::set_average() {set_average_1D();}
287 template<> void NORMALIZED_POLYNOMIAL<Y>::set_average() {set_average_1D();}
288 template<> void NORMALIZED_POLYNOMIAL<Z>::set_average() {set_average_1D();}
289 template<> void NORMALIZED_POLYNOMIAL<XY>::set_average() {set_average_2D();}
290 template<> void NORMALIZED_POLYNOMIAL<XZ>::set_average() {set_average_2D();}
291 template<> void NORMALIZED_POLYNOMIAL<YZ>::set_average() {set_average_2D();}
292 
293 template<> double NORMALIZED_POLYNOMIAL<X>::evaluate(double r) {return evaluate_1D(r);}
294 template<> double NORMALIZED_POLYNOMIAL<Y>::evaluate(double r) {return evaluate_1D(r);}
295 template<> double NORMALIZED_POLYNOMIAL<Z>::evaluate(double r) {return evaluate_1D(r);}
296 template<> double NORMALIZED_POLYNOMIAL<XY>::evaluate(double r) {return evaluate_2D(r);}
297 template<> double NORMALIZED_POLYNOMIAL<XZ>::evaluate(double r) {return evaluate_2D(r);}
298 template<> double NORMALIZED_POLYNOMIAL<YZ>::evaluate(double r) {return evaluate_2D(r);}
299 
300 template<> double NORMALIZED_POLYNOMIAL<X>::evaluateGradient(double r) {return evaluateGradient_1D(r);}
301 template<> double NORMALIZED_POLYNOMIAL<Y>::evaluateGradient(double r) {return evaluateGradient_1D(r);}
302 template<> double NORMALIZED_POLYNOMIAL<Z>::evaluateGradient(double r) {return evaluateGradient_1D(r);}
303 template<> double NORMALIZED_POLYNOMIAL<XY>::evaluateGradient(double r) {return evaluateGradient_2D(r);}
304 template<> double NORMALIZED_POLYNOMIAL<XZ>::evaluateGradient(double r) {return evaluateGradient_2D(r);}
305 template<> double NORMALIZED_POLYNOMIAL<YZ>::evaluateGradient(double r) {return evaluateGradient_2D(r);}
306 
307 template<> double NORMALIZED_POLYNOMIAL<X>::evaluateIntegral(double a, double b, double t) {return evaluateIntegral_1D(a,b,t);}
308 template<> double NORMALIZED_POLYNOMIAL<Y>::evaluateIntegral(double a, double b, double t) {return evaluateIntegral_1D(a,b,t);}
309 template<> double NORMALIZED_POLYNOMIAL<Z>::evaluateIntegral(double a, double b, double t) {return evaluateIntegral_1D(a,b,t);}
310 template<> double NORMALIZED_POLYNOMIAL<XY>::evaluateIntegral(double a, double b, double t) {return evaluateIntegral_2D(a,b,t);}
311 template<> double NORMALIZED_POLYNOMIAL<XZ>::evaluateIntegral(double a, double b, double t) {return evaluateIntegral_2D(a,b,t);}
312 template<> double NORMALIZED_POLYNOMIAL<YZ>::evaluateIntegral(double a, double b, double t) {return evaluateIntegral_2D(a,b,t);}
Mdouble evaluate_2D(Mdouble r)
Returns the value of the polynomial averaged over 1 dimension.
Definition: Polynomial.hcc:157
Mdouble evaluateGradient_1D(Mdouble r)
Returns the value of the gradient averaged over 2 dimensions.
Definition: Polynomial.hcc:138
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...
Definition: Polynomial.hcc:191
Mdouble evaluateGradient_2D(Mdouble r)
Returns the value of the gradient averaged over 1 dimensions.
Definition: Polynomial.hcc:150
void set_average()
Sets averaged_coefficients.
Definition: Polynomial.hcc:86
void finish_set_polynomial()
Normalizes the polynomial coefficients such that the integral over the unit sphere of the axisymmetr...
Definition: Polynomial.hcc:43
const Mdouble pi
Definition: ExtendedMath.h:54
void set_polynomial(std::vector< Mdouble > new_coefficients, unsigned int new_dim)
Use this function to set the polynomial coefficients .
Definition: Polynomial.hcc:27
void set_average_1D()
Sets averaged_coefficients for StatType=X,Y,Z such that .
Definition: Polynomial.hcc:89
void set_average_2D()
For StatType=XY,XZ,XZ, averaged_coefficients is not used since can be evaluated as a function of ...
Definition: Polynomial.hcc:104
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...
Definition: Polynomial.hcc:242
Mdouble evaluate_1D(Mdouble r)
Returns the value of the polynomial averaged over 2 dimensions.
Definition: Polynomial.hcc:129
#define UNUSED
Definition: ExtendedMath.h:38
Mdouble evaluateGradient(Mdouble r)
Returns the gradient of the polynomial, .
Definition: Polynomial.hcc:120
Mdouble get_volume()
Returns the integral over the unit sphere of the axisymmetric function .
Definition: Polynomial.hcc:62
Mdouble evaluate(Mdouble r)
Returns the value of the polynomial, .
Definition: Polynomial.hcc:109
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...
Definition: Polynomial.hcc:236