muMECH  1.0
esei_Sphere.cpp
Go to the documentation of this file.
1 //********************************************************************************************************
2 // code: ### ### ##### #### ## ##
3 // ## ## ######## ## ## ## ## ##
4 // ## ## ## ## ## ### ## ######
5 // ## ## ## ## ## ## ## ## ##
6 // ##### ## ## ##### #### ## ##
7 // ##
8 //
9 // name: eshelbySoluEllipticIntegralsSphere.cpp
10 // author(s): Jan Novak
11 // language: C, C++
12 // license: This program is free software; you can redistribute it and/or modify
13 // it under the terms of the GNU Lesser General Public License as published by
14 // the Free Software Foundation; either version 2 of the License, or
15 // (at your option) any later version.
16 //
17 // This program is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 // GNU Lesser General Public License for more details.
21 //
22 // You should have received a copy of the GNU Lesser General Public License
23 // along with this program; if not, write to the Free Software
24 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 //********************************************************************************************************
26 
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <math.h>
30 #include <cmath>
31 #include <iostream>
32 
33 #include "macros.h"
34 #include "esei_Sphere.h"
35 #include "elementaryFunctions.h"
36 #include "esei.h"
37 #include "problem.h"
38 
39 
40 namespace mumech {
41 
42 //********************************************************************************************************
43 // PUBLIC FUNCTIONS
44 //********************************************************************************************************
45 
46 
48 void eshelbySoluEllipticIntegralsSphere::giveEllipticIntegrals(double J[13], double lambda, bool intpoint)
49 {
50  double a0 = I->a[0];
51 
52  J[0] = 0.;
53  if (intpoint)
54  {
55  J[1] = J[2] = J[3] = 4.0 * PI / 3.0;
56  J[4] = J[5] = J[6] = J[7] = J[8] = J[9] = J[10] = J[11] = J[12] = 4.0 * PI / 5.0 / SQR(a0);
57  }
58  else
59  {
60  J[1] = J[2] = J[3] = 4.0 * PI * a0*a0*a0 / 3.0 / pow(a0*a0 + lambda, 3.0 / 2.0);
61  J[4] = J[5] = J[6] = J[7] = J[8] = J[9] = J[10] = J[11] = J[12] = 4.0 * PI * a0*a0*a0 / 5.0 / pow(a0*a0 + lambda, 5.0 / 2.0);
62  }
63 }//end of function: giveEllipticIntegrals( )
64 
65 
66 // ****************************************************************************************
67 // start: Alternative, more time demanding, evaluation of integrals
68 // ****************************************************************************************
69 
70 // termitovo: PROC JE TADY TATO FCE, DRIVE BYLA POUZIVANA, ALE JE TO ASI NEJAKY EXPERIMENT, NE?
71 //
72 // //********************************************************************************************************
73 // // description: Function gives the values of all elliptic integrals
74 // // last edit: 08. 06. 2010
75 // //-------------------------------------------------------------------------------------------------------
76 // // note: @J[13] - elliptic integral values
77 // // @a[3] - dimensions of sphere radii (a1=a2=a3)
78 // // @lambda - lambda parameter according Mura's book, page 73
79 // // @loc_x[3] - local coordinates of a point, in this case are the same as the global ones
80 // //********************************************************************************************************
81 // void eshelbySoluEllipticIntegralsSphere::giveEllipticIntegrals( double J[13], const double a[3], double lambda,
82 // const double loc_x[3] )
83 // {
84 // double aa = SQR( a[0] ), mult = 4. * PI * aa * a[0], xx = 0., aux_x = 0.,
85 // n_x[5] = { 0., 0., 0., 0., 0. };
86 //
87 // if( lambda > MACHINE_EPS ){
88 // xx = SQR( loc_x[0] ) + SQR( loc_x[1] ) + SQR( loc_x[2] ); aux_x = sqrt( xx );
89 // n_x[0] = aux_x; n_x[1] = n_x[0] * xx; n_x[2] = n_x[1] * xx; n_x[3] = n_x[2] * xx; n_x[4] = n_x[3] * xx;
90 // }else ;
91 //
92 // //Ferers-Dysons integrals:
93 // //------------------------
94 // this->give_Ii_and_Iij( J, mult, n_x, lambda, aa );
95 //
96 // return;
97 // }//end of function: giveEllipticIntegrals( )
98 //
99 // //********************************************************************************************************
100 // // description: Function gives the values of all elliptic Ferers-Dysons integrals
101 // // last edit: 08. 05. 2010
102 // //-------------------------------------------------------------------------------------------------------
103 // // note: @J[13] - table of elliptic integral values to be calculated
104 // // @mult - 4 * pi() * a^3
105 // // @norm_x[5] - length of vector x and its powers norm_x = {x, x^3, x^5, x^7, x^9}
106 // // @lambda - lambda parameter
107 // // @aa - square power of a[i] radius
108 // //********************************************************************************************************
109 // void eshelbySoluEllipticIntegralsSphere::give_Ii_and_Iij( double J[13], double mult, double norm_x[5],
110 // double lambda, double aa , bool intpoint )
111 // {
112 // //J[0] = this->eI( mult, norm_x, a, lambda ); //this value is not necessary anywhere else
113 // J[0] = 0.;
114 // J[1] = J[2] = J[3] = this->Ii( mult, norm_x, lambda, intpoint);
115 // J[4] = J[5] = J[6] = J[7] = J[8] = J[9] = J[10] = J[11] = J[12] = this->Iij( mult, norm_x, lambda, aa );
116 //
117 // return;
118 // }//end of function: give_Ii_and_Iij( )
119 //
120 // //********************************************************************************************************
121 // // description: Function gives the solution of the integral I_1
122 // // last edit: 05. 05. 2010
123 // //-------------------------------------------------------------------------------------------------------
124 // // note: I1 = I2 = I3
125 // // @mult - 4 * pi() * a^3
126 // // @norm_x[5] - length of vector x and its powers norm_x = {x, x^3, x^5, x^7, x^9}
127 // // @a - sphere radii
128 // // @lambda - lambda parameter
129 // //********************************************************************************************************
130 // double eshelbySoluEllipticIntegralsSphere::Ii( double mult, double norm_x[5], double lambda, bool intpoint )
131 // {
132 // return ( intpoint ? 4. * PI / 3. : mult/( 3. * norm_x[1] ) );
133 // }
134 //
135 // //********************************************************************************************************
136 // // description: Function gives the solution of the integral I_11
137 // // last edit: 05. 05. 2010
138 // //-------------------------------------------------------------------------------------------------------
139 // // note: I11 = I12 = I13 = I22 = I23 = I33
140 // // @mult - 4 * pi() * a^3
141 // // @norm_x[5] - length of vector x and its powers norm_x = {x, x^3, x^5, x^7, x^9}
142 // // @a[3] - sphere radii
143 // // @lambda - lambda parameter
144 // // @aa - square power of a[i] radius
145 // //********************************************************************************************************
146 // double eshelbySoluEllipticIntegralsSphere::Iij( double mult, double norm_x[5], double lambda, double aa, bool intpoint)
147 // {
148 // return ( intpoint ? 4. * PI / ( 5. * aa ) : mult/( 5. * norm_x[2] ) );
149 // }
150 // //********************************************************************************************************
151 // // description: Function gives the solution of the integral I
152 // // last edit: 05. 05. 2010
153 // //-------------------------------------------------------------------------------------------------------
154 // // note: @mult - 4 * pi() * a^3
155 // // @norm_x[5] - length of vector x and its powers norm_x = {x, x^3, x^5, x^7, x^9}
156 // // @a[3] - sphere radii
157 // // @lambda - lambda parameter
158 // //********************************************************************************************************
159 // double eshelbySoluEllipticIntegralsSphere::eI( double mult, double norm_x[5], const double a[3], double lambda, bool intpoint)
160 // {
161 // return ( intpoint ? mult/a[0] : mult/norm_x[0] );
162 // }
163 //
164 // ****************************************************************************************
165 // finish: Alternative, more time demanding, evaluation of integrals
166 // ****************************************************************************************
167 
168 
169 
170 //********************************************************************************************************
171 // description: Function gives the values of all elliptic integrals' derivatives
172 // last edit: 08. 06. 2010
173 //-------------------------------------------------------------------------------------------------------
174 // note: @point - point record (data structure of a given point)
175 // @a[3] - dimensions of sphere semiaxes (radii) (a1=a2=a3)
176 //********************************************************************************************************
178 {
179  if (intpoint) _errorr("derivatives are 0, this function should not be called");
180 
181  double ndiff = I->ndiff_1;
182 
183  double a0 = I->a[0];
184 
185  double aa = SQR( a0 ), mult = 4. * PI * aa * a0, xx = 0., aux_x = 0.,
186  n_x[5] = { 0., 0., 0., 0., 0. };
187 
188  // termitovo: toto je i v alternativni (asi pomaly) verzi vypoctu integralu, takze se to muze vykostit i odtud mozna
189  // a hlavne by se tady lambda vubec nemello pocitat, stejne jako v jinych tvarech
190  //if( point->la > MACHINE_EPS )
191  //{
192  xx = SQR( point->loc_x[0] ) + SQR( point->loc_x[1] ) + SQR( point->loc_x[2] ); aux_x = sqrt( xx );
193  n_x[0] = aux_x; n_x[1] = n_x[0] * xx; n_x[2] = n_x[1] * xx; n_x[3] = n_x[2] * xx; n_x[4] = n_x[3] * xx;
194  // }
195  //else
196  //errol; // test, sem by to nemelo dojit, a point->la by nemel byt lambda ???
197 
198 
199  //point->position == _EXT_POINT_
200  switch (I->P->give_diffType()){
201  case DT_COMPLEX : {
202  std::complex<double> cdJi[13], cdJij[27];
203 
204  //first derivatives Ii,i:
205  this->give_cdIi( cdJi, mult, point->loc_x );
206  //first derivatives Iij,i:
207  this->give_cdIij( cdJij, mult, point->loc_x );
208  //second derivatives Ii,ij:
209  this->give_cddIi( point->ddJi, cdJi );
210  //second derivatives Iij,ij:
211  this->give_cddIij( point->ddJij, cdJij );
212 
213  //complex-to-real conversion
214  for( int i = 0; i < 13; i++ ) point->dJi[i] = real( cdJi[i] );
215  for( int i = 0; i < 27; i++ ) point->dJij[i] = real( cdJij[i] );
216  break;
217  }
218  case DT_NUMERICAL : { // Real numerical derivatives
219  // Get perturbated points and their lambdas
220  double lambdas[NUM_PERTURB];
221  this->getPerturbatedLambdas(lambdas, point->loc_x);
222 
223  // Create and fill a two dimensional array containing values of J-integrals at perturbated points.
224  const int NUM_ELLIP_INT = 13;
225  double J_pert[NUM_PERTURB][NUM_ELLIP_INT]; // All perturbations of all elliptical integrals.
226  for (int i = 0; i < NUM_PERTURB; i++) // For each perturbated point
227  this->giveEllipticIntegrals(J_pert[i], lambdas[i], intpoint); // Get elliptical integrals for lambda of perturbated point.
228 
229  // Compute numerial derivatives of first and second order of J_i integrals.
230  for (int i = 0; i < 3; i++) // For each elliptic integral Ji
231  {
232  // See types.c, section "Derivatives of Ferers-Dysons' integrals".
233  // Ji_j = dJi[3*i+j-4], i,j=1..3.
234  point->dJi[3*i] = (J_pert[_Xp_][i+1] - J_pert[_Xm_][i+1]) / (2.0 * ndiff);
235  point->dJi[3*i+1] = (J_pert[_Yp_][i+1] - J_pert[_Ym_][i+1]) / (2.0 * ndiff);
236  point->dJi[3*i+2] = (J_pert[_Zp_][i+1] - J_pert[_Zm_][i+1]) / (2.0 * ndiff);
237 
238  // See types.c, section "Derivatives of Ferers-Dysons' integrals".
239  // Ji_jk = ddJi[9*i+3*j+k-13], i,j,k=1..3.
240  point->ddJi[9*i] = (J_pert[_Xp_][i+1] - 2.0 * J_pert[_CENTER_][i+1] + J_pert[_Xm_][i+1]) / (ndiff * ndiff); // d^2f(x,y,z)/dx^2 = (f(x+h,y,z) - 2*f(x,y,z) + f(x-h,y,z)) / h^2
241  point->ddJi[9*i+1] = (J_pert[_XpYp_][i+1] - J_pert[_XpYm_][i+1] - J_pert[_XmYp_][i+1] + J_pert[_XmYm_][i+1]) / (4.0*ndiff*ndiff); // d^2f(x,y,z)/dxdy = (f(x+h,y+h,z) - f(x+h,y-h,z) - f(x-h,y+h,z) + f(x-h,y-h,z)) / (4*h^2)
242  point->ddJi[9*i+2] = (J_pert[_XpZp_][i+1] - J_pert[_XpZm_][i+1] - J_pert[_XmZp_][i+1] + J_pert[_XmZm_][i+1]) / (4.0*ndiff*ndiff);
243 
244  point->ddJi[9*i+3] = point->ddJi[9*i+1];
245  point->ddJi[9*i+4] = (J_pert[_Yp_][i+1] - 2.0 * J_pert[_CENTER_][i+1] + J_pert[_Ym_][i+1]) / (ndiff * ndiff);
246  point->ddJi[9*i+5] = (J_pert[_YpZp_][i+1] - J_pert[_YpZm_][i+1] - J_pert[_YmZp_][i+1] + J_pert[_YmZm_][i+1]) / (4.0*ndiff*ndiff);
247 
248  point->ddJi[9*i+6] = point->ddJi[9*i+2];
249  point->ddJi[9*i+7] = point->ddJi[9*i+5];
250  point->ddJi[9*i+8] = (J_pert[_Zp_][i+1] - 2.0 * J_pert[_CENTER_][i+1] + J_pert[_Zm_][i+1]) / (ndiff * ndiff);
251  }
252 
253  // Compute numerial derivatives of first and second order of J_ij integrals.
254  for (int i = 0; i < 9; i++) // For each elliptic integral Jij
255  {
256  // See types.c, section "Derivatives of Ferers-Dysons' integrals".
257  // Jij_k = dJij[9*k+3*i+j-13], i,j,k=1..3.
258  point->dJij[i] = (J_pert[_Xp_][i+4] - J_pert[_Xm_][i+4]) / (2.0 * ndiff);
259  point->dJij[i+9] = (J_pert[_Yp_][i+4] - J_pert[_Ym_][i+4]) / (2.0 * ndiff);
260  point->dJij[i+18] = (J_pert[_Zp_][i+4] - J_pert[_Zm_][i+4]) / (2.0 * ndiff);
261 
262  // See types.c, section "Derivatives of Ferers-Dysons' integrals".
263  // Jij_kl = ddJi[27*i+9*j+3*k+l-40] i,j,k,l=1..3.
264  point->ddJij[9*i] = (J_pert[_Xp_][i+4] - 2.0 * J_pert[_CENTER_][i+4] + J_pert[_Xm_][i+4]) / (ndiff * ndiff);
265  point->ddJij[9*i+1] = (J_pert[_XpYp_][i+4] - J_pert[_XpYm_][i+4] - J_pert[_XmYp_][i+4] + J_pert[_XmYm_][i+4]) / (4.0*ndiff*ndiff);
266  point->ddJij[9*i+2] = (J_pert[_XpZp_][i+4] - J_pert[_XpZm_][i+4] - J_pert[_XmZp_][i+4] + J_pert[_XmZm_][i+4]) / (4.0*ndiff*ndiff);
267 
268  point->ddJij[9*i+3] = point->ddJij[9*i+1];
269  point->ddJij[9*i+4] = (J_pert[_Yp_][i+4] - 2.0 * J_pert[_CENTER_][i+4] + J_pert[_Ym_][i+4]) / (ndiff * ndiff);
270  point->ddJij[9*i+5] = (J_pert[_YpZp_][i+4] - J_pert[_YpZm_][i+4] - J_pert[_YmZp_][i+4] + J_pert[_YmZm_][i+4]) / (4.0*ndiff*ndiff);
271 
272  point->ddJij[9*i+6] = point->ddJij[9*i+2];
273  point->ddJij[9*i+7] = point->ddJij[9*i+5];
274  point->ddJij[9*i+8] = (J_pert[_Zp_][i+4] - 2.0 * J_pert[_CENTER_][i+4] + J_pert[_Zm_][i+4]) / (ndiff * ndiff);
275  }
276  break;
277  }
278  case DT_ANALITICAL :// Analytical derivatives
279  {
280  //first derivatives Ii,i:
281  this->give_dIi( point->dJi, mult, n_x, point->loc_x );
282  //first derivatives Iij,i:
283  this->give_dIij( point->dJij, mult, n_x, point->loc_x );
284  //second derivatives Ii,ij:
285  this->give_ddIi( point->ddJi, mult, n_x, point->loc_x );
286  //second derivatives Iij,ij:
287  this->give_ddIij( point->ddJij, mult, n_x, point->loc_x );
288  break;
289  }
290  default:
291  _errorr( "Invalid type of differentiation.\n");
292  }
293 }//end of function: giveDerivativesOfEllipticIntegrals( )
294 
295 //********************************************************************************************************
296 // PROTECTED FUNCTIONS
297 //********************************************************************************************************
298 
299 //Ferers-Dysons integrals:
300 //------------------------
301 
302 
303 
304 
305 //Analytical derivatives of Ferers-Dysons integrals:
306 //--------------------------------------------------
307 
308 //********************************************************************************************************
309 // description: Function gives the first derivative of the integral Ii
310 // last edit: 05. 05. 2010
311 //-------------------------------------------------------------------------------------------------------
312 // note: I1_i = I2_i = I3_i
313 // @mult - 4 * pi() * a^3
314 // @norm_x[5] - length of vector x and its powers norm_x = {x, x^3, x^5, x^7, x^9}
315 // @x[3] - coordinates of a point
316 // @direction - derivative direction (_x1_, _x2_, _x3_)
317 //********************************************************************************************************
318 double eshelbySoluEllipticIntegralsSphere::Ii_i( double mult, double norm_x[5], double x[3],
319  derivativeDirection direction )
320 {
321  int dir = direction - 1;
322 
323  return( -mult * x[dir]/norm_x[2] );
324 }//end of function: Ii_i()
325 
326 //********************************************************************************************************
327 // description: Function gives the second derivative of the integral Ii
328 // last edit: 05. 05. 2010
329 //-------------------------------------------------------------------------------------------------------
330 // note: I1_ij = I2_ij = I3_ij
331 // @mult - 4 * pi() * a^3
332 // @norm_x[5] - length of vector x and its powers norm_x = {x, x^3, x^5, x^7, x^9}
333 // @x[3] - coordinates of a point
334 // @direction - derivative direction (_x1_, _x2_, _x3_)
335 //********************************************************************************************************
336 double eshelbySoluEllipticIntegralsSphere::Ii_ij( double mult, double norm_x[5], double x[3],
337  derivativeDirection direction_1,
338  derivativeDirection direction_2 )
339 {
340  int dir_1 = direction_1 - 1, dir_2 = direction_2 - 1;
341  double aux = 5. * mult * x[dir_1] * x[dir_2]/norm_x[3];
342 
343  return ( dir_1 != dir_2 )? aux : ( aux - mult/norm_x[2] );
344 }//end of function: Ii_ij()
345 
346 //********************************************************************************************************
347 // description: Function gives the first derivative of the integral Iij
348 // last edit: 05. 05. 2010
349 //-------------------------------------------------------------------------------------------------------
350 // note: @mult - 4 * pi() * a^3
351 // @norm_x[5] - length of vector x and its powers norm_x = {x, x^3, x^5, x^7, x^9}
352 // @x[3] - coordinates of a point
353 // @direction - derivative direction (_x1_, _x2_, _x3_)
354 //********************************************************************************************************
355 double eshelbySoluEllipticIntegralsSphere::Iij_i( double mult, double norm_x[5], double x[3],
356  derivativeDirection direction )
357 {
358  int dir = direction - 1;
359 
360  return( -mult * x[dir]/norm_x[3] );
361 }//end of function: Iij_i()
362 
363 //********************************************************************************************************
364 // description: Function gives the second derivative of the integral Iij
365 // last edit: 08. 05. 2010
366 //-------------------------------------------------------------------------------------------------------
367 // note: @mult - 4 * pi() * a^3
368 // @norm_x[5] - length of vector x and its powers norm_x = {x, x^3, x^5, x^7, x^9}
369 // @x[3] - coordinates of a point
370 // @direction - derivative direction (_x1_, _x2_, _x3_)
371 //********************************************************************************************************
372 double eshelbySoluEllipticIntegralsSphere::Iij_ij( double mult, double norm_x[5], double x[3],
373  derivativeDirection direction_1,
374  derivativeDirection direction_2 )
375 {
376  int dir_1 = direction_1 - 1, dir_2 = direction_2 - 1;
377  double aux = 7. * mult * x[dir_1] * x[dir_2]/norm_x[4];
378 
379  return ( dir_1 != dir_2 )? aux : ( aux - mult/norm_x[3] );
380 }//end of function: Ii_ij()
381 
382 
383 //********************************************************************************************************
384 // description: Function gives all first derivatives of Ferers-Dysons' integrals Ii
385 // last edit: 08. 05. 2010
386 //-------------------------------------------------------------------------------------------------------
387 // note: @dJi[9] - table of elliptic integral derivatives to be calculated
388 // @mult - 4 * pi() * a^3
389 // @norm_x[5] - length of vector x and its powers norm_x = {x, x^3, x^5, x^7, x^9}
390 // @x[3] - coordinates of a point
391 //********************************************************************************************************
392 void eshelbySoluEllipticIntegralsSphere::give_dIi( double dJi[13], double mult, double norm_x[5],
393  double x[3] )
394 {
395  //dIi,1
396  dJi[0] = dJi[3] = dJi[6] = this->Ii_i( mult, norm_x, x, _x1_ ); //I1,1; I2,1; I3,1
397  //dIi,2
398  dJi[1] = dJi[4] = dJi[7] = this->Ii_i( mult, norm_x, x, _x2_ ); //I1,2; I2,2; I3,2
399  //dIi,3
400  dJi[2] = dJi[5] = dJi[8] = this->Ii_i( mult, norm_x, x, _x3_ ); //I1,3; I2,3; I3,3
401 
402  return;
403 }//end of function: give_dIi( )
404 
405 //********************************************************************************************************
406 // description: Function gives all first derivatives of Ferers-Dysons' integrals Iij
407 // last edit: 08. 05. 2010
408 //-------------------------------------------------------------------------------------------------------
409 // note: @dJij[27] - table of elliptic integral derivatives to be calculated
410 // @mult - 4 * pi() * a^3
411 // @norm_x[5] - length of vector x and its powers norm_x = {x, x^3, x^5, x^7, x^9}
412 // @x[3] - coordinates of a point
413 //********************************************************************************************************
414 void eshelbySoluEllipticIntegralsSphere::give_dIij( double dJij[27], double mult, double norm_x[5],
415  double x[3] )
416 {
417  //dIij,1
418  dJij[0] = dJij[1] = dJij[2] = this->Iij_i( mult, norm_x, x, _x1_ ); //I11,1; I12,1; I13,1
419  dJij[3] = dJij[4] = dJij[5] = dJij[0]; //I21,1; I22,1; I23,1
420  dJij[6] = dJij[7] = dJij[8] = dJij[0]; //I31,1; I32,1; I33,1
421  //dIij,2
422  dJij[9] = dJij[10] = dJij[11] = this->Iij_i( mult, norm_x, x, _x2_ ); //I11,2; I12,2; I13,2
423  dJij[12] = dJij[13] = dJij[14] = dJij[9]; //I21,2; I22,2; I23,2
424  dJij[15] = dJij[16] = dJij[17] = dJij[9]; //I31,2; I32,2; I33,2
425  //dIij,3
426  dJij[18] = dJij[19] = dJij[20] = this->Iij_i( mult, norm_x, x, _x3_ ); //I11,3; I12,3; I13,3
427  dJij[21] = dJij[22] = dJij[23] = dJij[18]; //I21,3; I22,3; I23,3
428  dJij[24] = dJij[25] = dJij[26] = dJij[18]; //I31,3; I32,3; I33,3
429 
430  return;
431 }//end of function: give_dIij( )
432 
433 //********************************************************************************************************
434 // description: Function gives all second derivatives of Ferers-Dysons' integrals Ii
435 // last edit: 08. 05. 2010
436 //-------------------------------------------------------------------------------------------------------
437 // note: @ddJi[27] - table of elliptic integral derivatives to be calculated
438 // @mult - 4 * pi() * a^3
439 // @norm_x[5] - length of vector x and its powers norm_x = {x, x^3, x^5, x^7, x^9}
440 // @x[3] - coordinates of a point
441 //********************************************************************************************************
442 void eshelbySoluEllipticIntegralsSphere::give_ddIi( double ddJi[27], double mult, double norm_x[5],
443  double x[3] )
444 {
445  //dI1,ij
446  ddJi[0] = this->Ii_ij( mult, norm_x, x, _x1_, _x1_ ); //I1,11
447  ddJi[1] = this->Ii_ij( mult, norm_x, x, _x1_, _x2_ ); //I1,12
448  ddJi[2] = this->Ii_ij( mult, norm_x, x, _x1_, _x3_ ); //I1,13
449 
450  ddJi[3] = ddJi[1]; //I1,21
451  ddJi[4] = this->Ii_ij( mult, norm_x, x, _x2_, _x2_ ); //I1,22
452  ddJi[5] = this->Ii_ij( mult, norm_x, x, _x2_, _x3_ ); //I1,23
453 
454  ddJi[6] = ddJi[2]; //I1,31
455  ddJi[7] = ddJi[5]; //I1,32
456  ddJi[8] = this->Ii_ij( mult, norm_x, x, _x3_, _x3_ ); //I1,33
457 
458  //dI1,ij = dI2,ij = dI3,ij
459  ddJi[9] = ddJi[18] = ddJi[0]; //I2,11; I3,11
460  ddJi[10] = ddJi[19] = ddJi[1]; //I2,12; I3,12
461  ddJi[11] = ddJi[20] = ddJi[2]; //I2,13; I3,13
462 
463  ddJi[12] = ddJi[21] = ddJi[3]; //I2,21; I3,21
464  ddJi[13] = ddJi[22] = ddJi[4]; //I2,22; I3,22
465  ddJi[14] = ddJi[23] = ddJi[5]; //I2,23; I3,23
466 
467  ddJi[15] = ddJi[24] = ddJi[6]; //I2,31; I3,31
468  ddJi[16] = ddJi[25] = ddJi[7]; //I2,32; I3,32
469  ddJi[17] = ddJi[26] = ddJi[8]; //I2,33; I3,33
470 
471  return;
472 }//end of function: give_ddIi( )
473 
474 //********************************************************************************************************
475 // description: Function gives all second derivatives of Ferers-Dysons' integrals Iij
476 // last edit: 15. 06. 2010
477 //-------------------------------------------------------------------------------------------------------
478 // note: @ddJij[81] - table of elliptic integral derivatives to be calculated
479 // @mult - 4 * pi() * a^3
480 // @norm_x[5] - length of vector x and its powers norm_x = {x, x^3, x^5, x^7, x^9}
481 // @x[3] - coordinates of a point
482 //********************************************************************************************************
483 void eshelbySoluEllipticIntegralsSphere::give_ddIij( double ddJij[81], double mult, double norm_x[5],
484  double x[3] )
485 {
486  int j = 0;
487 
488  //dI11,ij
489  ddJij[0] = this->Iij_ij( mult, norm_x, x, _x1_, _x1_ ); //I11,11
490  ddJij[1] = this->Iij_ij( mult, norm_x, x, _x1_, _x2_ ); //I11,12
491  ddJij[2] = this->Iij_ij( mult, norm_x, x, _x1_, _x3_ ); //I11,13
492 
493  ddJij[3] = ddJij[1]; //I11,21
494  ddJij[4] = this->Iij_ij( mult, norm_x, x, _x2_, _x2_ ); //I11,22
495  ddJij[5] = this->Iij_ij( mult, norm_x, x, _x2_, _x3_ ); //I11,23
496 
497  ddJij[6] = ddJij[2]; //I11,31
498  ddJij[7] = ddJij[5]; //I11,32
499  ddJij[8] = this->Iij_ij( mult, norm_x, x, _x3_, _x3_ ); //I11,33
500 
501  //dI11,ij = dI12,ij = dI13,ij = dI21,ij = dI22,ij = dI23,ij = dI31,ij = dI32,ij = dI33,ij
502  for( int i = 1; i < 9; i++ ){
503  j = i * 9;
504  ddJij[j] = ddJij[0];
505  ddJij[j + 1] = ddJij[1];
506  ddJij[j + 2] = ddJij[2];
507 
508  ddJij[j + 3] = ddJij[3];
509  ddJij[j + 4] = ddJij[4];
510  ddJij[j + 5] = ddJij[5];
511 
512  ddJij[j + 6] = ddJij[6];
513  ddJij[j + 7] = ddJij[7];
514  ddJij[j + 8] = ddJij[8];
515  }//end of loop 'for: i'
516 
517  return;
518 }//end of function: give_ddIij( )
519 
520 //Complex numerical derivatives of Ferers-Dysons integrals:
521 //---------------------------------------------------------
522 
523 //********************************************************************************************************
524 // description: Function gives the first derivative of the integral Ii by using
525 // the complex differentiation
526 // last edit: 08. 07. 2010
527 //-------------------------------------------------------------------------------------------------------
528 // note: I1_i = I2_i = I3_i
529 // @mult - 4 * pi() * a^3
530 // @x[3] - coordinates of a point
531 // @direction - derivative direction (_x1_, _x2_, _x3_)
532 //********************************************************************************************************
533 std::complex<double> eshelbySoluEllipticIntegralsSphere::cIi_i( double mult, std::complex<double> x[3],
534  derivativeDirection direction )
535 {
536  int dir = direction - 1;
537  std::complex<double> cn2 = SQR(x[0]) + SQR(x[1]) + SQR(x[2]);
538 
539  return( -mult * x[dir]/pow( cn2, 2.5 ) );
540 }//end of function: cIi_i()
541 
542 //********************************************************************************************************
543 // description: Function gives the first derivative of the integral Iij by using
544 // the complex differentiation
545 // last edit: 08. 07. 2010
546 //-------------------------------------------------------------------------------------------------------
547 // note: @mult - 4 * pi() * a^3
548 // @x[3] - coordinates of a point
549 // @direction - derivative direction (_x1_, _x2_, _x3_)
550 //********************************************************************************************************
551 std::complex<double> eshelbySoluEllipticIntegralsSphere::cIij_i( double mult, std::complex<double> x[3],
552  derivativeDirection direction )
553 {
554  int dir = direction - 1;
555  std::complex<double> cn2 = SQR(x[0]) + SQR(x[1]) + SQR(x[2]);
556 
557  return( -mult * x[dir]/pow( cn2, 3.5 ) );
558 }//end of function: cIij_i()
559 
560 //********************************************************************************************************
561 // description: Function gives all first derivatives of Ferers-Dysons' integrals Ii by using
562 // the complex differentiation
563 // last edit: 08. 07. 2010
564 //-------------------------------------------------------------------------------------------------------
565 // note: @dJi[9] - table of elliptic integral derivatives to be calculated
566 // @mult - 4 * pi() * a^3
567 // @x[3] - coordinates of a point
568 //********************************************************************************************************
569 void eshelbySoluEllipticIntegralsSphere::give_cdIi( std::complex<double> dJi[13], double mult, double x[3] )
570 {
571  std::complex<double> cx[3] = { x[0], x[1], x[2] };
572 
573  this->update_cx( cx, _x1_ );
574  dJi[0] = this->cIi_i( mult, cx, _x1_ ); //I1,1
575 
576  this->update_cx( cx, _x2_ );
577  dJi[3] = this->cIi_i( mult, cx, _x1_ ); //I2,1
578  dJi[1] = dJi[4] = this->cIi_i( mult, cx, _x2_ ); //I1,2; I2,2
579 
580  this->update_cx( cx, _x3_ );
581  dJi[6] = this->cIi_i( mult, cx, _x1_ ); //I3,1
582  dJi[7] = this->cIi_i( mult, cx, _x2_ ); //I3,2
583  dJi[2] = dJi[5] = dJi[8] = this->cIi_i( mult, cx, _x3_ ); //I1,3; I2,3; I3,3
584 
585  return;
586 }//end of function: give_cdIi( )
587 
588 //********************************************************************************************************
589 // description: Function gives all first derivatives of Ferers-Dysons' integrals Iij by using
590 // the complex differentiation
591 // last edit: 08. 07. 2010
592 //-------------------------------------------------------------------------------------------------------
593 // note: @dJij[27] - table of elliptic integral derivatives to be calculated
594 // @mult - 4 * pi() * a^3
595 // @x[3] - coordinates of a point
596 //********************************************************************************************************
597 void eshelbySoluEllipticIntegralsSphere::give_cdIij( std::complex<double> dJij[27], double mult, double x[3] )
598 {
599  std::complex<double> cx[3] = { x[0], x[1], x[2] };
600 
601  this->update_cx( cx, _x1_ );
602  dJij[0] = this->cIij_i( mult, cx, _x1_ );
603  this->update_cx( cx, _x2_ );
604  dJij[1] = this->cIij_i( mult, cx, _x1_ );
605  dJij[9] = this->cIij_i( mult, cx, _x2_ );
606  this->update_cx( cx, _x3_ );
607  dJij[2] = this->cIij_i( mult, cx, _x1_ ); //I11,1; I12,1; I13,1
608  dJij[10] = this->cIij_i( mult, cx, _x2_ );
609  dJij[18] = this->cIij_i( mult, cx, _x3_ );
610 
611  //dIij,1
612  dJij[3] = dJij[4] = dJij[5] = dJij[0]; //I21,1; I22,1; I23,1
613  dJij[6] = dJij[7] = dJij[8] = dJij[0]; //I31,1; I32,1; I33,1
614  //dIij,2
615  dJij[11] = dJij[9]; //I11,2; I12,2; I13,2
616  dJij[12] = dJij[13] = dJij[14] = dJij[9]; //I21,2; I22,2; I23,2
617  dJij[15] = dJij[16] = dJij[17] = dJij[9]; //I31,2; I32,2; I33,2
618  //dIij,3
619  dJij[19] = dJij[20] = dJij[18]; //I11,3; I12,3; I13,3
620  dJij[21] = dJij[22] = dJij[23] = dJij[18]; //I21,3; I22,3; I23,3
621  dJij[24] = dJij[25] = dJij[26] = dJij[18]; //I31,3; I32,3; I33,3
622 
623  return;
624 }//end of function: give_cdIij( )
625 
626 //********************************************************************************************************
627 // description: Function updates vectors cx according the derivative direction
628 // last edit: 08. 07. 2010
629 //-------------------------------------------------------------------------------------------------------
630 // note: @cx[3] - complex coordinates of a point 'x' (initialized to its real counterparts)
631 // @direction - derivative direction (_x1_, _x2_, _x3_)
632 //********************************************************************************************************
633 void eshelbySoluEllipticIntegralsSphere::update_cx( std::complex<double> cx[3], derivativeDirection direction )
634 {
635  if( direction == _x1_ ){
636  cx[0].imag(_DIFF_H_ );
637  cx[1].imag(0);
638  cx[2].imag(0);
639  }
640  else if( direction == _x2_ ){
641  cx[0].imag(0);
642  cx[1].imag( _DIFF_H_);
643  cx[2].imag(0);
644  }
645  else if( direction == _x3_ ){
646  cx[0].imag(0);
647  cx[1].imag(0);
648  cx[2].imag(_DIFF_H_);
649  }
650  else{
651  _errorr( "update_cx: Invalid derivative direction");
652  }
653 
654  return ;
655 }//end of function: update_cx( )
656 
657 //********************************************************************************************************
658 // description: Function gives all second derivatives of Ferers-Dysons' integrals Ii by using
659 // the complex differentiation
660 // last edit: 08. 07. 2010
661 //-------------------------------------------------------------------------------------------------------
662 // note: @ddJi[27] - table of second derivatives of elliptic integrals to be calculated
663 // @dJi[9] - table of the first complex derivatives of elliptic integrals
664 //********************************************************************************************************
665 void eshelbySoluEllipticIntegralsSphere::give_cddIi( double ddJi[27], std::complex<double> dJi[13] )
666 {
667  //dI1,ij
668  ddJi[0] = std::imag( dJi[0] ) / _DIFF_H_; //I1,11
669  ddJi[1] = std::imag( dJi[3] ) / _DIFF_H_; //I1,12
670  ddJi[2] = std::imag( dJi[6] ) / _DIFF_H_; //I1,13
671 
672  ddJi[3] = ddJi[1]; //I1,21
673  ddJi[4] = std::imag( dJi[4] ) / _DIFF_H_; //I1,22
674  ddJi[5] = std::imag( dJi[7] ) / _DIFF_H_; //I1,23
675 
676  ddJi[6] = ddJi[2]; //I1,31
677  ddJi[7] = ddJi[5]; //I1,32
678  ddJi[8] = std::imag( dJi[8] ) / _DIFF_H_; //I1,33
679 
680  //dI1,ij = dI2,ij = dI3,ij
681  ddJi[9] = ddJi[18] = ddJi[0]; //I2,11; I3,11
682  ddJi[10] = ddJi[19] = ddJi[1]; //I2,12; I3,12
683  ddJi[11] = ddJi[20] = ddJi[2]; //I2,13; I3,13
684 
685  ddJi[12] = ddJi[21] = ddJi[3]; //I2,21; I3,21
686  ddJi[13] = ddJi[22] = ddJi[4]; //I2,22; I3,22
687  ddJi[14] = ddJi[23] = ddJi[5]; //I2,23; I3,23
688 
689  ddJi[15] = ddJi[24] = ddJi[6]; //I2,31; I3,31
690  ddJi[16] = ddJi[25] = ddJi[7]; //I2,32; I3,32
691  ddJi[17] = ddJi[26] = ddJi[8]; //I2,33; I3,33
692 
693  return;
694 }//end of function: give_cddIi( )
695 
696 //********************************************************************************************************
697 // description: Function gives all second derivatives of Ferers-Dysons' integrals Iij by using
698 // the complex differentiation
699 // last edit: 08. 07. 2010
700 //-------------------------------------------------------------------------------------------------------
701 // note: @ddJij[81] - table of second derivatives of elliptic integrals to be calculated
702 // @dJij[27] - table of the first complex derivatives of elliptic integrals
703 //********************************************************************************************************
704 void eshelbySoluEllipticIntegralsSphere::give_cddIij( double ddJij[81], std::complex<double> dJij[27] )
705 {
706  int j = 0;
707 
708  //dI11,ij
709  ddJij[0] = std::imag( dJij[0] ) / _DIFF_H_; //I11,11
710  ddJij[1] = std::imag( dJij[1] ) / _DIFF_H_; //I11,12
711  ddJij[2] = std::imag( dJij[2] ) / _DIFF_H_; //I11,13
712 
713  ddJij[3] = ddJij[1]; //I11,21
714  ddJij[4] = std::imag( dJij[9] ) / _DIFF_H_; //I11,22
715  ddJij[5] = std::imag( dJij[10] ) / _DIFF_H_; //I11,23
716 
717  ddJij[6] = ddJij[2]; //I11,31
718  ddJij[7] = ddJij[5]; //I11,32
719  ddJij[8] = std::imag( dJij[18] ) / _DIFF_H_;; //I11,33
720 
721  //dI11,ij = dI12,ij = dI13,ij = dI21,ij = dI22,ij = dI23,ij = dI31,ij = dI32,ij = dI33,ij
722  for( int i = 1; i < 9; i++ ){
723  j = i * 9;
724  ddJij[j] = ddJij[0];
725  ddJij[j + 1] = ddJij[1];
726  ddJij[j + 2] = ddJij[2];
727 
728  ddJij[j + 3] = ddJij[3];
729  ddJij[j + 4] = ddJij[4];
730  ddJij[j + 5] = ddJij[5];
731 
732  ddJij[j + 6] = ddJij[6];
733  ddJij[j + 7] = ddJij[7];
734  ddJij[j + 8] = ddJij[8];
735  }//end of loop 'for: i'
736 
737  return;
738 }//end of function: give_cddIij( )
739 // Lambda computed according to Mura p. 86.
740 double eshelbySoluEllipticIntegralsSphere::getLambda(const double a[3], double x1, double x2, double x3)
741 {
742  // The cubic equation for lambda simplifies to
743  return SQR(x1) + SQR(x2) + SQR(x3) - SQR(a[0]);
744 }
745 
746 
747 } // end of namespace mumech
748 
749 /*end of file*/
std::complex< double > cIij_i(double mult, std::complex< double > x[3], derivativeDirection direction)
double loc_x[3]
Local coordinates of a point.
Definition: matrix.h:137
void give_cdIij(std::complex< double > dJij[13], double mult, double x[3])
const Problem * P
problem description
Definition: inclusion.h:69
double Iij_i(double mult, double norm_x[5], double x[3], derivativeDirection direction)
#define PI
Definition: macros.h:71
const InclusionRecord3D * I
Definition: esei.h:45
double Iij_ij(double mult, double norm_x[5], double x[3], derivativeDirection direction_1, derivativeDirection direction_2)
void give_cddIi(double ddJi[27], std::complex< double > dJi[13])
#define NUM_PERTURB
Definition: types.h:732
derivativeDirection
Definition: types.h:208
void giveDerivativesOfEllipticIntegrals(Point *point, bool intpoint)
Function gives the values of Ferers-Dyson&#39;s elliptic integral derivatives of the inclusion this->I...
Class eshelbySoluEllipticIntegrals.
The header file of usefull macros.
void getPerturbatedLambdas(double *lambdas, const double loc_x[3])
Helper function.
Definition: esei.cpp:51
Collection of the functions of basic manipulations, some of them can be used instead of their counter...
double ddJij[81]
Second derivatives of elliptic integral Iij.
Definition: matrix.h:145
DiffTypes give_diffType(void) const
Give type of ...
Definition: problem.h:336
Single Point data structure - contribution from Single inclusion.
Definition: matrix.h:133
double ndiff_1
derivative step for the first derivations
Definition: inclusion.h:108
std::complex< double > cIi_i(double mult, std::complex< double > x[3], derivativeDirection direction)
#define _DIFF_H_
Definition: types.h:666
void giveEllipticIntegrals(double J[13], double lambda, bool intpoint)
Function gives the values of Ferers-Dyson&#39;s elliptic integrals of the inclusion this->I.
Definition: esei_Sphere.cpp:48
double Ii_i(double mult, double norm_x[5], double x[3], derivativeDirection direction)
#define SQR(a)
Definition: macros.h:97
double dJi[9]
First derivatives of elliptic integral Ii.
Definition: matrix.h:142
void give_cdIi(std::complex< double > dJi[13], double mult, double x[3])
double * a
Inclusion semiaxes&#39; dimensions in global arrangement.
Definition: inclusion.h:76
double ddJi[27]
Second derivatives of elliptic integral Ii.
Definition: matrix.h:144
#define _errorr(_1)
Definition: gelib.h:160
void give_cddIij(double ddJij[81], std::complex< double > dJij[27])
void give_dIij(double dJij[27], double mult, double norm_x[5], double x[3])
double getLambda(const double a[3], double x1, double x2, double x3)
Returns lambda for a given point (x1, x2, x3)
double dJij[27]
First derivatives of elliptic integral Iij.
Definition: matrix.h:143
void give_ddIi(double ddJi[27], double mult, double norm_x[5], double x[3])
double Ii_ij(double mult, double norm_x[5], double x[3], derivativeDirection direction_1, derivativeDirection direction_2)
void give_dIi(double dJi[13], double mult, double norm_x[5], double x[3])
Class eshelbySoluEllipticIntegralsSphere.
void give_ddIij(double ddJij[81], double mult, double norm_x[5], double x[3])
void update_cx(std::complex< double > cx[3], derivativeDirection direction)
Class Problem.