RankTwoTensor TensorMechanicsPlasticTensile::dyieldFunction_dstress(const RankTwoTensor & stress, Real /*intnl*/) const { Real mean_stress = stress.trace() / 3.0; RankTwoTensor dmean_stress = stress.dtrace() / 3.0; Real sin3Lode = stress.sin3Lode(_lode_cutoff, 0); if (sin3Lode <= _sin3tt) { // the non-edge-smoothed version std::vector<Real> eigvals; std::vector<RankTwoTensor> deigvals; stress.dsymmetricEigenvalues(eigvals, deigvals); Real denom = std::sqrt(smooth(stress) + Utility::pow<2>(eigvals[2] - mean_stress)); return dmean_stress + (0.5 * dsmooth(stress) * dmean_stress + (eigvals[2] - mean_stress) * (deigvals[2] - dmean_stress)) / denom; } else { // the edge-smoothed version Real kk = _aaa + _bbb * sin3Lode + _ccc * Utility::pow<2>(sin3Lode); RankTwoTensor dkk = (_bbb + 2.0 * _ccc * sin3Lode) * stress.dsin3Lode(_lode_cutoff); Real sibar2 = stress.secondInvariant(); RankTwoTensor dsibar2 = stress.dsecondInvariant(); Real denom = std::sqrt(smooth(stress) + sibar2 * Utility::pow<2>(kk)); return dmean_stress + (0.5 * dsmooth(stress) * dmean_stress + 0.5 * dsibar2 * Utility::pow<2>(kk) + sibar2 * kk * dkk) / denom; } }
/** * Second derivative of Eginvalues are compared with finite difference method * This method checks all the elements in RankFourTensor **/ void RankTwoEigenRoutinesTest::d2symmetricEigenvaluesTest2() { Real ep = 1E-5; // small finite-difference parameter std::vector<Real> eigvals, eigvalsep, eigvalsep_minus; // eigenvalues in ascending order provided by RankTwoTensor std::vector<RankTwoTensor> deriv,derivep, derivep_minus; // derivatives of these eigenvalues provided by RankTwoTensor std::vector<RankFourTensor> second_deriv; RankTwoTensor mep; // the RankTwoTensor with successive entries shifted by ep _m2.d2symmetricEigenvalues(second_deriv); _m2.dsymmetricEigenvalues(eigvals, deriv); mep = _m2; for (unsigned int m = 0; m < 3; m++) for (unsigned i = 0; i < 3; i++) for (unsigned j = 0; j < 3; j++) { for (unsigned int k=0; k<3; k++) for (unsigned int l=0; l<3; l++) { mep(k, l) += ep; mep.dsymmetricEigenvalues(eigvalsep, derivep); CPPUNIT_ASSERT_DOUBLES_EQUAL((derivep[m](i, j) - deriv[m](i, j))/ep, second_deriv[m](i, j, k, l), ep); mep(k, l) -= ep; } } _m3.d2symmetricEigenvalues(second_deriv); _m3.dsymmetricEigenvalues(eigvals, deriv); mep = _m3; for (unsigned int m = 0; m < 3; m++) for (unsigned i = 0; i < 3; i++) for (unsigned j = 0; j < 3; j++) { for (unsigned int k=0; k<3; k++) for (unsigned int l=0; l<3; l++) { mep(k, l) += ep; mep.dsymmetricEigenvalues(eigvalsep, derivep); CPPUNIT_ASSERT_DOUBLES_EQUAL((derivep[m](i, j) - deriv[m](i, j))/ep, second_deriv[m](i, j, k, l), ep); mep(k, l) -= ep; } } }
RankFourTensor TensorMechanicsPlasticTensile::dflowPotential_dstress(const RankTwoTensor & stress, const Real & intnl) const { Real mean_stress = stress.trace()/3.0; RankTwoTensor dmean_stress = stress.dtrace()/3.0; Real sin3Lode = stress.sin3Lode(_lode_cutoff, 0); if (sin3Lode <= _sin3tt) { // the non-edge-smoothed version std::vector<Real> eigvals; std::vector<RankTwoTensor> deigvals; std::vector<RankFourTensor> d2eigvals; stress.dsymmetricEigenvalues(eigvals, deigvals); stress.d2symmetricEigenvalues(d2eigvals); Real denom = std::sqrt(_small_smoother2 + std::pow(eigvals[2] - mean_stress, 2)); RankFourTensor dr_dstress = (eigvals[2] - mean_stress)*d2eigvals[2]/denom; for (unsigned i = 0 ; i < 3 ; ++i) for (unsigned j = 0 ; j < 3 ; ++j) for (unsigned k = 0 ; k < 3 ; ++k) for (unsigned l = 0 ; l < 3 ; ++l) dr_dstress(i, j, k, l) += (1 - std::pow((eigvals[2] - mean_stress)/denom, 2))*(deigvals[2](i, j) - dmean_stress(i, j))*(deigvals[2](k, l) - dmean_stress(k, l))/denom; return dr_dstress; } else { // the edge-smoothed version RankTwoTensor dsin3Lode = stress.dsin3Lode(_lode_cutoff); Real kk = _aaa + _bbb*sin3Lode + _ccc*std::pow(sin3Lode, 2); RankTwoTensor dkk = (_bbb + 2*_ccc*sin3Lode)*dsin3Lode; RankFourTensor d2kk = (_bbb + 2*_ccc*sin3Lode)*stress.d2sin3Lode(_lode_cutoff); for (unsigned i = 0 ; i < 3 ; ++i) for (unsigned j = 0 ; j < 3 ; ++j) for (unsigned k = 0 ; k < 3 ; ++k) for (unsigned l = 0 ; l < 3 ; ++l) d2kk(i, j, k, l) += 2*_ccc*dsin3Lode(i, j)*dsin3Lode(k, l); Real sibar2 = stress.secondInvariant(); RankTwoTensor dsibar2 = stress.dsecondInvariant(); RankFourTensor d2sibar2 = stress.d2secondInvariant(); Real denom = std::sqrt(_small_smoother2 + sibar2*std::pow(kk, 2)); RankFourTensor dr_dstress = (0.5*d2sibar2*std::pow(kk, 2) + sibar2*kk*d2kk)/denom; for (unsigned i = 0 ; i < 3 ; ++i) for (unsigned j = 0 ; j < 3 ; ++j) for (unsigned k = 0 ; k < 3 ; ++k) for (unsigned l = 0 ; l < 3 ; ++l) { dr_dstress(i, j, k, l) += (dsibar2(i, j)*dkk(k, l)*kk + dkk(i, j)*dsibar2(k, l)*kk + sibar2*dkk(i, j)*dkk(k, l))/denom; dr_dstress(i, j, k, l) -= (0.5*dsibar2(i, j)*std::pow(kk, 2) + sibar2*kk*dkk(i, j))*(0.5*dsibar2(k, l)*std::pow(kk, 2) + sibar2*kk*dkk(k, l))/std::pow(denom, 3); } return dr_dstress; } }
void TensorMechanicsPlasticMohrCoulombMulti::dflowPotential_dintnlV(const RankTwoTensor & stress, Real intnl, std::vector<RankTwoTensor> & dr_dintnl) const { const Real cos_angle = std::cos(psi(intnl)); const Real dsin_angle = cos_angle*dpsi(intnl); std::vector<Real> eigvals; std::vector<RankTwoTensor> deigvals; stress.dsymmetricEigenvalues(eigvals, deigvals); if (eigvals[0] > eigvals[1] - 0.1*_shift || eigvals[1] > eigvals[2] - 0.1*_shift) perturbStress(stress, eigvals, deigvals); dr_dintnl.resize(6); dr_dintnl[0] = dr_dintnl[1] = 0.5*(deigvals[0] + deigvals[1])*dsin_angle; dr_dintnl[2] = dr_dintnl[3] = 0.5*(deigvals[0] + deigvals[2])*dsin_angle; dr_dintnl[4] = dr_dintnl[5] = 0.5*(deigvals[1] + deigvals[2])*dsin_angle; }
void TensorMechanicsPlasticMohrCoulombMulti::df_dsig(const RankTwoTensor & stress, Real sin_angle, std::vector<RankTwoTensor> & df) const { std::vector<Real> eigvals; std::vector<RankTwoTensor> deigvals; stress.dsymmetricEigenvalues(eigvals, deigvals); if (eigvals[0] > eigvals[1] - 0.1*_shift || eigvals[1] > eigvals[2] - 0.1*_shift) perturbStress(stress, eigvals, deigvals); df.resize(6); df[0] = 0.5*(deigvals[0] - deigvals[1]) + 0.5*(deigvals[0] + deigvals[1])*sin_angle; df[1] = 0.5*(deigvals[1] - deigvals[0]) + 0.5*(deigvals[0] + deigvals[1])*sin_angle; df[2] = 0.5*(deigvals[0] - deigvals[2]) + 0.5*(deigvals[0] + deigvals[2])*sin_angle; df[3] = 0.5*(deigvals[2] - deigvals[0]) + 0.5*(deigvals[0] + deigvals[2])*sin_angle; df[4] = 0.5*(deigvals[1] - deigvals[2]) + 0.5*(deigvals[1] + deigvals[2])*sin_angle; df[5] = 0.5*(deigvals[2] - deigvals[1]) + 0.5*(deigvals[1] + deigvals[2])*sin_angle; }
void TensorMechanicsPlasticTensileMulti::dyieldFunction_dstressV(const RankTwoTensor & stress, const Real & /*intnl*/, std::vector<RankTwoTensor> & df_dstress) const { std::vector<Real> eigvals; stress.dsymmetricEigenvalues(eigvals, df_dstress); if (eigvals[0] > eigvals[1] - 0.1*_shift || eigvals[1] > eigvals[2] - 0.1*_shift) { Real small_perturbation; RankTwoTensor shifted_stress = stress; while (eigvals[0] > eigvals[1] - 0.1*_shift || eigvals[1] > eigvals[2] - 0.1*_shift) { for (unsigned i = 0; i < 3; ++i) for (unsigned j = 0; j <= i; ++j) { small_perturbation = 0.1*_shift*2*(MooseRandom::rand() - 0.5); shifted_stress(i, j) += small_perturbation; shifted_stress(j, i) += small_perturbation; } shifted_stress.dsymmetricEigenvalues(eigvals, df_dstress); } } }
RankFourTensor TensorMechanicsPlasticTensile::dflowPotential_dstress(const RankTwoTensor & stress, Real /*intnl*/) const { Real mean_stress = stress.trace() / 3.0; RankTwoTensor dmean_stress = stress.dtrace() / 3.0; Real sin3Lode = stress.sin3Lode(_lode_cutoff, 0); if (sin3Lode <= _sin3tt) { // the non-edge-smoothed version std::vector<Real> eigvals; std::vector<RankTwoTensor> deigvals; std::vector<RankFourTensor> d2eigvals; stress.dsymmetricEigenvalues(eigvals, deigvals); stress.d2symmetricEigenvalues(d2eigvals); Real denom = std::sqrt(smooth(stress) + Utility::pow<2>(eigvals[2] - mean_stress)); Real denom3 = Utility::pow<3>(denom); RankTwoTensor numer_part = deigvals[2] - dmean_stress; RankTwoTensor numer_full = 0.5 * dsmooth(stress) * dmean_stress + (eigvals[2] - mean_stress) * numer_part; Real d2smooth_over_denom = d2smooth(stress) / denom; RankFourTensor dr_dstress = (eigvals[2] - mean_stress) * d2eigvals[2] / denom; for (unsigned i = 0; i < 3; ++i) for (unsigned j = 0; j < 3; ++j) for (unsigned k = 0; k < 3; ++k) for (unsigned l = 0; l < 3; ++l) { dr_dstress(i, j, k, l) += 0.5 * d2smooth_over_denom * dmean_stress(i, j) * dmean_stress(k, l); dr_dstress(i, j, k, l) += numer_part(i, j) * numer_part(k, l) / denom; dr_dstress(i, j, k, l) -= numer_full(i, j) * numer_full(k, l) / denom3; } return dr_dstress; } else { // the edge-smoothed version RankTwoTensor dsin3Lode = stress.dsin3Lode(_lode_cutoff); Real kk = _aaa + _bbb * sin3Lode + _ccc * Utility::pow<2>(sin3Lode); RankTwoTensor dkk = (_bbb + 2.0 * _ccc * sin3Lode) * dsin3Lode; RankFourTensor d2kk = (_bbb + 2.0 * _ccc * sin3Lode) * stress.d2sin3Lode(_lode_cutoff); for (unsigned i = 0; i < 3; ++i) for (unsigned j = 0; j < 3; ++j) for (unsigned k = 0; k < 3; ++k) for (unsigned l = 0; l < 3; ++l) d2kk(i, j, k, l) += 2.0 * _ccc * dsin3Lode(i, j) * dsin3Lode(k, l); Real sibar2 = stress.secondInvariant(); RankTwoTensor dsibar2 = stress.dsecondInvariant(); RankFourTensor d2sibar2 = stress.d2secondInvariant(); Real denom = std::sqrt(smooth(stress) + sibar2 * Utility::pow<2>(kk)); Real denom3 = Utility::pow<3>(denom); Real d2smooth_over_denom = d2smooth(stress) / denom; RankTwoTensor numer_full = 0.5 * dsmooth(stress) * dmean_stress + 0.5 * dsibar2 * kk * kk + sibar2 * kk * dkk; RankFourTensor dr_dstress = (0.5 * d2sibar2 * Utility::pow<2>(kk) + sibar2 * kk * d2kk) / denom; for (unsigned i = 0; i < 3; ++i) for (unsigned j = 0; j < 3; ++j) for (unsigned k = 0; k < 3; ++k) for (unsigned l = 0; l < 3; ++l) { dr_dstress(i, j, k, l) += 0.5 * d2smooth_over_denom * dmean_stress(i, j) * dmean_stress(k, l); dr_dstress(i, j, k, l) += (dsibar2(i, j) * dkk(k, l) * kk + dkk(i, j) * dsibar2(k, l) * kk + sibar2 * dkk(i, j) * dkk(k, l)) / denom; dr_dstress(i, j, k, l) -= numer_full(i, j) * numer_full(k, l) / denom3; } return dr_dstress; } }