53FCMMaterial :: hasMaterialModeCapability(MaterialMode mode)
const
55 return mode == _3dMat || mode == _PlaneStress || mode == _PlaneStrain;
80 FloatArray stressIncrement_l, stressVector_g, trialStress_g, trialStress_l, sigmaResid, sigmaElast_l, sigmaCrack_l, sigmaResid_old;
84 FloatArray reducedStrain_g, strainIncrement_g, strainIncrement_l, crackStrain, crackStrainIncrement, elasticStrain_l, elasticStrainIncrement_l;
87 MaterialMode mMode = gp->giveMaterialMode();
99 double gamma_cr, d_gamma_cr;
100 double tau_el, tau_cr;
102 double d_tau_old = 0.;
103 bool illinoisFlag =
false;
105 int iterLimitGradient = 20;
106 int iterLimitNormal = 100;
107 int iterLimitShear = 100;
110 FloatArray tempNormalCrackStrain, normalCrackStrain;
120 int index, indexOld, indexCount;
122 bool changeIndexFlag =
false;
125 FloatArray crackStrainPlus, crackStrainMinus, residPlus, residMinus;
134 sigmaResid_old.
resize(nMaxCr);
136 index = indexOld = indexCount = 0;
143 zeros.resize( StructuralMaterial :: giveSizeOfVoigtSymVector( gp->giveMaterialMode() ) );
162 trialStress_g.
add(stressVector_g);
171 answer = trialStress_g;
190 if ( nCr < nMaxCr ) {
194 for (
int iCrack = nCr + 1; iCrack <=
min(nMaxCr, this->
nAllowedCracks); iCrack++ ) {
217 strainIncrement_l.
beProductOf(epsG2L, strainIncrement_g);
220 stressIncrement_l.
beProductOf(De, strainIncrement_l);
239 tempNormalCrackStrain.
resize(nMaxCr);
241 normalCrackStrain = tempNormalCrackStrain;
244 normalStressVector_l = stressVector_l;
245 normalStressVector_l.
resize(nMaxCr);
247 normalStrainIncrement_l = strainIncrement_l;
254 sigmaResid = stressIncrement_l;
257 for (
int indexCount = 1; indexCount <= indexLimit; indexCount++ ) {
259 if (indexCount > 1 ) {
260 if ( !changeIndexFlag ) {
261 OOFEM_WARNING(
"FCM: maximum error on the same component, max. stress error %f, index %d, indexCount %d, element %d\n", maxErr, index, indexCount, gp->giveElement()->giveNumber() );
267 minus = plus =
false;
268 illinoisFlag =
false;
269 changeIndexFlag =
false;
271 sigmaResid_old.
zero();
278 if ( (iterN == 1) && (indexCount == 1) ) {
288 D.
solveForRhs(sigmaResid, normalCrackStrainIncrement);
291 tempNormalCrackStrain.
add(normalCrackStrainIncrement);
301 sigmaCrack_l.
resize( nMaxCr );
302 for (
int i = 1; i <= nMaxCr; i++ ) {
303 sigmaCrack_l.
at(i) = Dcr.
at(i, i) * tempNormalCrackStrain.
at(i);
310 normalElasticStrainIncrement_l = normalStrainIncrement_l;
311 normalElasticStrainIncrement_l.
subtract(tempNormalCrackStrain);
312 normalElasticStrainIncrement_l.
add(normalCrackStrain);
315 sigmaElast_l.
beProductOf(DeRed, normalElasticStrainIncrement_l);
318 sigmaElast_l.
add(normalStressVector_l);
321 sigmaResid = sigmaElast_l;
327 for (
int i = 1; i <= sigmaResid.
giveSize(); i++ ) {
328 if ( fabs( sigmaResid.
at(i) ) > maxErr ) {
329 maxErr = fabs( sigmaResid.
at(i) );
344 if ( indexCount == 1 ) {
346 if (iterN < iterLimitGradient/2.) {
354 if (index != indexOld) {
355 minus = plus =
false;
368 if ( sigmaResid.
at(index) > 0 ) {
371 residPlus = sigmaResid;
372 crackStrainPlus = tempNormalCrackStrain;
373 }
else if ( fabs(sigmaResid.
at(index)) < fabs(residPlus.
at(index)) ) {
374 residPlus = sigmaResid;
375 crackStrainPlus = tempNormalCrackStrain;
381 residMinus = sigmaResid;
382 crackStrainMinus = tempNormalCrackStrain;
385 else if ( fabs(sigmaResid.
at(index)) < fabs(residMinus.
at(index)) ) {
386 residMinus = sigmaResid;
387 crackStrainMinus = tempNormalCrackStrain;
394 if ( ( plus) && ( minus) ) {
395 if ( ( indexCount == 1 ) && ( iterN < iterLimitGradient ) ) {
410 tempNormalCrackStrain.
zero();
412 if( (crackStrainMinus.
at(index) < 0.) || (crackStrainPlus.
at(index) < 0.) ) {
413 tempNormalCrackStrain.
add(crackStrainMinus);
414 tempNormalCrackStrain.
add(crackStrainPlus);
415 tempNormalCrackStrain.
times(0.5);
426 if ( sigmaResid.
at(index) == residPlus.
at(index) ) {
428 tempNormalCrackStrain.
add(crackStrainMinus);
429 tempNormalCrackStrain.
times(residPlus.
at(index) );
431 helpRF = crackStrainPlus;
432 helpRF.
times( 0.5 * residMinus.
at(index) );
434 tempNormalCrackStrain.
subtract(helpRF);
435 tempNormalCrackStrain.
times( 1. / ( residPlus.
at(index) - 0.5 * residMinus.
at(index) ) );
439 tempNormalCrackStrain.
add(crackStrainMinus);
440 tempNormalCrackStrain.
times( 0.5 * residPlus.
at(index) );
442 helpRF = crackStrainPlus;
443 helpRF.
times( residMinus.
at(index) );
445 tempNormalCrackStrain.
subtract(helpRF);
446 tempNormalCrackStrain.
times( 1. / ( 0.5 * residPlus.
at(index) - residMinus.
at(index) ) );
453 tempNormalCrackStrain.
add(crackStrainMinus);
454 tempNormalCrackStrain.
times(residPlus.
at(index) );
456 helpRF = crackStrainPlus;
457 helpRF.
times(residMinus.
at(index) );
459 tempNormalCrackStrain.
subtract(helpRF);
460 tempNormalCrackStrain.
times( 1. / ( residPlus.
at(index) - residMinus.
at(index) ) );
469 tempNormalCrackStrain.
at(index) = 0.;
473 if (tempNormalCrackStrain.
at(index) < 0.) {
474 tempNormalCrackStrain.
at(index) = 0.;
484 sigmaCrack_l.
resize( nMaxCr );
485 for (
int i = 1; i <= nMaxCr; i++ ) {
486 sigmaCrack_l.
at(i) = Dcr.
at(i, i) * tempNormalCrackStrain.
at(i);
492 normalElasticStrainIncrement_l = normalStrainIncrement_l;
493 normalElasticStrainIncrement_l.
subtract(tempNormalCrackStrain);
494 normalElasticStrainIncrement_l.
add(normalCrackStrain);
497 sigmaElast_l.
beProductOf(DeRed, normalElasticStrainIncrement_l);
500 sigmaElast_l.
add(normalStressVector_l);
503 sigmaResid = sigmaElast_l;
519 if ( fabs( sigmaResid.
at(index) ) <
fcm_TOLERANCE * this->giveTensileStrength(gp, tStep) ) {
520 changeIndexFlag =
true;
525 if ( (sigmaResid.
at(index) >= 0.) && ( sigmaResid.
at(index) < residPlus.
at(index) ) ) {
526 residPlus = sigmaResid;
527 crackStrainPlus = tempNormalCrackStrain;
529 }
else if ( (sigmaResid.
at(index) <= 0.) && ( fabs(sigmaResid.
at(index)) < fabs(residMinus.
at(index) ) ) ) {
531 residMinus = sigmaResid;
532 crackStrainMinus = tempNormalCrackStrain;
535 changeIndexFlag =
true;
540 if ( ( ( fabs( crackStrainMinus.
at(index) - crackStrainPlus.
at(index) ) < 1.e-16 ) &&
541 (
max( fabs( crackStrainMinus.
at(index) ), fabs( crackStrainPlus.
at(index) ) ) < 1.e-14 ) ) ||
543 tempNormalCrackStrain.
zero();
544 tempNormalCrackStrain.
add(crackStrainMinus);
545 tempNormalCrackStrain.
add(crackStrainPlus);
546 tempNormalCrackStrain.
times(0.5);
548 tempNormalCrackStrain.
at(index) = 0.;
561 for (
int i_count = 1; i_count <= 2; i_count++ ) {
567 normalElasticStrainIncrement_l = normalStrainIncrement_l;
568 normalElasticStrainIncrement_l.
subtract(tempNormalCrackStrain);
569 normalElasticStrainIncrement_l.
add(normalCrackStrain);
571 sigmaElast_l.
beProductOf(DeRed, normalElasticStrainIncrement_l);
574 tempNormalCrackStrain.
at(index) = sigmaElast_l.
at(index) / this->
giveCrackingModulus(SecantStiffness, gp, tStep, index);
583 sigmaCrack_l.
resize( nMaxCr );
584 for (
int i = 1; i <= nMaxCr; i++ ) {
585 sigmaCrack_l.
at(i) = Dcr.
at(i, i) * tempNormalCrackStrain.
at(i);
589 sigmaResid = sigmaElast_l;
598 for (
int i = 1; i <= sigmaResid.
giveSize(); i++ ) {
599 if ( fabs( sigmaResid.
at(i) ) > maxErr ) {
600 maxErr = fabs( sigmaResid.
at(i) );
606 if (indexOld != index) {
607 changeIndexFlag =
true;
608 illinoisFlag =
false;
612 if (
sgn(sigmaResid.
at(index) ) ==
sgn(sigmaResid_old.
at(index) ) ) {
615 illinoisFlag =
false;
618 sigmaResid_old = sigmaResid;
624 }
while ( (!changeIndexFlag) && (iterN <= iterLimitNormal) && ( fabs( sigmaResid.
at(index) ) <
fcm_TOLERANCE * this->giveTensileStrength(gp, tStep) ) );
634 if ( indexCount >= indexLimit/2.) {
635 OOFEM_WARNING(
"FCM: slowly converging equilibrium in crack direction!, max. stress error %f, index %d, indexCount %d, element %d\n", maxErr, index, indexCount, gp->giveElement()->giveNumber() );
638 if ( indexCount >= indexLimit ) {
639 OOFEM_WARNING(
"FCM: slowly converging equilibrium in crack direction!, max. stress error %f, index %d, indexCount %d, element %d\n", maxErr, index, indexCount, gp->giveElement()->giveNumber() );
653 for (
int i = nMaxCr+1; i <= crackStrain.
giveSize(); i++ ) {
658 crackStrainPlus.
resize(1);
659 crackStrainPlus.
zero();
660 crackStrainMinus.
resize(1);
661 crackStrainMinus.
zero();
668 d_tau = G * strainIncrement_l.
at(i);
671 for (
int iterS = 1; iterS <= iterLimitShear; iterS++ ) {
688 OOFEM_ERROR(
"Material mode %s not supported", __MaterialModeToString(mMode) );
692 if ( ( !plus ) || ( !minus ) ) {
695 d_gamma_cr = ( stressVector_l.
at(i) - DII * status->
giveCrackStrain(i) + d_tau ) / ( G + DII );
697 d_gamma_cr = ( d_tau ) / ( G + DII );
700 gamma_cr += d_gamma_cr;
703 if (
sgn( crackStrainMinus.
at(1) ) ==
sgn( crackStrainPlus.
at(1) ) ) {
707 if (d_tau == residPlus.
at(1) ) {
708 gamma_cr = ( crackStrainMinus.
at(1) * residPlus.
at(1) - 0.5 * crackStrainPlus.
at(1) * residMinus.
at(1) ) / ( residPlus.
at(1) - 0.5 * residMinus.
at(1) );
711 gamma_cr = ( 0.5 * crackStrainMinus.
at(1) * residPlus.
at(1) - crackStrainPlus.
at(1) * residMinus.
at(1) ) / ( 0.5 * residPlus.
at(1) - residMinus.
at(1) );
716 gamma_cr = ( crackStrainMinus.
at(1) * residPlus.
at(1) - crackStrainPlus.
at(1) * residMinus.
at(1) ) / ( residPlus.
at(1) - residMinus.
at(1) );
719 gamma_cr = ( crackStrainMinus.
at(1) + crackStrainPlus.
at(1) ) / 2.;
747 OOFEM_ERROR(
"Material mode %s not supported", __MaterialModeToString(mMode) );
750 if( fabs(tau_cr) > maxTau) {
752 if ( ( !plus ) || ( !minus ) ) {
755 d_gamma_el = (
sgn(tau_cr)* maxTau - stressVector_l.
at(i) ) / G;
788 OOFEM_ERROR(
"Material mode %s not supported", __MaterialModeToString(mMode) );
791 tau_el = stressVector_l.
at(i) + d_gamma_el * G;
793 tau_cr =
min( maxTau, DII * fabs(gamma_cr) );
794 tau_cr *=
sgn(gamma_cr);
799 tau_el = stressVector_l.
at(i);
801 tau_el += G * ( strainIncrement_l.
at(i) - gamma_cr + status->
giveCrackStrain(i) );
805 d_tau = tau_el - tau_cr;
815 residMinus.
at(1) = d_tau;
816 crackStrainMinus.
at(1) = gamma_cr;
821 residPlus.
at(1) = d_tau;
822 crackStrainPlus.
at(1) = gamma_cr;
826 if (
sgn(d_tau_old) ==
sgn(d_tau) ) {
830 illinoisFlag =
false;
838 if ( iterS > iterLimitShear*0.3) {
839 OOFEM_WARNING(
"Fixed crack model: Local equilibrium in shear not converging!, max. stress error %f, index %d, iter %d, element %d\n", fabs(d_tau), i, iterS, gp->giveElement()->giveNumber() );
844 if ( iterS == iterLimitShear ) {
845 OOFEM_WARNING(
"Fixed crack model: Local equilibrium in shear direction(s) not reached!, max. stress error %f, element %d\n", fabs(d_tau), gp->giveElement()->giveNumber() );
856 elasticStrainIncrement_l = strainIncrement_l;
857 elasticStrainIncrement_l.
subtract(crackStrain);
860 sigmaElast_l.
beProductOf(De, elasticStrainIncrement_l);
861 sigmaElast_l.
add(stressVector_l);
867 for (
int i = 1; i <= crackStrain.
giveSize(); i++ ) {
868 sigmaCrack_l.
at(i) = Dcr.
at(i, i) * crackStrain.
at(i);
886 OOFEM_ERROR(
"Material mode %s not supported", __MaterialModeToString(mMode) );
890 if ( fabs( sigmaCrack_l.
at(i) ) > maxTau ) {
891 sigmaCrack_l.
at(i) =
sgn(sigmaCrack_l.
at(i)) * maxTau;
897 sigmaResid = sigmaElast_l;
901 for (
int i = 1; i <= sigmaResid.
giveSize(); i++ ) {
902 if ( fabs( sigmaResid.
at(i) ) > maxErr ) {
903 maxErr = fabs( sigmaResid.
at(i) );
912 OOFEM_WARNING(
"Fixed crack model: Local equilibrium not reached!, max. stress error %f, element %d\n", maxErr, gp->giveElement()->giveNumber() );
916 OOFEM_WARNING(
"Slowly converning (normal vs. shear interaction)!, iter %d/ iter limit %d, max. stress error %f, element %d\n", iterG,
iterLimitGlobal, maxErr, gp->giveElement()->giveNumber() );
923 for (
int i = 1; i <= nMaxCr; i++ ) {
926 if ( crackStrain.
at(i) != crackStrain.
at(i) ) {
938 principalDirs.
zero();
947 principalDirs.
zero();
951 }
else if ( crackStrain.
at(i) < 0. ) {
963 answer.beProductOf(sigmaL2G, sigmaElast_l);
986 crackVector.
at(i) = base.
at(i, nCrack);
1001 if ( ( mMode == _PlaneStress ) && ( nCrack == 2 ) ) {
1007 if ( nCrack <= nMaxCracks ) {
1009 if ( nMaxCracks == 3 ) {
1010 base.
at(1, 3) = base.
at(2, 1) * base.
at(3, 2) - base.
at(3, 1) * base.
at(2, 2);
1011 base.
at(2, 3) = base.
at(3, 1) * base.
at(1, 2) - base.
at(1, 1) * base.
at(3, 2);
1012 base.
at(3, 3) = base.
at(1, 1) * base.
at(2, 2) - base.
at(2, 1) * base.
at(1, 2);
1018 if ( mMode == _PlaneStress ) {
1045 if ( icrack >= 4 ) {
1063 int normal_1, normal_2;
1068 }
else if ( i == 5 ) {
1071 }
else if ( i == 6 ) {
1075 OOFEM_ERROR(
"Unexpected number for shear stress (must be either 4, 5 or 6).");
1094FCMMaterial :: isThisShearComponent(
GaussPoint *gp,
int component)
const {
1101 if (component == 3) {
1107 if (component == 4) {
1114 if (component >=4 ) {
1130FCMMaterial :: computeNormalCrackOpening(
GaussPoint *gp,
int i)
const {
1133 double crackOpening,
N;
1143 return crackOpening;
1152 double crackOpening,
N;
1162 return crackOpening;
1183 double gamma_cr_ij, gamma_cr_ik;
1186 double factor_ij, factor_ik;
1195 OOFEM_ERROR(
"Unexpected value of index i (4, 5, 6 permitted only)");
1199 if ( ( mMode == _PlaneStress ) || ( mMode == _PlaneStrain ) ) {
1201 if ( mMode == _PlaneStress ) {
1213 if ( icrack == 1 ) {
1225 slip = factor_ij * fabs(gamma_cr_ij) * status->
giveCharLength(icrack) / nCracks;
1226 }
else if ( mMode == _3dMat ) {
1227 if ( icrack == 1 ) {
1233 }
else if ( icrack == 2 ) {
1262 u_ij = factor_ij * fabs(gamma_cr_ij) * status->
giveCharLength(icrack) / nCracks;
1263 u_ik = factor_ik * fabs(gamma_cr_ik) * status->
giveCharLength(icrack) / nCracks;
1265 slip = sqrt( pow(u_ij, 2) + pow(u_ik, 2) );
1267 OOFEM_ERROR(
"Material mode %s not supported", __MaterialModeToString(mMode) );
1287FCMMaterial :: computeShearStiffnessRedistributionFactor(
GaussPoint *gp,
TimeStep *tStep,
int ithCrackPlane,
int jthCrackDirection)
const {
1294 factor_ij = D2_j / ( D2_i + D2_j );
1304 double sigX, sigY, tau, sig2;
1305 FloatArray trialStress, planeStress, princStress, crackingStrain, shearStrains, newShearStrains;
1306 FloatMatrix sigmaG2L, princCrackDir, oldBase, princCrackDirExt;
1322 }
else if ( nCrack == 3 ) {
1334 sigX = trialStress.
at(2);
1335 sigY = trialStress.
at(3);
1336 tau = trialStress.
at(4);
1338 sig2 = ( sigX + sigY ) / 2. + sqrt( ( sigX - sigY ) * ( sigX - sigY ) / 4. + tau * tau );
1345 planeStress.
at(1) = trialStress.
at(2);
1346 planeStress.
at(2) = trialStress.
at(3);
1347 planeStress.
at(3) = trialStress.
at(4);
1354 princCrackDir.
at(1, 2) = -1. * princCrackDir.
at(2, 1);
1355 princCrackDir.
at(2, 2) = princCrackDir.
at(1, 1);
1360 princCrackDirExt.
resize(3, 3);
1361 princCrackDirExt.
zero();
1362 princCrackDirExt.
at(1, 1) = 1.;
1364 for (
int i = 1; i <= 2; i++ ) {
1365 for (
int j = 1; j <= 2; j++ ) {
1366 princCrackDirExt.
at(i + 1, j + 1) = princCrackDir.
at(i, j);
1460 shearStrains.
at(1) = crackingStrain.
at(6);
1461 shearStrains.
at(2) = crackingStrain.
at(5);
1467 newShearStrains.
beTProductOf(princCrackDir, shearStrains);
1469 crackingStrain.
at(5) = newShearStrains.
at(2);
1470 crackingStrain.
at(6) = newShearStrains.
at(1);
1484 newShearStrains.
beTProductOf(princCrackDir, shearStrains);
1521 for (
int i = 1; i <= nMaxCracks; i++ ) {
1525 if ( crackStrain.
at(i) >= maxCrackStrain.
at(i) ) {
1531 if ( i == nMaxCracks ) {
1533 }
else if ( nMaxCracks > i ) {
1547 }
else if ( crackStrain.
at(i) <= 0. ) {
1572 }
else if ( crackStrain.
at(i) < maxCrackStrain.
at(i) ) {
1575 OOFEM_ERROR(
"Unexpected value of %d-th cracking strain %f ", i, crackStrain.
at(i) );
1581 for (
int i = nMaxCracks + 1; i <= crackStrain.
giveSize(); i++ ) {
1582 if ( fabs( crackStrain.
at(i) ) > maxCrackStrain.
at(i) ) {
1593FCMMaterial :: giveTotalLocalCrackedStiffnessMatrix(
FloatMatrix &answer,
1600 StructuralMaterial :: giveVoigtSymVectorMask( indx, gp->
giveMaterialMode() );
1606 for (
int i = 1; i <= dim; i++ ) {
1622FCMMaterial :: giveNormalLocalCrackedStiffnessMatrix(
FloatMatrix &answer,
1631 Dcr.
resize(nMaxCr, nMaxCr);
1633 for (
int i = 1; i <= nMaxCr; i++ ) {
1644 MatResponseMode rMode,
1655 MaterialMode mMode = gp->giveMaterialMode();
1657 int numberOfActiveCracks, nMaxCracks;
1658 double overallElasticStiffness;
1672 if ( overallElasticStiffness != ( this->
give(
'E', gp) ) ) {
1673 De.
times( overallElasticStiffness / ( this->
give(
'E', gp) ) );
1676 if ( ( rMode == ElasticStiffness ) || ( numberOfActiveCracks == 0 ) ) {
1688 if ( rMode == SecantStiffness ) {
1692 for (
int i = 1; i <= numberOfActiveCracks; i++ ) {
1696 C.
at(i, i) += 1. / E_crack;
1703 }
else if ( rMode == TangentStiffness ) {
1709 DeHelp.
resizeWithData(numberOfActiveCracks, numberOfActiveCracks);
1711 Dcr.
resize(numberOfActiveCracks, numberOfActiveCracks);
1714 for (
int i = 1; i <= numberOfActiveCracks; i++ ) {
1730 D.
resize(nMaxCracks, nMaxCracks);
1740 for (
int i = 1; i <= nMaxCracks; i++ ) {
1741 for (
int j = 1; j <= nMaxCracks; j++ ) {
1743 D.
at(i, j) =
max( D.
at(i,j), this->normalCoeffNumer * overallElasticStiffness );
1745 D.
at(i, j) =
max( D.
at(i,j), this->normalCoeffNumer * overallElasticStiffness * nu/(1-nu) );
1762 D.
at(3, 3) =
max( D.
at(3,3), this->shearCoeffNumer * G );
1778 for (
int i = 4; i <= 6; i++ ) {
1782 D.
at(i, i) =
max( D.
at(i,i), this->shearCoeffNumer * G );
1787 }
else if ( i == 5 ) {
1790 D.
at(i, i) =
max( D.
at(i,i), this->shearCoeffNumer * G );
1798 D.
at(i, i) =
max( D.
at(i,i), this->shearCoeffNumer * G );
1812 D.
at(6, 6) =
max( D.
at(6,6), this->shearCoeffNumer * G );
1820 OOFEM_ERROR(
"Material mode %s not supported", __MaterialModeToString(mMode) );
1843 StructuralMaterial :: giveReducedSymMatrixForm( answer, D, gp->giveMaterialMode() );
1848 OOFEM_ERROR(
"Material mode %s not supported", __MaterialModeToString(mMode) );
1865 if ( shearDirection == 4 ) {
1868 }
else if ( shearDirection == 5 ) {
1871 }
else if ( shearDirection == 6 ) {
1875 OOFEM_ERROR(
"Unexpected value of index i (4, 5, 6 permitted only)");
1879 if ( this->
isIntact(gp, crackA) ) {
1890 D2 = D2_1 * D2_2 / ( D2_1 + D2_2 );
1892 D2 =
min(D2_1, D2_2);
1936 if ( shearDirection == 4 ) {
1939 }
else if ( shearDirection == 5 ) {
1942 }
else if ( shearDirection == 6 ) {
1946 OOFEM_ERROR(
"Unexpected value of index i (4, 5, 6 permitted only)");
1950 if ( this->
isIntact(gp, crackA) ) {
1961 D2 = D2_1 * D2_2 / ( D2_1 + D2_2 );
1963 D2 =
min(D2_1, D2_2);
1976 StructuralMaterial :: initializeFrom(ir);
2025FCMMaterial :: giveCrackSpacing(
void)
const
2032FCMMaterial :: giveNumberOfCracksInDirection(
GaussPoint *gp,
int iCrack)
const
2035 double spacing, L,
N;
2040 if ( ( spacing > L ) || ( spacing < 0. ) ) {
2043 N = ( L / spacing );
2051FCMMaterial :: giveNumberOfCracksForShearDirection(
GaussPoint *gp,
int i)
const
2059 }
else if ( i == 5 ) {
2062 }
else if ( i == 6 ) {
2066 OOFEM_ERROR(
"Unexpected value of index i (4, 5, 6 permitted only)");
2084 if ( type == IST_CrackVector ) {
2098 for (
int i = 1; i <= status->
giveCrackDirs().giveNumberOfRows(); i++ ) {
2103 }
else if ( type == IST_2ndCrackVector ) {
2130 for (
int i = 1; i <= status->
giveCrackDirs().giveNumberOfRows(); i++ ) {
2135 }
else if ( type == IST_3rdCrackVector ) {
2158 for (
int i = 1; i <= status->
giveCrackDirs().giveNumberOfRows(); i++ ) {
2166 }
else if ( type == IST_CrackWidth ) {
2175 answer.
at(1) = width;
2177 }
else if ( type == IST_2ndCrackWidth ) {
2205 answer.
at(1) = width;
2207 }
else if ( type == IST_CrackDirs ) {
2210 for (
int i = 1; i <= 3; i++ ) {
2211 answer.
at(i) = help.
at(1, i);
2212 answer.
at(i + 3) = help.
at(2, i);
2213 answer.
at(i + 6) = help.
at(3, i);
2218 }
else if ( type == IST_CrackStatuses ) {
2226 }
else if ( type == IST_CrackStatusesTemp ) {
2234 }
else if ( type == IST_CrackStrainTensor ) {
2242 StructuralMaterial :: giveFullSymVectorForm( answer, crackStrain, gp->
giveMaterialMode() );
2246 }
else if ( type == IST_CrackSlip ) {
2255 for (
int i = 1; i <= nMaxCracks; i++ ) {
2256 answer.
at(1) =
max(answer.
at(1), this->computeShearSlipOnCrack(gp, tStep, i) );
2262 return StructuralMaterial :: giveIPValue(answer, gp, type, tStep);
2267FCMMaterial :: give3dMaterialStiffnessMatrix(MatResponseMode mode,
2278FCMMaterial :: givePlaneStressStiffMtrx(MatResponseMode mode,
2289FCMMaterial :: givePlaneStrainStiffMtrx(MatResponseMode mode,
2322 for (
int i = 1; i <= this->
nMaxCracks; i++ ) {
2356FCMMaterialStatus :: printOutputAt(FILE *file,
TimeStep *tStep)
const
2360 StructuralMaterialStatus :: printOutputAt(file, tStep);
2361 fprintf(file,
"status { ");
2363 for (
int i = 1; i <=
crackDirs.giveNumberOfColumns(); i++ ) {
2369 strcpy(s,
"JUST_INIT");
2372 strcpy(s,
"SOFTENING");
2375 strcpy(s,
"UNLO_RELO");
2378 strcpy(s,
"CLOSED");
2381 strcpy(s,
"UNKNOWN");
2385 fprintf(file,
"crack %d {status %s, crackplane is normal to { ", i, s);
2387 for (
int j = 1; j <=
crackDirs.giveNumberOfRows(); j++ ) {
2388 fprintf( file,
"%f ",
crackDirs.at(j, i) );
2391 fprintf(file,
"} ");
2395 fprintf(file,
" } ");
2399 fprintf(file,
" }\n");
2403FCMMaterialStatus :: giveNumberOfCracks() const
2421FCMMaterialStatus :: giveNumberOfTempCracks() const
2447 StructuralMaterial :: giveVoigtSymVectorMask( indx,
gp->giveMaterialMode() );
2449 for (
int i = 1; i <= 3; i++ ) {
2463FCMMaterialStatus :: setTempNormalCrackStrainVector(
FloatArray tempNormalCrackStrain)
2469 for (
int i = 1; i <= tempNormalCrackStrain.
giveSize(); i++ ) {
2477FCMMaterialStatus :: initTempStatus()
2482 StructuralMaterialStatus :: initTempStatus();
2499 StructuralMaterialStatus :: updateYourself(tStep);
2506 for (
int i = 1; i <= this->
nMaxCracks; i++ ) {
2540 StructuralMaterialStatus :: saveContext(stream, mode);
2587 StructuralMaterialStatus :: restoreContext(stream, mode);
virtual double giveCharacteristicLength(const FloatArray &normalToCrackPlane)
void setCharLength(int icrack, double val)
sets characteristic length for i-th crack
void setTempMaxCrackStrain(int icrack, double val)
sets value of the maximum crack strain for the i-th crack (temporary value)
FloatMatrix transMatrix_G2Lstress
transformation matrix converting stress from global to local coordinate system
void setL2GStressVectorTransformationMtrx(FloatMatrix t)
sets transformation matrix for stress transformation from local to global coordinate system
const FloatMatrix & giveG2LStressVectorTransformationMtrx()
returns transformation matrix for stress transformation from global to local coordinate system
const FloatMatrix & giveL2GStrainVectorTransformationMtrx()
sets transformation matrix for stress transformation from global to local coordinate system
void setTempNormalCrackStrainVector(FloatArray a)
sets temporary vector of cracking strains (normal components)
FloatArray tempMaxCrackStrains
FloatMatrix transMatrix_L2Gstress
transformation matrix converting stress from local to global coordinate system
IntArray crackStatuses
crack statuses (none, just initialized, softening, unload-reload, closed)
double giveCharLength(int icrack) const
returns characteristic length associated with i-th crack direction
double giveCrackStrain(int icrack) const
returns i-th component of the crack strain vector (equilibrated)
void setMaxCrackStrain(int icrack, double val)
sets value of the maximum crack strain for the i-th crack (equilibrated value)
void setCrackStrainVector(FloatArray a)
sets equilibrated vector of cracking strains (max 6 components)
FloatArray charLengths
Characteristic lengths computed from the crack orientation and element geometry.
FloatMatrix crackDirs
Storing direction of cracks (crack normals) in columwise format.
const IntArray & giveTempCrackStatus()
returns vector of temporary crack statuses
FloatArray tempCrackStrainVector
void setTempCrackStrain(int icrack, double val)
sets temporary value of i-th cracking strain (max 6 components)
const FloatMatrix & giveG2LStrainVectorTransformationMtrx()
sets transformation matrix for strain transformation from global to local coordinate system
const FloatArray & giveMaxCrackStrainVector()
returns vector with maximum cracking strains (max 3 components)
const FloatMatrix & giveL2GStressVectorTransformationMtrx()
sets transformation matrix for stress transformation from local to global coordinate system
int giveCrackStatus(int icrack) const
return equilibrated value of status associated with i-th crack direction
FloatArray maxCrackStrains
Max. crack strain reached in the entire previous history.
virtual int giveNumberOfCracks() const
returns number of cracks from the previous time step (equilibrated value)
void setG2LStrainVectorTransformationMtrx(FloatMatrix s)
sets transformation matrix for strain transformation from global to local coordinate system
void setTempCrackStrainVector(FloatArray a)
sets temporary vector of cracking strains (max 6 components)
void setTempCrackStatus(int icrack, int val)
sets temporary value of status for of the i-th crack
void setCrackDirs(FloatMatrix a)
sets matrix with crack directions (normal vectors)
IntArray tempCrackStatuses
virtual int giveNumberOfTempCracks() const
returns temporary number of cracks
FloatMatrix transMatrix_L2Gstrain
transformation matrix converting strain from local to global coordinate system
void setG2LStressVectorTransformationMtrx(FloatMatrix t)
sets transformation matrix for stress transformation from global to local coordinate system
FloatArray crackStrainVector
Components of crack strain vector (normal as well as shear).
double giveMaxCrackStrain(int icrack)
returns maximum crack strain for the i-th crack (equilibrated value)
double giveTempCrackStrain(int icrack) const
returns i-th component of the crack strain vector (temporary)
void setL2GStrainVectorTransformationMtrx(FloatMatrix s)
sets transformation matrix for stress transformation from global to local coordinate system
const FloatMatrix & giveCrackDirs()
returns crack directions
int nMaxCracks
number of maximum possible cracks (optional parameter)
const FloatArray & giveTempCrackStrainVector()
return temporary crack strain vector (max 6 components)
virtual int giveMaxNumberOfCracks(GaussPoint *gp)
returns maximum number of cracks associated with current mode
FloatMatrix transMatrix_G2Lstrain
transformation matrix converting strain from global to local coordinate system
const FloatArray & giveCrackStrainVector() const
return equilibrated crack strain vector (max 6 components)
virtual double givePoissonsRatio() const
returns Poisson's ratio
virtual double giveCharacteristicElementLength(GaussPoint *gp, const FloatArray &crackPlaneNormal) const
returns characteristic element length in given direction
virtual void updateCrackStatus(GaussPoint *gp) const
updates crack statuses
bool multipleCrackShear
if true = takes shear compliance of all cracks, false = only dominant crack contribution,...
virtual double giveTensileStrength(GaussPoint *gp, TimeStep *tStep) const =0
comutes tensile strength
virtual void checkSnapBack(GaussPoint *gp, TimeStep *tStep, int crack) const =0
checks possible snap-back
double shearCoeffNumer
minimum ratio of effective shear modulus vs. shear modulus - just for numerical purpose
virtual bool isIntactForShear(GaussPoint *gp, int i) const
returns true for closed or no cracks associated to given shear direction (i = 4, 5,...
virtual void giveMaterialStiffnessMatrix(FloatMatrix &answer, MatResponseMode, GaussPoint *gp, TimeStep *tStep) const
virtual double computeTotalD2Modulus(GaussPoint *gp, TimeStep *tStep, int i) const
shear modulus for a given shear direction (4, 5, 6)
virtual void giveTotalLocalCrackedStiffnessMatrix(FloatMatrix &answer, MatResponseMode rMode, GaussPoint *gp, TimeStep *tStep) const
returns local stiffness matrix in the cracks' direction (total according to the material mode)
virtual bool isIntact(GaussPoint *gp, int icrack) const
returns true for closed or no crack (i = 1, 2, 3)
virtual double giveCrackSpacing(void) const
returns either user-provided value of crack spacing or a value computed from composition
virtual double giveNumberOfCracksInDirection(GaussPoint *gp, int iCrack) const
returns number of fictiotious parallel cracks in the direction of i-th crack
virtual double computeEffectiveShearModulus(GaussPoint *gp, TimeStep *tStep, int i) const =0
returns Geff which is necessary in the global stiffness matrix
double give(int aProperty, GaussPoint *gp) const override
virtual double computeOverallElasticShearModulus(GaussPoint *gp, TimeStep *tStep) const
returns overall shear modulus
virtual double computeOverallElasticStiffness(GaussPoint *gp, TimeStep *tStep) const
returns overall Young's modulus
double normalCoeffNumer
minimum ratio of effective normal stiffness vs. overall modulus - just for numerical purpose
virtual void giveNormalLocalCrackedStiffnessMatrix(FloatMatrix &answer, MatResponseMode rMode, GaussPoint *gp, TimeStep *tStep) const
returns local stiffness matrix in the cracks' direction (only normal components)
virtual bool checkStrengthCriterion(FloatMatrix &newBase, const FloatArray &globalStress, GaussPoint *gp, TimeStep *tStep, int nCrack) const
checks if the globalStress does not exceed strength in the direction of newBase for n-th crack
virtual bool isStrengthExceeded(const FloatMatrix &base, GaussPoint *gp, TimeStep *tStep, int iCrack, double trialStress) const
compares trial stress with strength. Returns true if the strength is exceeded. Function oveloaded in ...
virtual double maxShearStress(GaussPoint *gp, TimeStep *tStep, int i) const =0
computes the maximum value of the shear stress; if the shear stress exceeds this value,...
virtual bool isThisShearComponent(GaussPoint *gp, int component) const
returns true if current component is associated with shear
virtual double computeD2ModulusForCrack(GaussPoint *gp, TimeStep *tStep, int icrack) const =0
shear modulus for a given crack plane (1, 2, 3)
IsotropicLinearElasticMaterial linearElasticMaterial
virtual void initializeCrack(GaussPoint *gp, TimeStep *tStep, FloatMatrix &base, int nCrack) const
virtual double computeShearStiffnessRedistributionFactor(GaussPoint *gp, TimeStep *tStep, int ithCrackPlane, int jthCrackDirection) const
function calculating ratio used to split shear slips on two crack planes
ElementCharSizeMethod ecsMethod
Method used for evaluation of characteristic element size.
virtual double giveCrackingModulus(MatResponseMode rMode, GaussPoint *gp, TimeStep *tStep, int i) const =0
returns stiffness in the normal direction of the i-th crack
FCMMaterial(int n, Domain *d)
double crackSpacing
value of crack spacing (allows to "have" more parallel cracks in one direction if the element size ex...
virtual double computeNumerD2ModulusForCrack(GaussPoint *gp, TimeStep *tStep, int icrack) const =0
shear modulus for numerical purpose (stiffness matrix) for a given crack plane (1,...
int nAllowedCracks
allowed number of cracks (user-defined)
Index giveSize() const
Returns the size of receiver.
void resizeWithValues(Index s, std::size_t allocChunk=0)
void beDifferenceOf(const FloatArray &a, const FloatArray &b)
void zero()
Zeroes all coefficients of receiver.
void beProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
void beTProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
void add(const FloatArray &src)
void subtract(const FloatArray &src)
void rotatedWith(const FloatMatrix &r, char mode='n')
void resizeWithData(Index, Index)
void add(const FloatMatrix &a)
void resize(Index rows, Index cols)
void beProductOf(const FloatMatrix &a, const FloatMatrix &b)
void zero()
Zeroes all coefficient of receiver.
bool beInverseOf(const FloatMatrix &src)
int giveNumberOfRows() const
Returns number of rows of receiver.
double at(std::size_t i, std::size_t j) const
bool solveForRhs(const FloatArray &b, FloatArray &answer, bool transpose=false)
void subtract(const FloatMatrix &a)
MaterialMode giveMaterialMode()
Returns corresponding material mode of receiver.
Element * giveElement()
Returns corresponding element to receiver.
bool contains(int value) const
GaussPoint * gp
Associated integration point.
virtual MaterialStatus * giveStatus(GaussPoint *gp) const
virtual bool isActivated(TimeStep *tStep) const
virtual void initTempStatus(GaussPoint *gp) const
const FloatArray & giveStrainVector() const
Returns the const pointer to receiver's strain vector.
StructuralMaterialStatus(GaussPoint *g)
Constructor. Creates new StructuralMaterialStatus with IntegrationPoint g.
const FloatArray & giveStressVector() const
Returns the const pointer to receiver's stress vector.
void letTempStressVectorBe(const FloatArray &v)
Assigns tempStressVector to given vector v.
void letTempStrainVectorBe(const FloatArray &v)
Assigns tempStrainVector to given vector v.
static FloatMatrixF< 3, 3 > givePlaneStressVectorTranformationMtrx(const FloatMatrixF< 2, 2 > &base, bool transpose=false)
static FloatMatrixF< 6, 6 > giveStressVectorTranformationMtrx(const FloatMatrixF< 3, 3 > &base, bool transpose=false)
StructuralMaterial(int n, Domain *d)
virtual void giveStiffnessMatrix(FloatMatrix &answer, MatResponseMode mode, GaussPoint *gp, TimeStep *tStep) const
static void computePrincipalValDir(FloatArray &answer, FloatMatrix &dir, const FloatArray &s, stressStrainPrincMode mode)
static FloatMatrixF< 6, 6 > giveStrainVectorTranformationMtrx(const FloatMatrixF< 3, 3 > &base, bool transpose=false)
void giveStressDependentPartOfStrainVector(FloatArray &answer, GaussPoint *gp, const FloatArray &reducedStrainVector, TimeStep *tStep, ValueModeType mode) const
static FloatMatrixF< 3, 3 > give2DStrainVectorTranformationMtrx(const FloatMatrixF< 2, 2 > &base, bool transpose=false)
#define OOFEM_WARNING(...)
#define _IFT_FCM_multipleCrackShear
#define _IFT_FCM_nAllowedCracks
#define _IFT_FCM_shearCoeffNumer
#define _IFT_FCM_crackSpacing
#define fcm_THRESHOLD_CRACK_STRAIN
#define _IFT_FCM_normalCoeffNumer
FloatArrayF< N > min(const FloatArrayF< N > &a, const FloatArrayF< N > &b)
FloatArrayF< N > max(const FloatArrayF< N > &a, const FloatArrayF< N > &b)
@ principal_stress
For computing principal stresses.
double sgn(double i)
Returns the signum of given value (if value is < 0 returns -1, otherwise returns 1).
@ ECSM_ProjectionCentered
FloatArrayF< N > zeros()
For more readable code.