muMECH  1.0
esei_EllipticCylinder.cpp
Go to the documentation of this file.
1 //********************************************************************************************************
2 // code: ### ### ##### #### ## ##
3 // ## ## ######## ## ## ## ## ##
4 // ## ## ## ## ## ### ## ######
5 // ## ## ## ## ## ## ## ## ##
6 // ##### ## ## ##### #### ## ##
7 // ##
8 //
9 // name: eshelbySoluEllipticIntegralsEllipticCylinder.cpp
10 // author(s): Jan Novak, Tomas Janda
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_EllipticCylinder.h"
35 #include "eshelbySoluLambda.h"
36 #include "legendreIntegrals.h"
37 #include "elementaryFunctions.h"
38 #include "inclusion.h"
39 
40 
41 namespace mumech {
42 
43 
44 // Function gives the values of Ferers-Dysons integrals
45 // Last edit: 14-Jan-2014
46 void eshelbySoluEllipticIntegralsEllipticCylinder::giveEllipticIntegrals(double J[13], double lambda, bool intpoint)
47 {
48  // Elliptic cylinder: a1 > a2, a3 -> infinity
49  if (I->a[0] <= I->a[1])
50  {
51  _warningg( "Values of semiaxes do not fit the condition for elliptic cylinder (a1 > a2, a3 is ignored). " );
52  std::cout << "a1, a2, a3 = " << I->a[0] << ", " << I->a[1] << ", " << I->a[2];
53  }
54 
55  double a1 = I->a[1];
56  double a2 = I->a[2];
57  // a3 is assumed to be infinite.
58 
59  CleanVector(J, 13);
60 
61  J[0] = 0.;
62 
63  J[1] = 0.0; // I1
64  J[2] = this->I2(a1, a2, lambda); // I2
65  J[3] = this->I3(a1, a2, lambda); // I3
66 
67  // (Order changed due to sequential evaluation)
68  J[4] = 0.0; // I11
69  J[5] = 0.0; // I12
70  J[6] = 0.0; // I13
71 
72  J[7] = 0.0; // I21
73  J[9] = this->I23(a1, a2, J[2], J[3]); // I23
74  J[8] = this->I22(a1, J[2], J[3], J[9], lambda); // I22
75 
76  J[10] = 0.0; // I31
77  J[11] = J[9]; // I32
78  J[12] = this->I33(a2, J[2], J[3], J[9], lambda); // I33
79 
80 #ifdef TOM_DEBUG
81  if (log)
82  {
83  std::cout << "J integrals" << std::endl;
84  for (int i = 0; i < 13; i++)
85  std::cout << "J[" << i << "] = " << J[i] << std::endl;
86  std::cout << std::endl;
87  }
88 #endif
89 }
90 
91 // Function gives the derivatives of Ferers-Dysons integrals
92 // Last edit: 14-Jan-2014
93 // Flat shapes has zero drtivatives
95 {
96  //if (point->position == PPF_INT_POINT) {
97  // CleanVector( point->dJi, 9 );
98  // CleanVector( point->dJij, 27 );
99  // CleanVector( point->ddJi, 27 );
100  // CleanVector( point->ddJij, 81 );
101  //}
102  //else if (point->position == PPF_EXT_POINT) {
103  // NUMERICAL DERIVATIVES (using REAL ARGUMENTS)
104 
105  double ndiff = I->ndiff_1;
106 
107  // Get perturbated points and their lambdas
108  double lambdas[NUM_PERTURB];
109  this->getPerturbatedLambdas(lambdas, point->loc_x);
110 
111  // Create and fill a two dimensional array containing values of J-integrals at perturbated points.
112  const int NUM_ELLIP_INT = 13;
113  double J_pert[NUM_PERTURB][NUM_ELLIP_INT]; // All perturbations of all elliptical integrals.
114 
115  this->log = false;
116  for (int i = 0; i < NUM_PERTURB; i++) // For each perturbated point
117  this->giveEllipticIntegrals(J_pert[i], lambdas[i], intpoint); // Get elliptical integrals for lambda of perturbated point.
118  this->log = true;
119 
120  // Compute numerial derivatives of first and second order of J_i integrals.
121  for (int i = 0; i < 3; i++) // For each elliptic integral Ji
122  {
123  // See types.c, section "Derivatives of Ferers-Dysons' integrals".
124  // Ji_j = dJi[3*i+j-4], i,j=1..3.
125  //point->dJi[3*i] = (J_pert[_Xp_][i+1] - J_pert[_Xm_][i+1]) / (2.0 * ndiff);
126  point->dJi[3*i+1] = (J_pert[_Yp_][i+1] - J_pert[_Ym_][i+1]) / (2.0 * ndiff);
127  point->dJi[3*i+2] = (J_pert[_Zp_][i+1] - J_pert[_Zm_][i+1]) / (2.0 * ndiff);
128 
129  // See types.c, section "Derivatives of Ferers-Dysons' integrals".
130  // Ji_jk = ddJi[9*i+3*j+k-13], i,j,k=1..3.
131  //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
132  //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)
133  //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);
134 
135  //point->ddJi[9*i+3] = point->ddJi[9*i+1];
136  point->ddJi[9*i+4] = (J_pert[_Yp_][i+1] - 2.0 * J_pert[_CENTER_][i+1] + J_pert[_Ym_][i+1]) / (ndiff * ndiff);
137  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);
138 
139  //point->ddJi[9*i+6] = (J_pert[_XpZp_][i+1] - J_pert[_XpZm_][i+1] - J_pert[_XmZp_][i+1] + J_pert[_XmZm_][i+1]) / (4.0*ndiff*ndiff);
140  point->ddJi[9*i+7] = point->ddJi[9*i+5];
141  point->ddJi[9*i+8] = (J_pert[_Zp_][i+1] - 2.0 * J_pert[_CENTER_][i+1] + J_pert[_Zm_][i+1]) / (ndiff * ndiff);
142  }
143 
144  // Compute numerial derivatives of first and second order of J_ij integrals.
145  for (int i = 0; i < 9; i++) // For each elliptic integral Jij
146  {
147  // See types.c, section "Derivatives of Ferers-Dysons' integrals".
148  // Jij_k = dJij[9*k+3*i+j-13], i,j,k=1..3.
149  point->dJij[i] = (J_pert[_Xp_][i+4] - J_pert[_Xm_][i+4]) / (2.0 * ndiff);
150  point->dJij[i+9] = (J_pert[_Yp_][i+4] - J_pert[_Ym_][i+4]) / (2.0 * ndiff);
151  point->dJij[i+18] = (J_pert[_Zp_][i+4] - J_pert[_Zm_][i+4]) / (2.0 * ndiff);
152 
153  // See types.c, section "Derivatives of Ferers-Dysons' integrals".
154  // Jij_kl = ddJi[27*i+9*j+3*k+l-40] i,j,k,l=1..3.
155  //point->ddJij[9*i] = (J_pert[_Xp_][i+4] - 2.0 * J_pert[_CENTER_][i+4] + J_pert[_Xm_][i+4]) / (ndiff * ndiff);
156  //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);
157  //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);
158 
159  //point->ddJij[9*i+3] = point->ddJij[9*i+1];
160  point->ddJij[9*i+4] = (J_pert[_Yp_][i+4] - 2.0 * J_pert[_CENTER_][i+4] + J_pert[_Ym_][i+4]) / (ndiff * ndiff);
161  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);
162 
163  //point->ddJij[9*i+6] = point->ddJij[9*i+2];
164  point->ddJij[9*i+7] = point->ddJij[9*i+5];
165  point->ddJij[9*i+8] = (J_pert[_Zp_][i+4] - 2.0 * J_pert[_CENTER_][i+4] + J_pert[_Zm_][i+4]) / (ndiff * ndiff);
166  }
167  //}
168  //else _errorr("point position is not defined");
169 
170 #ifdef TOM_DEBUG
171  std::cout << "dJi integrals" << std::endl;
172  for (int i = 0; i < 9; i++)
173  std::cout << "dJi[" << i << "] = " << point->dJi[i] << std::endl;
174  std::cout << std::endl;
175  std::cout << "dJij integrals" << std::endl;
176  for (int i = 0; i < 27; i++)
177  std::cout << "dJij[" << i << "] = " << point->dJij[i] << std::endl;
178  std::cout << std::endl;
179  std::cout << "ddJi integrals" << std::endl;
180  for (int i = 0; i < 27; i++)
181  std::cout << "ddJi[" << i << "] = " << point->ddJi[i] << std::endl;
182  std::cout << std::endl;
183  std::cout << "ddJij integrals" << std::endl;
184  for (int i = 0; i < 81; i++)
185  std::cout << "ddJij[" << i << "] = " << point->ddJij[i] << std::endl;
186  std::cout << std::endl;
187 #endif
188 }
189 
190 // I2 (corresponds to I1 in Mura's book, this cilinder is rotated and a1 is infinity)
191 double eshelbySoluEllipticIntegralsEllipticCylinder::I2(double a1, double a2, double lambda)
192 {
193  return _4PI_ * a1 * a2 / (SQR(a2) - SQR(a1)) * (sqrt(SQR(a2) + lambda) / sqrt(SQR(a1) + lambda) - 1.0); // I2
194 }
195 // I3 (corresponds to I2 in Mura's book, this cilinder is rotated and a1 is infinity)
196 double eshelbySoluEllipticIntegralsEllipticCylinder::I3(double a1, double a2, double lambda)
197 {
198  return _4PI_ * a1 * a2 / (SQR(a1) - SQR(a2)) * (sqrt(SQR(a1) + lambda) / sqrt(SQR(a2) + lambda) - 1.0); // I2
199 }
200 double eshelbySoluEllipticIntegralsEllipticCylinder::I22(double a1, double I2, double I3, double I23, double lambda)
201 {
202  return ((I2 + I3) / (SQR(a1) + lambda) - I23) / 3.0;
203 }
204 double eshelbySoluEllipticIntegralsEllipticCylinder::I23(double a1, double a2, double I2, double I3)
205 {
206  return (I3 - I2) / (SQR(a1) - SQR(a2));
207 }
208 double eshelbySoluEllipticIntegralsEllipticCylinder::I33(double a2, double I2, double I3, double I23, double lambda)
209 {
210  return ((I2 + I3) / (SQR(a2) + lambda) - I23) / 3.0;
211 }
212 
213 // Returns lambda for a given point coordinates
214 double eshelbySoluEllipticIntegralsEllipticCylinder::getLambda(const double a[3], double x1, double x2, double x3)
215 {
216  // Solving quadratic equation.
217  // a = 1.0
218  double b = SQR(a[1]) + SQR(a[2]) - SQR(x2) - SQR(x3);
219  double c = SQR(a[1]) * SQR(a[2]) - SQR(a[1]) * SQR(x3) - SQR(a[2]) * SQR(x2);
220  double D = SQR(b) - 4.0 * c;
221  if (D < 0.0) { _errorr("Discriminant is less than zero in eshelbySoluEllipticIntegralsEllipticCylinder::getLambda()"); }
222  // Lambda is the largest positive root
223  return (-b + sqrt(D)) / 2.0;
224 }
225 
226 
227 } // end of namespace mumech
228 
229 /*end of file*/
double I3(double a1, double a2, double lambda)
#define _warningg(_1)
Definition: gelib.h:163
double loc_x[3]
Local coordinates of a point.
Definition: matrix.h:137
Class legendreIntegrals.
const InclusionRecord3D * I
Definition: esei.h:45
double I33(double a2, double I2, double I3, double I23, double lambda)
#define NUM_PERTURB
Definition: types.h:732
double I2(double a1, double a2, double lambda)
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
Single Point data structure - contribution from Single inclusion.
Definition: matrix.h:133
double I23(double a1, double a2, double I2, double I3)
double ndiff_1
derivative step for the first derivations
Definition: inclusion.h:108
void giveDerivativesOfEllipticIntegrals(Point *point, bool intpoint)
Function gives the values of Ferers-Dyson&#39;s elliptic integral derivatives of the inclusion this->I...
Class inclusion contains and handles all inclusion data.
double getLambda(const double a[3], double x1, double x2, double x3)
Returns lambda for a given point (x1, x2, x3)
#define SQR(a)
Definition: macros.h:97
double dJi[9]
First derivatives of elliptic integral Ii.
Definition: matrix.h:142
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
double dJij[27]
First derivatives of elliptic integral Iij.
Definition: matrix.h:143
Class eshelbySoluEllipticIntegralsEllipticCylinder.
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.
double I22(double a1, double I2, double I3, double I23, double lambda)
#define _4PI_
Definition: types.h:50
void CleanVector(double *a, long n)
Functin cleans a &#39;double&#39; vector, initialize each value being 0-zero.