OOFEM 3.0
Loading...
Searching...
No Matches
homogenize.C
Go to the documentation of this file.
1/*
2 *
3 * ##### ##### ###### ###### ### ###
4 * ## ## ## ## ## ## ## ### ##
5 * ## ## ## ## #### #### ## # ##
6 * ## ## ## ## ## ## ## ##
7 * ## ## ## ## ## ## ## ##
8 * ##### ##### ## ###### ## ##
9 *
10 *
11 * OOFEM : Object Oriented Finite Element Code
12 *
13 * Copyright (C) 1993 - 2025 Borek Patzak
14 *
15 *
16 *
17 * Czech Technical University, Faculty of Civil Engineering,
18 * Department of Structural Mechanics, 166 29 Prague, Czech Republic
19 *
20 * This library is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU Lesser General Public
22 * License as published by the Free Software Foundation; either
23 * version 2.1 of the License, or (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28 * Lesser General Public License for more details.
29 *
30 * You should have received a copy of the GNU Lesser General Public
31 * License along with this library; if not, write to the Free Software
32 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
33 */
34
35#include "homogenize.h"
36#include "mathfem.h"
37
38namespace oofem {
39Homogenize :: Homogenize()
40{ }
41
42//parallel configuration of Voigt
43void Homogenize :: voigt(FloatMatrix &PhaseMatrix)
44{
45 double k, mu;
46 //double volTot = 0.;
47 int NumPhases = PhaseMatrix.giveNumberOfRows();
48
49 checkVolFraction(PhaseMatrix);
50
51 k_hmg = 0.;
52 mu_hmg = 0.;
53 for ( int r = 0; r < NumPhases; r++ ) {
54 ENuToKMu(PhaseMatrix(r, 1), PhaseMatrix(r, 2), k, mu);
55 k_hmg += k * PhaseMatrix(r, 0);
56 mu_hmg += mu * PhaseMatrix(r, 0);
57 //volTot += PhaseMatrix(r, 0);
58 }
59
61}
62
63
64//serial configuration of Reuss
65void Homogenize :: reuss(FloatMatrix &PhaseMatrix)
66{
67 double k, mu;
68 int NumPhases = PhaseMatrix.giveNumberOfRows();
69
70 checkVolFraction(PhaseMatrix);
71
72 k_hmg = 0.;
73 mu_hmg = 0.;
74 for ( int r = 0; r < NumPhases; r++ ) {
75 ENuToKMu(PhaseMatrix(r, 1), PhaseMatrix(r, 2), k, mu);
76 k_hmg += PhaseMatrix(r, 0) / k;
77 mu_hmg += PhaseMatrix(r, 0) / mu;
78 }
79
80 k_hmg = 1. / k_hmg;
81 mu_hmg = 1. / mu_hmg;
83}
84
85/*
86 * Hashin-Shtrikman-Walpole lower and upper bounds, arbitrary number of phases
87 * If phases satisfy ascending order of bulk or shear moduli simultaneously, i.e. k_0<k_1<...k_N together
88 * with mu_0<mu_1<...mu_N, Hashin-Shtrikman bounds are obtained
89 * If the order of bulk and shear moduli is not satisfied, wider Hashin-Shtrikman-Walpole bounds are computed
90 * Implementation according to J.G. Berryman: Mixture Theories for Rock Properties, Physics and Phase Relations,
91 * A Handbook of Physical Constants, Am. Geophys, 1995 or download directly from the web
92 */
93void Homogenize :: hashinShtrikmanWalpole(FloatMatrix &PhaseMatrix)
94{
95 int phase = 0;
96 int counter = 0;
97 int numRows = PhaseMatrix.giveNumberOfRows();
98 double k, k_min, mu, mu_phase = 0., muMin, muMax;
99 double dummy;
100 FloatMatrix PhaseMatrix1;
101 PhaseMatrix1 = PhaseMatrix;
102 FloatMatrix SortedPhaseMatrix(numRows, 3);
103
104
105 checkVolFraction(PhaseMatrix1);
106
107 //Sort phases in ascending order of bulk moduli
108 for ( int i = 0; i < numRows; i++ ) {
109 k_min = 1.e+40;
110 for ( int r = 0; r < numRows; r++ ) {
111 if ( PhaseMatrix1(r, 0) > 0. + 1.e-40 ) {
112 ENuToKMu(PhaseMatrix1(r, 1), PhaseMatrix1(r, 2), k, mu);
113 if ( k < k_min ) {
114 phase = r;
115 k_min = k;
116 mu_phase = mu;
117 }
118 }
119 }
120
121 SortedPhaseMatrix(counter, 0) = PhaseMatrix1(phase, 0);
122 SortedPhaseMatrix(counter, 1) = k_min;
123 SortedPhaseMatrix(counter, 2) = mu_phase;
124
125 PhaseMatrix1(phase, 0) = 0.;
126 counter++;
127 }
128
129 //SortedPhaseMatrix contains (vol. fraction, bulk modulus, shear modulus), sorted in ascending order of bulk modulus
130 //Find phase numbers for maximum and minimum shear moduli
131 muMin = 1.e+40;
132 muMax = 0.;
133 for ( int i = 0; i < numRows; i++ ) {
134 if ( SortedPhaseMatrix(i, 2) > muMax ) {
135 muMax = SortedPhaseMatrix(i, 2);
136 }
137
138 if ( SortedPhaseMatrix(i, 2) < muMin ) {
139 muMin = SortedPhaseMatrix(i, 2);
140 }
141 }
142
143 // find bounds for bulk moduli
144 k_hmg = 0; //lower bound
145 k_hmg_2 = 0; //upper bound
146 for ( int i = 0; i < numRows; i++ ) {
147 k_hmg += SortedPhaseMatrix(i, 0) / ( SortedPhaseMatrix(i, 1) + 4. / 3. * muMin );
148 k_hmg_2 += SortedPhaseMatrix(i, 0) / ( SortedPhaseMatrix(i, 1) + 4. / 3. * muMax );
149 }
150
151 k_hmg = 1. / k_hmg;
152 k_hmg -= 4. / 3. * muMin;
153 k_hmg_2 = 1. / k_hmg_2;
154 k_hmg_2 -= 4. / 3. * muMax;
155
156 //find bounds for shear moduli
157 mu_hmg = gamma( SortedPhaseMatrix, zeta(SortedPhaseMatrix(0, 1), muMin) ); //lower bound
158 mu_hmg_2 = gamma( SortedPhaseMatrix, zeta(SortedPhaseMatrix(numRows - 1, 1), muMax) ); //upper bound
159
160 //Young's moduli are determined from k_min, mu_min and k_max an mu_max
161 kMuToENu(k_hmg, mu_hmg, E_hmg, dummy);
163 //Poisson's ratii are determined from k_min, mu_max and k_max, mu_min
164 kMuToENu(k_hmg, mu_hmg_2, dummy, nu_hmg);
166}
167
168/*
169 * Mori-Tanaka homogenization method
170 * isotropic strain concentration tensor = 3*k_S[r]*J + 2*mu_S[r]*I
171 * refRow is the reference phase of this scheme (0 is the first phase)
172 * for derivation see Bernard et al.: A multiscale micromechanics-hydration model... CCR,pp. 1293-1309, 2003
173 */
174void Homogenize :: moriTanaka(FloatMatrix &PhaseMatrix, int refRow)
175{
176 double f_r, E_r, nu_r, k_r, mu_r;
177 double E_m, nu_m, k_m, mu_m;
178 //double fr_tot = 0.;
179 double nom_k_MT = 0., denom_k_MT = 0., nom_mu_MT = 0., denom_mu_MT = 0.;
180 double k_S_denom = 0., mu_S_denom = 0.;
181 double alpha_m, beta_m;
182 int numRows = PhaseMatrix.giveNumberOfRows();
183 FloatArray k_S(numRows), mu_S(numRows);
184
185 checkVolFraction(PhaseMatrix);
186
187 //determine matrix parameters
188 E_m = PhaseMatrix(refRow, 1);
189 nu_m = PhaseMatrix(refRow, 2);
190
191 ENuToKMu(E_m, nu_m, k_m, mu_m);
192
193 //auxiliary parameters
194 alpha_m = 3. * k_m / ( 3. * k_m + 4 * mu_m );
195 beta_m = 6. * ( k_m + 2. * mu_m ) / ( 5. * ( 3. * k_m + 4. * mu_m ) );
196
197 //cycle through all phases, including the matrix phase
198 for ( int r = 0; r < numRows; r++ ) {
199 f_r = PhaseMatrix(r, 0);
200 E_r = PhaseMatrix(r, 1);
201 nu_r = PhaseMatrix(r, 2);
202
203 //fr_tot += f_r;
204 ENuToKMu(E_r, nu_r, k_r, mu_r);
205
206 nom_k_MT += f_r * k_r / ( 1. + alpha_m * ( k_r / k_m - 1. ) );
207 denom_k_MT += f_r / ( 1. + alpha_m * ( k_r / k_m - 1. ) );
208
209 nom_mu_MT += f_r * mu_r / ( 1. + beta_m * ( mu_r / mu_m - 1. ) );
210 denom_mu_MT += f_r / ( 1. + beta_m * ( mu_r / mu_m - 1. ) );
211
212 k_S [ r ] = 1. / ( 1. + alpha_m * ( k_r / k_m - 1. ) );
213 mu_S [ r ] = 1. / ( 1. + beta_m * ( mu_r / mu_m - 1. ) );
214 }
215
216
217 k_hmg = nom_k_MT / denom_k_MT;
218 mu_hmg = nom_mu_MT / denom_mu_MT;
219
221
222 //calculate denominator of strain concentration tensor (in terms of k_S and mu_S) and final values
223 for ( int r = 0; r < numRows; r++ ) {
224 f_r = PhaseMatrix(r, 0);
225 E_r = PhaseMatrix(r, 1);
226 nu_r = PhaseMatrix(r, 2);
227 ENuToKMu(E_r, nu_r, k_r, mu_r);
228 k_S_denom += f_r * 1. / ( 1. + alpha_m * ( k_r / k_m - 1. ) );
229 mu_S_denom += f_r * 1. / ( 1. + beta_m * ( mu_r / mu_m - 1. ) );
230 }
231
232 for ( int r = 0; r < numRows; r++ ) {
233 E_r = PhaseMatrix(r, 1);
234 nu_r = PhaseMatrix(r, 2);
235 ENuToKMu(E_r, nu_r, k_r, mu_r);
236 // These are pointless operations, and will not do anything as far as I can see / Mikael
237 k_S [ r ] /= k_S_denom;
238 mu_S [ r ] /= mu_S_denom;
239 }
240}
241
242// for derivation see Bernard et al.:A multiscale micromechanics-hydration model... CCR,pp. 1293-1309, 2003
243void Homogenize :: selfConsistent(FloatMatrix &PhaseMatrix)
244{
245 double f_r, E_r, nu_r, k_r, mu_r;
246 double k_SCS, mu_SCS, nom_k_SCS, denom_k_SCS, nom_mu_SCS, denom_mu_SCS;
247 //double fr_tot;
248 double alpha_m = 0., beta_m = 0.;
249 double k_S_denom = 0., mu_S_denom = 0.;
250 int numRows = PhaseMatrix.giveNumberOfRows();
251 FloatArray k_S(numRows), mu_S(numRows);
252
253 checkVolFraction(PhaseMatrix);
254
255 /*first estimation*/
256 k_SCS = 10.;
257 mu_SCS = .3;
258
259 /*iteration for nonlinear equations*/
260 for ( int i = 1; i < 100; i++ ) {
261 //fr_tot = 0.;
262 nom_k_SCS = 0;
263 denom_k_SCS = 0;
264 nom_mu_SCS = 0;
265 denom_mu_SCS = 0;
266 for ( int r = 0; r < numRows; r++ ) {
267 f_r = PhaseMatrix(r, 0);
268 E_r = PhaseMatrix(r, 1);
269 nu_r = PhaseMatrix(r, 2);
270
271 //fr_tot += f_r;
272
273 ENuToKMu(E_r, nu_r, k_r, mu_r);
274
275 alpha_m = 3. * k_SCS / ( 3. * k_SCS + 4 * mu_SCS );
276 beta_m = 6. * ( k_SCS + 2. * mu_SCS ) / ( 5. * ( 3. * k_SCS + 4. * mu_SCS ) );
277
278 nom_k_SCS += f_r * k_r / ( 1 + alpha_m * ( k_r / k_SCS - 1 ) );
279 denom_k_SCS += f_r / ( 1 + alpha_m * ( k_r / k_SCS - 1 ) );
280
281 nom_mu_SCS += f_r * mu_r / ( 1 + beta_m * ( mu_r / mu_SCS - 1 ) );
282 denom_mu_SCS += f_r / ( 1 + beta_m * ( mu_r / mu_SCS - 1 ) );
283 }
284
285 k_SCS = nom_k_SCS / denom_k_SCS;
286 mu_SCS = nom_mu_SCS / denom_mu_SCS;
287 }
288
289 k_hmg = k_SCS;
290 mu_hmg = mu_SCS;
291
293
294 //calculate nominator and denominator of strain concentration tensor (in terms of k_S and mu_S) and final values
295 for ( int r = 0; r < numRows; r++ ) {
296 f_r = PhaseMatrix(r, 0);
297 E_r = PhaseMatrix(r, 1);
298 nu_r = PhaseMatrix(r, 2);
299 ENuToKMu(E_r, nu_r, k_r, mu_r);
300 k_S [ r ] = 1. / ( 1. + alpha_m * ( k_r / k_hmg - 1. ) );
301 mu_S [ r ] = 1. / ( 1. + beta_m * ( mu_r / mu_hmg - 1. ) );
302 k_S_denom += f_r * 1. / ( 1. + alpha_m * ( k_r / k_hmg - 1. ) );
303 mu_S_denom += f_r * 1. / ( 1. + beta_m * ( mu_r / mu_hmg - 1. ) );
304 }
305
306 for ( int r = 0; r < numRows; r++ ) {
307 E_r = PhaseMatrix(r, 1);
308 nu_r = PhaseMatrix(r, 2);
309 ENuToKMu(E_r, nu_r, k_r, mu_r);
310 k_S [ r ] /= k_S_denom;
311 mu_S [ r ] /= mu_S_denom;
312 }
313}
314
315/*
316 * Homogenization scheme of Herve and Zaoui for n-spherical isotropic domains
317 * see Herve E., Zaoui A. n-layered Inclusion-based Micromechanical Modelling,
318 * Int. J. Engng Sci. 31, pp 1-10, 1993.
319 *
320 * The sum of n phases must yield a unity, (n+1) may have arbitrary radius
321 *
322 * The scheme is derived from stress and displacement equivalence at boundaries among phases
323 * homogenized bulk and shear response is calculated
324 * NumPhases is the number of phases including homogeneous medium (n+1)
325 * In homogenized values, (n+1) phase may have arbitrary values - if it has the right
326 * homogenized values of the assembly, the equations (49) and (51) are satisfied exactly without solution
327 *
328 * In case of n=2, the Hashin-Shtrikman bounds are calculated if the well-ordered moduli are used
329 * Homogenized bulk modulus is 100 % OK (corresponds to HS bounds for 2 phases)
330 *
331 * Shear modulus is with small difference when compared to HS bound for 2 phases
332 * typical usage for mortars and concrete is
333 * phase 0 - aggregate
334 * phase 1 - ITZ
335 * phase 2 (n) - cement paste
336 * phase 3 (n+1) - equivalent concrete medium
337 *
338 * The bulk modulus of this scheme coincides with HS bound. This is not true for shear modulus, see Christensen: Two Theoretical Elasticity Micromechanics Models, Journal of Elasticity 50: 15–25, 1998.
339 */
340
341void Homogenize :: herveZaoui(FloatMatrix &PhaseMatrix)
342{
343 int NumPhases = PhaseMatrix.giveNumberOfRows() + 1; //need to extend for an equivalent homogeneous medium
344 FloatMatrix PhaseMatrix1( NumPhases, PhaseMatrix.giveNumberOfColumns() );
345 checkVolFraction(PhaseMatrix);
346 PhaseMatrix1.setSubMatrix(PhaseMatrix, 1, 1);
347 //add arbitrary values for a reference medium
348 PhaseMatrix1(NumPhases - 1, 0) = 0.1;
349 PhaseMatrix1(NumPhases - 1, 1) = 10.;
350 PhaseMatrix1(NumPhases - 1, 2) = 0.3;
351
352 // a)HYDROSTATIC pressure - conditions of displacement and radial stress compatibility between adjacent phases
353 FloatArray r(NumPhases - 1), k(NumPhases), mu(NumPhases);
354 FloatArray Q11(NumPhases - 1), Q21(NumPhases - 1), F(NumPhases), G(NumPhases);
355 FloatMatrix J(2, 2), Jinv(2, 2), N(2, 2), Nhelp(2, 2), Q(2, 2);
356 //set lambda_0 for strain control - arbitrary value for homogenization
357 double lambda_0 = 0.735;
358 double temp1;
359
360 if ( NumPhases < 3 ) {
361 OOFEM_ERROR("Number of considered phases must be at least 3 (including hom. medium)");
362 }
363
364 F[NumPhases - 1] = lambda_0 / 3.;
365
366 //radii of spheres, assume 1 as the maximal radius
367 temp1 = 0.;
368 for ( int i = 0; i < NumPhases - 1; i++ ) {
369 temp1 += PhaseMatrix1(i, 0);
370 r[i] = 1. * cbrt(temp1);
371 //printf( "r(%d)=%f\n", i, r[i] );
372 }
373
374 for ( int i = 0; i < NumPhases; i++ ) {
375 ENuToKMu( PhaseMatrix1(i, 1), PhaseMatrix1(i, 2), k[i], mu[i] );
376 //printf("k(%d)=%f mu(%d)=%f\n", i, k[i], i, mu[i]);
377 }
378
379 //create unit matrix for the first multiplication
380 Nhelp(0, 0) = 1.;
381 Nhelp(1, 1) = 1.;
382
383 //calculate Q
384 for ( int phi = 0; phi <= NumPhases - 2; phi++ ) {
385 //calculate inverse of J_{phi+1}
386 fillJ(J, r[phi], mu, k, phi + 1);
387 Jinv.beInverseOf(J);
388 //calculate J_{phi}
389 fillJ(J, r[phi], mu, k, phi);
390 //calculate N^{phi}=J_{phi+1}^{-1}*J_{phi}
391 N.beProductOf(Jinv, J);
392 //calculate a part of Q^{phi}
393 Q.beProductOf(N, Nhelp);
394 //store part of matrix Q in vector Q11 and Q21
395 Q11[phi] = Q(0, 0);
396 Q21[phi] = Q(1, 0);
397 //copy Q to Nhelp and use in the next cycle
398 Nhelp = Q;
399 }
400
401 //calculate V (contains vector components F,G), F[0] and G[0] make no sense
402 for ( int phi = 1; phi <= NumPhases - 1; phi++ ) {
403 F[phi] = F[NumPhases - 1] * Q11[phi - 1] / Q11[NumPhases - 2];
404 G[phi] = F[NumPhases - 1] * Q21[phi - 1] / Q11[NumPhases - 2];
405 //printf("F(%d)=%f G(%d)=%f\n", phi, F[phi], phi, G[phi]);
406 }
407
408 //check displacement and stress continuity, phi is the more distant phase
409#if 0
410 for ( int phi = 1; phi <= NumPhases - 1; phi++ ) {
411 printf("r=%f displ(in)=%f displ(out)=%f\n", r[phi-1], F[phi-1]*r[phi-1]+G[phi-1]/(r[phi-1]*r[phi-1]), F[phi]*r[phi-1]+G[phi]/(r[phi-1]*r[phi-1]));
412 printf("r=%f stress(in)=%f stress(out)=%f\n", r[phi-1], 3.*k[phi-1]*F[phi-1]-4.*mu[phi-1]*G[phi-1]/(r[phi-1]*r[phi-1]*r[phi-1]), 3.*k[phi]*F[phi]-4.*mu[phi]*G[phi]/(r[phi-1]*r[phi-1]*r[phi-1]));
413 }
414#endif
415
416 /*replace n+1 layer with equivalent homogeneous media calculate homogenized k
417 * checked with Mori-Tanaka method for two phases, bulk modulus is exact
418 */
419 k_hmg = ( 3. * k[NumPhases - 2] * pow(r[NumPhases - 2], 3.) * Q11[NumPhases - 3] - 4. * mu[NumPhases - 2] * Q21[NumPhases - 3] ) / ( 3. * ( pow(r[NumPhases - 2], 3.) * Q11[NumPhases - 3] + Q21[NumPhases - 3] ) );
420
421 //printf("Homogenized k=%f\n", k_hmg);
422
423 //b)SIMPLE SHEAR - continuity of radial and phi displacements and two shear stresses
424 FloatArray B(NumPhases), C(NumPhases), D(NumPhases), A(NumPhases);
425 FloatArray P_v(4), Phelp(4);
426 FloatMatrix L(4, 4), Linv(4, 4), M(4, 4), Mhelp(4, 4), Z(4, 4), M_test(4, 4);
427 std :: vector< FloatMatrix > P_arr(NumPhases); //array to store individual P matrices, allocate memory for P matrices, store there P11, P12, P21, P22
428 //set gamma for displacement approach - arbitrary value for homogenization
429 //variables for homogenized values
430 double a, b, c, nu_n, sqr = 0.;
431 double gamma = 10.; //no effect for homogenziation
432
433 A.zero();
434 A[NumPhases - 1] = gamma;
435
436 //create unit matrix for the first multiplication
437 Mhelp.zero();
438 Mhelp.beUnitMatrix();
439
440 //calculate P
441 for ( int phi = 0; phi < NumPhases - 1; phi++ ) {
442 //calculate inverse of L_{phi+1}
443 fillL(L, r[phi], mu, k, phi + 1);
444 //printf("%f", L(0,1));
445 Linv.beInverseOf(L);
446 //calculate L_{phi}
447 fillL(L, r[phi], mu, k, phi);
448 //calulate M^{phi}=L_{phi+1}^{-1}*L_{phi}
449 M.beProductOf(Linv, L);
450
451#if 0
452 // test routine directly for M
453 this part calculate inverse of M directly
454 M=M_test so the L, Linv and M assembly are OK
455
456 double ak, bk, ck, dk, ek, fk, alphak, nuk, nukp1, koef;
457
458 nuk=PhaseMatrix1(phi,2);
459 nukp1=PhaseMatrix1(phi+1,2);
460
461 ak=mu[phi]/mu[phi+1]*(7.+5.*nuk)*(7.-10.*nukp1)-(7.-10*nuk)*(7.+5.*nukp1);
462 bk=4.*(7.-10.*nuk)+mu[phi]/mu[phi+1]*(7.+5.*nuk);
463 ck=(7.-5.*nukp1)+2.*mu[phi]/mu[phi+1]*(4.-5.*nukp1);
464 dk=(7.+5.*nukp1)+4.*mu[phi]/mu[phi+1]*(7.-10.*nukp1);
465 ek=2*(4.-5.*nuk)+mu[phi]/mu[phi+1]*(7.-5.*nuk);
466 fk=(4.-5.*nuk)*(7.-5.*nukp1)-mu[phi]/mu[phi+1]*(4.-5.*nukp1)*(7.-5.*nuk);
467 alphak=mu[phi]/mu[phi+1]-1.;
468 koef=1./(5.*(1-nukp1));
469
470 M_test(0,0)=koef*ck/3.;
471 M_test(0,1)=koef*pow(r[phi],2)*(3*bk-7*ck)/(5.*(1.-2*nuk));
472 M_test(0,2)=koef*(-12.)*alphak/pow(r[phi],5);
473 M_test(0,3)=koef*4.*(fk-27.*alphak)/(15.*(1.-2*nuk)*pow(r[phi],3));
474
475 M_test(1,0)=koef*0.;
476 M_test(1,1)=koef*(1.-2*nukp1)*bk/(7.*(1.-2.*nuk));
477 M_test(1,2)=koef*(-20.)*(1.-2.*nukp1)*alphak/(7*pow(r[phi],7));
478 M_test(1,3)=koef*(-12.)*alphak*(1.-2.*nukp1)/(7.*(1.-2.*nuk)*(pow(r[phi],5)));
479
480 M_test(2,0)=koef*pow(r[phi],5)*alphak/2.;
481 M_test(2,1)=koef*(-pow(r[phi],7))*(2*ak+147*alphak)/(70.*(1.-2.*nuk));
482 M_test(2,2)=koef*dk/7.;
483 M_test(2,3)=koef*pow(r[phi],2)*(105*(1.-nukp1)+12.*alphak*(7.-10.*nukp1)-7.*ek)/(35.*(1.-2*nuk));
484
485 M_test(3,0)=koef*(-5.)/6.*(1.-2*nukp1)*alphak*pow(r[phi],3);
486 M_test(3,1)=koef*7.*(1.-2*nukp1)*alphak*pow(r[phi],5)/(2.*(1.-2.*nuk));
487 M_test(3,2)=koef*0.;
488 M_test(3,3)=koef*ek*(1.-2.*nukp1)/(3.*(1.-2*nuk));
489
490 M = M_test;
491#endif
492 P_arr [ phi ].resize(4, 4);
493 P_arr [ phi ].beProductOf(M, Mhelp);
494 Mhelp = P_arr [ phi ];
495 }
496
497 //printf("PPP %f\n", P_arr[1](3,0)*P_arr[1](1,1) - P_arr[1](3,1)*P_arr[1](1,0));
498
499 //calculate vector W (contains scalar components A,B,C,D for each step)
500
501 P_v[0] = P_arr [ NumPhases - 2 ](1, 1); //matrix stored column wise (P11, P21, P31....), P_22
502 P_v[1] = -P_arr [ NumPhases - 2 ](1, 0); // P_21
503 P_v[2] = P_v[3] = 0.;
504
505 for ( int phi = 1; phi <= NumPhases - 1; phi++ ) {
506 Phelp.beProductOf(P_arr [ phi - 1 ], P_v);
507 Phelp.times( A[NumPhases - 1] / sqrt(2.) / ( P_arr [ NumPhases - 2 ](0, 0) * P_arr [ NumPhases - 2 ](1, 1) - P_arr [ NumPhases - 2 ](0, 1) * P_arr [ NumPhases - 2 ](1, 0) ) );
508 A[phi] = Phelp[0];
509 B[phi] = Phelp[1];
510 C[phi] = Phelp[2];
511 D[phi] = Phelp[3];
512 //printf("A(%d]=%f B(%d)=%f C(%d)=%f D(%d)=%f\n", phi, A[phi], phi, B[phi], phi, C[phi], phi, D[phi]);
513 }
514
515 //check displacement and stress continuity, phi is the less distant phase
516 //this cycle for for checking purposes only
517 for ( int phi = 0; phi <= NumPhases - 2; phi++ ) {
518 //phase closer to the center
519 fillL(L, r[phi], mu, k, phi);
520 Phelp[0] = A[phi];
521 Phelp[1] = B[phi];
522 Phelp[2] = C[phi];
523 Phelp[3] = D[phi];
524 P_v.beProductOf(L, Phelp);
525 //printf("(in) n=%d r=%f ur=%f uphi=%f srp=%f srf=%f\n",phi, r[phi], P_v[0],P_v[1], P_v[2], P_v[3]);
526
527 fillL(L, r[phi], mu, k, phi + 1);
528 Phelp[0] = A[phi + 1];
529 Phelp[1] = B[phi + 1];
530 Phelp[2] = C[phi + 1];
531 Phelp[3] = D[phi + 1];
532 P_v.beProductOf(L, Phelp);
533 //printf("(out) n=%d r=%f ur=%f uphi=%f srp=%f srf=%f\n", phi,r[phi], P_v[0],P_v[1], P_v[2], P_v[3]);
534 }
535
536 // replace n+1 layer with equivalent homogeneous media, calculate homogenized mu
537 for ( int i = 0; i <= 3; i++ ) { //alpha, rows in Z
538 for ( int j = 0; j <= 3; j++ ) { //beta, columns in Z
539 Z(i, j) = P_arr [ NumPhases - 3 ](i, 0) * P_arr [ NumPhases - 3 ](j, 1) - P_arr [ NumPhases - 3 ](j, 0) * P_arr [ NumPhases - 3 ](i, 1);
540 // printf("Z=%f ", Z(i,j));
541 }
542 }
543
544 nu_n = ( 3. * k[NumPhases - 2] - 2. * mu[NumPhases - 2] ) / ( 6. * k[NumPhases - 2] + 2. * mu[NumPhases - 2] );
545
546 a = 4. * pow(r[NumPhases - 2], 10.) * ( 1. - 2. * nu_n ) * ( 7. - 10. * nu_n ) * Z(0, 1) +
547 20. * pow(r[NumPhases - 2], 7.) * ( 7. - 12. * nu_n + 8. * nu_n * nu_n ) * Z(3, 1) +
548 12. * pow(r[NumPhases - 2], 5.) * ( 1. - 2. * nu_n ) * ( Z(0, 3) - 7. * Z(1, 2) ) +
549 20. * pow(r[NumPhases - 2], 3.) * ( 1. - 2. * nu_n ) * ( 1. - 2. * nu_n ) * Z(0, 2) +
550 16. * ( 4. - 5. * nu_n ) * ( 1. - 2. * nu_n ) * Z(3, 2);
551
552 b = 3. * pow(r[NumPhases - 2], 10.) * ( 1. - 2. * nu_n ) * ( 15. * nu_n - 7. ) * Z(0, 1) +
553 60. * pow(r[NumPhases - 2], 7.) * ( nu_n - 3. ) * nu_n * Z(3, 1) -
554 24. * pow(r[NumPhases - 2], 5.) * ( 1. - 2. * nu_n ) * ( Z(0, 3) - 7. * Z(1, 2) ) -
555 40. * pow(r[NumPhases - 2], 3.) * ( 1. - 2. * nu_n ) * ( 1. - 2. * nu_n ) * Z(0, 2) -
556 8. * ( 1. - 5. * nu_n ) * ( 1. - 2. * nu_n ) * Z(3, 2);
557
558 c = -pow(r[NumPhases - 2], 10.) * ( 1. - 2. * nu_n ) * ( 7. + 5 * nu_n ) * Z(0, 1) +
559 10. * pow(r[NumPhases - 2], 7.) * ( 7. - nu_n * nu_n ) * Z(3, 1) +
560 12. * pow(r[NumPhases - 2], 5.) * ( 1. - 2. * nu_n ) * ( Z(0, 3) - 7. * Z(1, 2) ) +
561 20. * pow(r[NumPhases - 2], 3.) * ( 1. - 2. * nu_n ) * ( 1. - 2. * nu_n ) * Z(0, 2) -
562 8. * ( 7. - 5. * nu_n ) * ( 1. - 2. * nu_n ) * Z(3, 2);
563
564 //solve quadratic equation, report higher number
565 sqr = b * b - 4. * a * c;
566 if ( sqr < 0 ) {
567 OOFEM_ERROR("Shear modulus does not yield a real number");
568 }
569
570 if ( ( -b - pow(sqr, 0.5) ) >= 0 ) {
571 OOFEM_WARNING("Two solutions for the shear modulus were found, continuing with the higher value");
572 }
573
574 //usually this higher value is reported
575 mu_hmg = mu[NumPhases - 2] * ( -b + pow(sqr, 0.5) ) / ( 2. * a );
576 //uncomment if lower value of mu should be used, only when positive
577 //mu_hmg=mu(NumPhases-2)*(-b+pow(sqr, 0.5))/(2.*a);
578
579 //printf("Homogenized mu=%f\n", mu_hmg);
580
582}
583
584/*Hirsh model as a combination of Voigt and Reuss (parameter chi)*/
585void Homogenize :: hirsch(FloatMatrix &PhaseMatrix, double chi)
586{
587 double k_Voigt, mu_Voigt, k_Reuss, mu_Reuss;
588 voigt(PhaseMatrix);
589 k_Voigt = k_hmg;
590 mu_Voigt = mu_hmg;
591 reuss(PhaseMatrix);
592 k_Reuss = k_hmg;
593 mu_Reuss = mu_hmg;
594 k_hmg = ( 1. - chi ) * k_Reuss + chi * k_Voigt;
595 mu_hmg = ( 1. - chi ) * mu_Reuss + chi * mu_Voigt;
597}
598
599
600void Homogenize :: hansen(FloatMatrix &PhaseMatrix)
601{
602 double f_i, E_i, f_m, E_m;
603
604 if ( PhaseMatrix.giveNumberOfRows() != 2 ) {
605 OOFEM_ERROR("Only two phases are allowed");
606 }
607
608 checkVolFraction(PhaseMatrix);
609
610 f_i = PhaseMatrix(0, 0);
611 E_i = PhaseMatrix(0, 1);
612 f_m = PhaseMatrix(1, 0);
613 E_m = PhaseMatrix(1, 1);
614
615 E_hmg = E_i * ( ( f_i * E_i + ( 1 + f_m ) * E_m ) / ( ( 1. + f_m ) * E_i + f_i * E_m ) );
616 nu_hmg = 0.2;
618}
619
620
621void Homogenize :: counto(FloatMatrix &PhaseMatrix)
622{
623 double E_i, f_m, E_m, nu_m;
624 if ( PhaseMatrix.giveNumberOfRows() != 2 ) {
625 OOFEM_ERROR("Only two phases are allowed");
626 }
627
628 checkVolFraction(PhaseMatrix);
629
630 E_i = PhaseMatrix(0, 1);
631 f_m = PhaseMatrix(1, 0);
632 E_m = PhaseMatrix(1, 1);
633 nu_m = PhaseMatrix(1, 2);
634
635 E_hmg = 1. / ( ( 1. - sqrt(f_m) ) / E_i + 1. / ( E_i * ( ( 1. - sqrt(f_m) ) / sqrt(f_m) ) + E_m ) );
636 nu_hmg = nu_m;
638}
639
640/* Kuster-Toksoz model from Monteiro: Elastic Moduli Lightweight Aggregate Model,
641 * Cement and Concrete Research, 1995, No.2, pp. 276-280.
642 */
643void Homogenize :: kusterToksoz(FloatMatrix &PhaseMatrix)
644{
645 double k_KT, mu_KT, nom, denom;
646 double f_i, E_i, nu_i, k_i, mu_i, f_m, E_m, nu_m, mu_m, k_m;
647 if ( PhaseMatrix.giveNumberOfRows() != 2 ) {
648 OOFEM_ERROR("Only two phases are allowed");
649 }
650
651 checkVolFraction(PhaseMatrix);
652
653 f_i = PhaseMatrix(0, 0);
654 E_i = PhaseMatrix(0, 1);
655 nu_i = PhaseMatrix(0, 2);
656 ENuToKMu(E_i, nu_i, k_i, mu_i);
657 f_m = PhaseMatrix(1, 0);
658 E_m = PhaseMatrix(1, 1);
659 nu_m = PhaseMatrix(1, 2);
660 ENuToKMu(E_m, nu_m, k_m, mu_m);
661
662 nom = 1 + ( 4 * mu_m * ( k_i - k_m ) / ( ( 3 * k_i * +4 * mu_m ) * k_m ) ) * f_i;
663 denom = 1 - ( 3 * ( k_i - k_m ) / ( 3 * k_i + 4 * mu_m ) ) * f_i;
664 k_KT = k_m * nom / denom;
665
666 nom = ( 6 * k_m + 12 * mu_m ) * mu_i + ( 9 * k_m + 8 * mu_m ) * ( f_m * mu_m + f_i * mu_i );
667 denom = ( 9 * k_m + 8 * mu_m ) * mu_m + ( 6 * k_m + 12 * mu_m ) * ( f_m * mu_i + f_i * mu_m );
668 mu_KT = mu_m * nom / denom;
669
670 k_hmg = k_KT;
671 mu_hmg = mu_KT;
672
674}
675
676void Homogenize :: printYourself(int out)
677{
678 if ( out == 0 ) {
679 printf("E %.4e\t nu %.4e\t k %.4e\t mu %.4e\n", this->E_hmg, this->nu_hmg, this->k_hmg, this->mu_hmg);
680 } else {
681 printf("E %.4e\t nu %.4e\t k %.4e\t mu %.4e\n", this->E_hmg_2, this->nu_hmg_2, this->k_hmg_2, this->mu_hmg_2);
682 }
683}
684
685
686void Homogenize :: ENuToKMu(const double E, const double nu, double &k, double &mu)
687{
688 mu = E / ( 2. * ( 1. + nu ) );
689 k = E / ( 3. * ( 1. - 2. * nu ) );
690}
691
692void Homogenize :: kMuToENu(const double k, const double mu, double &E, double &nu)
693{
694 E = 9. * k * mu / ( 3. * k + mu );
695 nu = ( 3. * k - 2. * mu ) / ( 6. * k + 2 * mu );
696}
697
698//Auxiliary function for Hashin-Shtrikman-Walpole shear bounds
699double Homogenize :: zeta(double k, double mu)
700{
701 return mu / 6. * ( 9. * k + 8. * mu ) / ( k + 2. * mu );
702}
703
704//Auxiliary function for Hashin-Shtrikman-Walpole shear bounds
705double Homogenize :: gamma(FloatMatrix &SortedPhaseMatrix, double zeta)
706{
707 double gamma = 0;
708 int NumPhases = SortedPhaseMatrix.giveNumberOfRows();
709
710 for ( int r = 0; r < NumPhases; r++ ) {
711 gamma += SortedPhaseMatrix(r, 0) / ( SortedPhaseMatrix(r, 2) + zeta );
712 }
713
714 gamma = 1. / gamma;
715 gamma -= zeta;
716 return gamma;
717}
718
719void Homogenize :: checkVolFraction(FloatMatrix &PhaseMatrix)
720{
721 double volTot = 0.;
722 int NumPhases = PhaseMatrix.giveNumberOfRows();
723 for ( int r = 0; r < NumPhases; r++ ) {
724 volTot += PhaseMatrix(r, 0);
725 }
726
727 if ( volTot < 0.99 || volTot > 1.01 ) {
728 OOFEM_ERROR("Volumetric fraction of phases 0-%d is %f, which not the unity\n", NumPhases, volTot);
729 }
730}
731
732//help function for filling the J matrix
733void Homogenize :: fillJ(FloatMatrix &J, double r, const FloatArray &mu, const FloatArray &k, int phase)
734{
735 J(0, 0) = r;
736 J(0, 1) = 1. / ( pow(r, 2.) );
737 J(1, 0) = 3 * k[phase];
738 J(1, 1) = -4. * mu[phase] / ( pow(r, 3.) );
739}
740
741//help function for filling the L matrix
742void Homogenize :: fillL(FloatMatrix &L, double r, const FloatArray &mu, const FloatArray &k, int phase)
743{
744 double mu_l = mu[phase];
745 double k_l = k[phase];
746 double nu_l = ( 3. * k_l - 2. * mu_l ) / ( 6. * k_l + 2. * mu_l ); //OK
747
748 L(0, 0) = r;
749 L(0, 1) = -6. *nu_l *pow(r, 3.) / ( 1. - 2. * nu_l );
750 L(0, 2) = 3. / pow(r, 4.);
751 L(0, 3) = ( 5. - 4. * nu_l ) / ( ( 1. - 2. * nu_l ) * pow(r, 2.) );
752
753 L(1, 0) = r;
754 L(1, 1) = -( 7. - 4. * nu_l ) * pow(r, 3.) / ( 1. - 2. * nu_l );
755 L(1, 2) = -2. / pow(r, 4.);
756 L(1, 3) = 2. / pow(r, 2.);
757
758 L(2, 0) = mu_l;
759 L(2, 1) = 3. *nu_l *mu_l *pow(r, 2.) / ( 1. - 2. * nu_l );
760 L(2, 2) = -12. * mu_l / pow(r, 5.);
761 L(2, 3) = 2. * ( nu_l - 5. ) * mu_l / ( ( 1. - 2. * nu_l ) * pow(r, 3.) );
762
763 L(3, 0) = mu_l;
764 L(3, 1) = -( 7. + 2 * nu_l ) * mu_l * pow(r, 2.) / ( 1. - 2. * nu_l );
765 L(3, 2) = 8. * mu_l / pow(r, 5.);
766 L(3, 3) = 2. * ( 1 + nu_l ) * mu_l / ( ( 1. - 2. * nu_l ) * pow(r, 3.) );
767}
768} // end namespace oofem
#define N(a, b)
#define E(a, b)
void zero()
Zeroes all coefficients of receiver.
Definition floatarray.C:683
void beProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
Definition floatarray.C:689
void times(double s)
Definition floatarray.C:834
void resize(Index rows, Index cols)
Definition floatmatrix.C:79
int giveNumberOfColumns() const
Returns number of columns of receiver.
void beProductOf(const FloatMatrix &a, const FloatMatrix &b)
void setSubMatrix(const FloatMatrix &src, int sr, int sc)
int giveNumberOfRows() const
Returns number of rows of receiver.
void fillL(FloatMatrix &L, double r, const FloatArray &mu, const FloatArray &k, int phase)
Auxiliary function for Herve-Zaoui scheme.
Definition homogenize.C:742
double E_hmg_2
Upper bound of Young's modulus if applicable.
Definition homogenize.h:128
double gamma(FloatMatrix &SortedPhaseMatrix, double zeta)
Auxiliary function.
Definition homogenize.C:705
double mu_hmg
Effective shear modulus or the lower bound.
Definition homogenize.h:143
double zeta(double k, double mu)
Auxiliary function for Hashin-Shtrikman bounds.
Definition homogenize.C:699
double nu_hmg
Effective Poisson's ratio.
Definition homogenize.h:131
double mu_hmg_2
Upper shear modulus if applicable.
Definition homogenize.h:146
double nu_hmg_2
Effective Poisson's ratio or the lower bound.
Definition homogenize.h:134
void reuss(FloatMatrix &PhaseMatrix)
Definition homogenize.C:65
double k_hmg_2
Upper bound of bulk modulus if applicable.
Definition homogenize.h:140
void kMuToENu(const double k, const double mu, double &E, double &nu)
Convert bulk and shear moduli to Young's modulus and Poisson's ratio, isotropic material.
Definition homogenize.C:692
void voigt(FloatMatrix &PhaseMatrix)
Definition homogenize.C:43
double E_hmg
Effective Young's modulus or the lower bound.
Definition homogenize.h:125
void fillJ(FloatMatrix &J, double r, const FloatArray &mu, const FloatArray &k, int phase)
Auxiliary function for Herve-Zaoui scheme.
Definition homogenize.C:733
void ENuToKMu(const double E, const double nu, double &k, double &mu)
Convert Young's modulus and Poisson's ratio to bulk and shear moduli, isotropic material.
Definition homogenize.C:686
void checkVolFraction(FloatMatrix &PhaseMatrix)
Definition homogenize.C:719
double k_hmg
Effective bulk modulus or the lower bound.
Definition homogenize.h:137
#define OOFEM_WARNING(...)
Definition error.h:80
#define OOFEM_ERROR(...)
Definition error.h:79
double cbrt(double x)
Returns the cubic root of x.
Definition mathfem.h:122
double sqr(double x)
Definition mathfem.h:125

This page is part of the OOFEM-3.0 documentation. Copyright Copyright (C) 1994-2025 Borek Patzak Bořek Patzák
Project e-mail: oofem@fsv.cvut.cz
Generated at for OOFEM by doxygen 1.15.0 written by Dimitri van Heesch, © 1997-2011