muMECH  1.0
eshelbySoluLambda.cpp
Go to the documentation of this file.
1 //********************************************************************************************************
2 // code: ### ### ##### #### ## ##
3 // ## ## ######## ## ## ## ## ##
4 // ## ## ## ## ## ### ## ######
5 // ## ## ## ## ## ## ## ## ##
6 // ##### ## ## ##### #### ## ##
7 // ##
8 //
9 // name: eshelbySoluLambda.cpp
10 // description: source file of the functions calculating the values of 'lambda' parameter and
11 // its derivatives
12 // author(s): Jan Novak
13 
14 // last edit: 02. 08. 2010
15 // language: C, C++
16 // license: This program is free software; you can redistribute it and/or modify
17 // it under the terms of the GNU Lesser General Public License as published by
18 // the Free Software Foundation; either version 2 of the License, or
19 // (at your option) any later version.
20 //
21 // This program is distributed in the hope that it will be useful,
22 // but WITHOUT ANY WARRANTY; without even the implied warranty of
23 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 // GNU Lesser General Public License for more details.
25 //
26 // You should have received a copy of the GNU Lesser General Public License
27 // along with this program; if not, write to the Free Software
28 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 //********************************************************************************************************
30 
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <math.h>
34 #include <cmath>
35 
36 #include "macros.h"
37 #include "polynomialRootSolution.h"
38 #include "eshelbySoluLambda.h"
39 
40 namespace mumech {
41 
42 //********************************************************************************************************
43 // description: constructor
44 // last edit: 07. 09. 2009
45 //********************************************************************************************************
47 
48 //********************************************************************************************************
49 // description: destructor
50 // last edit: 07. 09. 2009
51 //********************************************************************************************************
53 
54 
55 
56 //********************************************************************************************************
57 // PUBLIC FUNCTIONS
58 //********************************************************************************************************
59 
60 
61 //********************************************************************************************************
62 // description: Function gives the lambda value
63 // last edit: 12. 05. 2010
64 //-------------------------------------------------------------------------------------------------------
65 // note: Solution adopted from Toshio Mura's book (1982), page(s) 72-73
66 // @a[3] - dimensions of an ellipsoid (a1, a2, a3 semi-axies dimensions)
67 // @x[3] - coordinates of a point
68 // @shape - inclusion shape
69 //********************************************************************************************************
70 double eshelbySoluLambda :: giveLambda (const double a[3], const double x[3], InclusionGeometry shape)
71 {
72  return eshelbySoluLambda :: giveLambda(a, x[0], x[1], x[2], shape);
73 }
74 
75 // Overloaded giveLambda method
76 double eshelbySoluLambda :: giveLambda (const double a[3], const double x1, const double x2, const double x3, InclusionGeometry shape)
77 {
78  double lambda;
79  if (shape == IS_ELLIPSOID || shape == IS_OBLATE_SPHEROID || shape == IS_PROLATE_SPHEROID) { // || shape == IS_ELLIPTIC_CYLINDER || shape == IS_CYLINDER){
80 // if( ( SQR( x[0]/a[0]) + SQR( x[1]/a[1]) + SQR( x[2]/a[2]) ) <= ( 1. + MACHINE_EPS ) ){
81 // lambda = 0.;//patch: 23. 09. 2009
82 // }
83 // else{
84  double a1 = a[0], a2 = a[1], a3 = a[2],
85  aa = SQR( a1 ) + SQR( a2 ) + SQR( a3 ) - SQR( x1 ) - SQR( x2 ) - SQR( x3 ),
86  b = SQR( a1 ) * SQR( a2 ) + SQR( a1 ) * SQR( a3 ) + SQR( a2 ) * SQR( a3 ) -
87  SQR( a2 ) * SQR( x1 ) - SQR( a3 ) * SQR( x1 ) - SQR( a1 ) * SQR( x2 ) -
88  SQR( a3 ) * SQR( x2 ) - SQR( a1 ) * SQR( x3 ) - SQR( a2 ) * SQR( x3 ),
89  c = SQR( a1 ) * SQR( a2 ) * SQR( a3 ) - SQR( a2 ) * SQR( a3 ) * SQR( x1 ) -
90  SQR( a1 ) * SQR( a3 ) * SQR( x2 ) - SQR( a1 ) * SQR( a2 ) * SQR( x3 );
91  std::complex<double> roots[3];
92 
93  polynomialRootSolution giveRoots;
94 
95  //calculation of generally complex roots
96  giveRoots.GetCubicPolyRoots( aa, b, c, roots );
97  //elimination of complex roots
98  roots[1].real(( ABS( imag(roots[1]) ) > MACHINE_EPS )? -INFTY : real(roots[1]));
99  roots[2].real(( ABS( imag(roots[2]) ) > MACHINE_EPS )? -INFTY : real(roots[2]));
100 
101  lambda = ( MAX( MAX( real(roots[0]), real(roots[1]) ), real(roots[2]) ) );
102  // }
103  }
104  else if( shape == IS_SPHERE ){
105  //this is most likely not necessary to evaluate in the case of spherical inclusion
106  lambda = SQR( x1 ) + SQR( x2 ) + SQR( x3 ) - SQR( a[0] );
107  }
108  else{
109  _errorr( "giveLambda: unknown inclusion shape\n");
110  }
111 
112  return lambda;
113 }//end of function: giveLambda( )
114 
115 //********************************************************************************************************
116 // description: Function gives generally complex lambda value
117 // last edit: 02. 08. 2010
118 //-------------------------------------------------------------------------------------------------------
119 // note: Solution adopted from Toshio Mura's book (1982), page(s) 72-73
120 // @a[3] - dimensions of an ellipsoid (a1, a2, a3 semi-axies dimensions)
121 // @x[3] - coordinates of a point
122 // @shape - inclusion shape
123 //********************************************************************************************************
124 std::complex<double> eshelbySoluLambda::giveLambda( const double a[3], std::complex<double> x[3], InclusionGeometry shape )
125 {
126  std::complex<double> lambda;
127 
128  if (shape == IS_ELLIPSOID){
129  double a1 = a[0], a2 = a[1], a3 = a[2];
130  std::complex<double> x1 = x[0], x2 = x[1], x3 = x[2],
131  aa = SQR( a1 ) + SQR( a2 ) + SQR( a3 ) - SQR( x1 ) - SQR( x2 ) - SQR( x3 ),
132  b = SQR( a1 ) * SQR( a2 ) + SQR( a1 ) * SQR( a3 ) + SQR( a2 ) * SQR( a3 ) -
133  SQR( a2 ) * SQR( x1 ) - SQR( a3 ) * SQR( x1 ) - SQR( a1 ) * SQR( x2 ) -
134  SQR( a3 ) * SQR( x2 ) - SQR( a1 ) * SQR( x3 ) - SQR( a2 ) * SQR( x3 ),
135  c = SQR( a1 ) * SQR( a2 ) * SQR( a3 ) - SQR( a2 ) * SQR( a3 ) * SQR( x1 ) -
136  SQR( a1 ) * SQR( a3 ) * SQR( x2 ) - SQR( a1 ) * SQR( a2 ) * SQR( x3 ),
137  roots[3];
138  polynomialRootSolution giveRoots;
139 
140  //calculation of generally complex roots
141  giveRoots.GetCubicPolyRoots( aa, b, c, roots );
142  //seeking for maximum root
143  lambda = ( CReMAX( CReMAX( roots[0], roots[1] ), roots[2] ) );
144  }
145  else if( shape == IS_SPHERE ){
146  //this is most likely not necessary to evaluate in the case of spherical inclusion
147  lambda = SQR( x[0] ) + SQR( x[1] ) + SQR( x[2] ) - SQR( a[0] );
148  }
149  else{
150  _errorr( "giveLambda: unknown inclusion shape\n");
151  }
152 
153  return lambda;
154 }//end of function: giveLambda( )
155 
157 
158 //********************************************************************************************************
159 // description: Function gives the first or seccond derivative of Lambda
160 // last edit: 07. 09. 2009
161 // note: Solution adopted from Toshio Mura's book (1982), page(s) 73
162 // @a[3] - dimensions of an ellipsoid (a1, a2, a3 semi-axies dimensions)
163 // @x[3] - coordinates of a point
164 // @lambda - lambda parameter calculated according 'giveLambda()' function
165 // @direction - derivative direction
166 //********************************************************************************************************
167 double eshelbySoluLambda::giveLambdaDerivative( const double a[3], const double x[3], double lambda,
168  derivativeDirection direction )
169 {
170  double derivative = 0.;
171 
172  switch( direction ){
173  case _x1_ :
174  derivative = this->giveLambdaFirstDerivative( a, x, lambda, _x1_ );
175  break;
176  case _x1x1_ :
177  derivative = this->giveLambdaSeccondDerivative( a, x, lambda, _x1x1_ );
178  break;
179  case _x1x2_ :
180  derivative = this->giveLambdaSeccondDerivative( a, x, lambda, _x1x2_ );
181  break;
182  case _x1x3_ :
183  derivative = this->giveLambdaSeccondDerivative( a, x, lambda, _x1x3_ );
184  break;
185  case _x2_ :
186  derivative = this->giveLambdaFirstDerivative( a, x, lambda, _x2_ );
187  break;
188  case _x2x1_ :
189  derivative = this->giveLambdaSeccondDerivative( a, x, lambda, _x2x1_ );
190  break;
191  case _x2x2_ :
192  derivative = this->giveLambdaSeccondDerivative( a, x, lambda, _x2x2_ );
193  break;
194  case _x2x3_ :
195  derivative = this->giveLambdaSeccondDerivative( a, x, lambda, _x2x3_ );
196  break;
197  case _x3_ :
198  derivative = this->giveLambdaFirstDerivative( a, x, lambda, _x3_ );
199  break;
200  case _x3x1_ :
201  derivative = this->giveLambdaSeccondDerivative( a, x, lambda, _x3x1_ );
202  break;
203  case _x3x2_ :
204  derivative = this->giveLambdaSeccondDerivative( a, x, lambda, _x3x2_ );
205  break;
206  case _x3x3_ :
207  derivative = this->giveLambdaSeccondDerivative( a, x, lambda, _x3x3_ );
208  break;
209  default:
210  _errorr( "giveLambdaDerivative: invalid derivative direction ");
211  break;
212  }//end of switch: direction
213 
214  return( derivative );
215 }//end of function: giveLambdaDerivative()
216 
217 //********************************************************************************************************
218 // description: Function gives the first or seccond derivative of Lambda
219 // last edit: 07. 09. 2009
220 // note: Solution adopted from Toshio Mura's book (1982), page(s) 73
221 // @a[3] - dimensions of an ellipsoid (a1, a2, a3 semi-axies dimensions)
222 // @x[3] - coordinates of a point
223 // @lambda - lambda parameter calculated according 'giveLambda()' function
224 // @direction_1 - direction of the first derivative: _x1_, _x2_, _x3_
225 // @direction_2 - direction of the seccond derivative: _x1_, _x2_, _x3_ or must be '_empty_'
226 // to return the first derivative according 'direction_1' only
227 //********************************************************************************************************
228 double eshelbySoluLambda::giveLambdaDerivative( const double a[3], const double x[3], double lambda,
229  derivativeDirection direction_1,
230  derivativeDirection direction_2 )
231 {
232  double derivative = 0.;
233 
234  if( direction_1 == _x1_ && direction_2 == _empty_ ){
235  derivative = this->giveLambdaFirstDerivative( a, x, lambda, _x1_ );
236  }
237  else if( direction_1 == _x1_ && direction_2 == _x1_ ){
238  derivative = this->giveLambdaSeccondDerivative( a, x, lambda, _x1x1_ );
239  }
240  else if( direction_1 == _x1_ && direction_2 == _x2_ ){
241  derivative = this->giveLambdaSeccondDerivative( a, x, lambda, _x1x2_ );
242  }
243  else if( direction_1 == _x1_ && direction_2 == _x3_ ){
244  derivative = this->giveLambdaSeccondDerivative( a, x, lambda, _x1x3_ );
245  }
246  else if( direction_1 == _x2_ && direction_2 == _empty_ ){
247  derivative = this->giveLambdaFirstDerivative( a, x, lambda, _x2_ );
248  }
249  else if( direction_1 == _x2_ && direction_2 == _x1_ ){
250  derivative = this->giveLambdaSeccondDerivative( a, x, lambda, _x2x1_ );
251  }
252  else if( direction_1 == _x2_ && direction_2 == _x2_ ){
253  derivative = this->giveLambdaSeccondDerivative( a, x, lambda, _x2x2_ );
254  }
255  else if( direction_1 == _x2_ && direction_2 == _x3_ ){
256  derivative = this->giveLambdaSeccondDerivative( a, x, lambda, _x2x3_ );
257  }
258  else if( direction_1 == _x3_ && direction_2 == _empty_ ){
259  derivative = this->giveLambdaFirstDerivative( a, x, lambda, _x3_ );
260  }
261  else if( direction_1 == _x3_ && direction_2 == _x1_ ){
262  derivative = this->giveLambdaSeccondDerivative( a, x, lambda, _x3x1_ );
263  }
264  else if( direction_1 == _x3_ && direction_2 == _x2_ ){
265  derivative = this->giveLambdaSeccondDerivative( a, x, lambda, _x3x2_ );
266  }
267  else if( direction_1 == _x3_ && direction_2 == _x3_ ){
268  derivative = this->giveLambdaSeccondDerivative( a, x, lambda, _x3x3_ );
269  }
270  else{
271  _errorr( "giveLambdaDerivative: invalid derivative direction ");
272  }
273 
274  return( derivative );
275 }//end of function: giveLambdaDerivative()
276 
277 //********************************************************************************************************
278 // description: Function gives the first complex derivative of Lambda
279 // last edit: 02. 08. 2010
280 // note: Solution adopted from Toshio Mura's book (1982), page(s) 73
281 // @a[3] - dimensions of an ellipsoid (a1, a2, a3 semi-axies dimensions)
282 // @x[3] - coordinates of a point
283 // @lambda - lambda parameter calculated according 'giveLambda()' function
284 // @direction - derivative direction: _x1_, _x2_, _x3_
285 //********************************************************************************************************
286 std::complex<double> eshelbySoluLambda::c_dLambda( const double a[3], std::complex<double> x[3], std::complex<double> lambda,
287  derivativeDirection direction )
288 {
289  int dir = direction - 1;
290 
291  return( 2. * x[dir] / ( ( SQR( a[dir] ) + lambda ) * ( SQR( x[0] )/SQR( SQR( a[0] ) + lambda ) +
292  SQR( x[1] )/SQR( SQR( a[1] ) + lambda ) +
293  SQR( x[2] )/SQR( SQR( a[2] ) + lambda ) ) ) );
294 }//end of function: c_dLambda()
295 
296 //********************************************************************************************************
297 // PROTECTED FUNCTIONS
298 //********************************************************************************************************
299 
300 
301 //********************************************************************************************************
302 // description: Function gives the first derivative of Lambda
303 // last edit: 07. 09. 2009
304 // note: Solution adopted from Toshio Mura's book (1982), page(s) 73
305 // @a[3] - dimensions of an ellipsoid (a1, a2, a3 semi-axies dimensions)
306 // @x[3] - coordinates of a point
307 // @lambda - lambda parameter calculated according 'giveLambda()' function
308 // @direction - derivative direction: _x1_, _x2_, _x3_
309 //********************************************************************************************************
310 double eshelbySoluLambda::giveLambdaFirstDerivative( const double a[3], const double x[3], double lambda,
311  derivativeDirection direction )
312 {
313  double a1 = a[0], a2 = a[1], a3 = a[2], x1 = x[0], x2 = x[1], x3 = x[2], derivative = 0.,
314  var_a = 0, var_x = 0;
315 
316  //variable initiations
317  switch( direction ){
318  case _x1_ :
319  var_x = x1;
320  var_a = a1;
321  break;
322  case _x2_ :
323  var_x = x2;
324  var_a = a2;
325  break;
326  case _x3_ :
327  var_x = x3;
328  var_a = a3;
329  break;
330  default:
331  _errorr( "giveLambdaFirstDerivative: invalid derivative direction ");
332  break;
333  }//end of switch: direction
334 
335  derivative = 2. * var_x / ( ( SQR( var_a ) + lambda ) * ( SQR( x1 )/SQR( SQR( a1 ) + lambda ) +
336  SQR( x2 )/SQR( SQR( a2 ) + lambda ) +
337  SQR( x3 )/SQR( SQR( a3 ) + lambda ) ) );
338  return( derivative );
339 }//end of function: giveLambdaFirstDerivative()
340 
341 //********************************************************************************************************
342 // description: Function gives the seccond derivative of Lambda
343 // last edit: 08. 09. 2009
344 // note: Solution adopted from Toshio Mura's book (1982), page(s) 73
345 // @a[3] - dimensions of an ellipsoid (a1, a2, a3 semi-axies dimensions)
346 // @x[3] - coordinates of a point
347 // @lambda - lambda parameter calculated according 'giveLambda()' function
348 // @dLa - array with first derivatives of lambda
349 // @direction - derivative direction: _xixj_; i,j = 1,2,3
350 //********************************************************************************************************
351 double eshelbySoluLambda::giveLambdaSeccondDerivative( const double a[3], const double x[3], double lambda,
352  derivativeDirection direction )
353 {
354  double ai = a[0], aj = a[1], ak = a[2], xi = x[0], xj = x[1], xk = x[2], derivative = 0., dummy = 0.,
355  dLa[3] = { this->giveLambdaFirstDerivative( a, x, lambda, _x1_ ),
356  this->giveLambdaFirstDerivative( a, x, lambda, _x2_ ),
357  this->giveLambdaFirstDerivative( a, x, lambda, _x3_ ) };
358  double dLai = dLa[0], dLaj = dLa[1], dLak = dLa[2];
359  derivativeDirection dirType;
360 
361  //variable initiations
362  switch( direction ){
363  case _x1x1_ :
364  dirType = _HOMOGENEOUS_;
365  //default set-up
366  break;
367  case _x1x2_ :
368  dirType = _MIXED_;
369  //default set-up
370  break;
371  case _x1x3_ :
372  dirType = _MIXED_;
373  SWAP( dLaj, dLak, dummy );
374  SWAP( xj, xk, dummy );
375  SWAP( aj, ak, dummy );
376  break;
377  case _x2x1_ :
378  dirType = _MIXED_;
379  //default set-up
380  break;
381  case _x2x2_ :
382  dirType = _HOMOGENEOUS_;
383  SWAP( dLai, dLaj, dummy );
384  SWAP( xi, xj, dummy );
385  SWAP( ai, aj, dummy );
386  break;
387  case _x2x3_ :
388  dirType = _MIXED_;
389  SWAP( dLai, dLak, dummy );
390  SWAP( xi, xk, dummy );
391  SWAP( ai, ak, dummy );
392  break;
393  case _x3x1_ :
394  dirType = _MIXED_;
395  SWAP( dLaj, dLak, dummy );
396  SWAP( xj, xk, dummy );
397  SWAP( aj, ak, dummy );
398  break;
399  case _x3x2_ :
400  dirType = _MIXED_;
401  SWAP( dLai, dLak, dummy );
402  SWAP( xi, xk, dummy );
403  SWAP( ai, ak, dummy );
404  break;
405  case _x3x3_ :
406  dirType = _HOMOGENEOUS_;
407  SWAP( dLai, dLak, dummy );
408  SWAP( xi, xk, dummy );
409  SWAP( ai, ak, dummy );
410  break;
411  default:
412  _errorr( "giveLambdaSeccondDerivative: invalid derivative direction ");
413  break;
414  }//end of switch: direction
415 
416  //homogeneous or mixed derivative formula
417  if( dirType == _MIXED_ ){
418  derivative =
419  ( -2. * xi * dLaj / SQR( SQR( ai ) + lambda )
420  - 2. * xj * dLai / SQR( SQR( aj ) + lambda )
421  + 2. * SQR( xi ) * dLai * dLaj / CUB( SQR( ai ) + lambda )
422  + 2. * SQR( xj ) * dLai * dLaj / CUB( SQR( aj ) + lambda )
423  + 2. * SQR( xk ) * dLai * dLaj / CUB( SQR( ak ) + lambda ) )
424  /
425  ( SQR( x[0] )/SQR( SQR( a[0] ) + lambda ) +
426  SQR( x[1] )/SQR( SQR( a[1] ) + lambda ) +
427  SQR( x[2] )/SQR( SQR( a[2] ) + lambda ) );
428  }
429  else if( dirType == _HOMOGENEOUS_ ){
430  derivative =
431  ( 2. / ( SQR( ai ) + lambda )
432  - 4. * xi * dLai / SQR( SQR( ai ) + lambda )
433  + 2. * SQR( xi ) * SQR( dLai ) / CUB( SQR( ai ) + lambda )
434  + 2. * SQR( xj ) * SQR( dLai ) / CUB( SQR( aj ) + lambda )
435  + 2. * SQR( xk ) * SQR( dLai ) / CUB( SQR( ak ) + lambda ) )
436  /
437  ( SQR( x[0] ) / SQR( SQR( a[0] ) + lambda ) +
438  SQR( x[1] ) / SQR( SQR( a[1] ) + lambda ) +
439  SQR( x[2] ) / SQR( SQR( a[2] ) + lambda ) );
440  }else ;
441 
442  return( derivative );
443 }//end of function: giveLambdaSeccondDerivative()
444 
445 
446 } // end of namespace mumech
447 
448 /*end of file*/
Class polynomialRootSolution collects functions calculating the roots of polynomial functions...
#define MAX(a, b)
Definition: macros.h:101
std::complex< double > * GetCubicPolyRoots(double a, double b, double c, std::complex< double > *roots)
Function gives the analitical solution of cubic furmula of the real coefficients a, b, c x^3 + ax^2 + bx + c = 0.
double giveLambdaFirstDerivative(const double a[3], const double x[3], double lambda, derivativeDirection direction)
#define CReMAX(a, b)
Definition: macros.h:110
derivativeDirection
Definition: types.h:208
double giveLambdaDerivative(const double a[3], const double x[3], double lambda, derivativeDirection direction)
#define CUB(a)
Definition: macros.h:98
The header file of usefull macros.
#define ABS(a)
Definition: macros.h:118
static double giveLambda(const double a[3], const double x[3], InclusionGeometry shape)
#define SQR(a)
Definition: macros.h:97
#define _errorr(_1)
Definition: gelib.h:160
InclusionGeometry
Inclusion shapes&#39; type.
Definition: types.h:161
double giveLambdaSeccondDerivative(const double a[3], const double x[3], double lambda, derivativeDirection direction)
std::complex< double > c_dLambda(const double a[3], std::complex< double > x[3], std::complex< double > lambda, derivativeDirection direction)
#define MACHINE_EPS
Definition: macros.h:68
#define SWAP(a, b, dummy)
Definition: macros.h:94
Class polynomialRootSolution collects functions calculating the roots of polynomial functions...
#define INFTY
Definition: macros.h:143