void YieldPolynomial::computeYieldFunction(){ computeYieldFunction(yield.size()); }
void IntMatBilinearCZ :: giveFirstPKTraction_3d(FloatArray &answer, GaussPoint *gp, const FloatArray &jump, const FloatMatrix &F, TimeStep *tStep) { IntMatBilinearCZStatus *status = static_cast< IntMatBilinearCZStatus * >( this->giveStatus(gp) ); status->mJumpNew = jump; FloatArray jumpInc; jumpInc.beDifferenceOf(status->mJumpNew, status->mJumpOld); FloatArray tractionTrial = status->mTractionOld; tractionTrial.add(mPenaltyStiffness, jumpInc); double TTrNormal = tractionTrial.at(3); double TTrTang = sqrt( pow(tractionTrial.at(1), 2.0) + pow(tractionTrial.at(2), 2.0) ); double phiTr = computeYieldFunction(TTrNormal, TTrTang); const double damageTol = 1.0e-6; if ( status->mDamageOld > ( 1.0 - damageTol ) ) { status->mDamageNew = 1.0; status->mPlastMultIncNew = 0.0; answer.resize(3); answer.zero(); status->mTractionNew = answer; status->letTempJumpBe(jump); status->letTempFirstPKTractionBe(answer); status->letTempTractionBe(answer); return; } answer = tractionTrial; if ( phiTr < 0.0 ) { status->mDamageNew = status->mDamageOld; status->mPlastMultIncNew = 0.0; answer.beScaled( ( 1.0 - status->mDamageNew ), answer ); status->mTractionNew = answer; status->letTempJumpBe(jump); status->letTempFirstPKTractionBe(answer); status->letTempTractionBe(answer); return; } else { // Iterate to find plastic strain increment. int maxIter = 50; int minIter = 1; double absTol = 1.0e-9; // Absolute error tolerance double relTol = 1.0e-9; // Relative error tolerance double eps = 1.0e-12; // Small value for perturbation when computing numerical Jacobian double plastMultInc = 0.0; double initialRes = 0.0; for ( int iter = 0; iter < maxIter; iter++ ) { // Evaluate residual (i.e. yield function) computeTraction(answer, tractionTrial, plastMultInc); double TNormal = answer.at(3); double TTang = sqrt( pow(answer.at(1), 2.0) + pow(answer.at(2), 2.0) ); double phi = computeYieldFunction(TNormal, TTang); // if(iter > 20) { // printf("iter: %d res: %e\n", iter, fabs(phi) ); // } if ( iter == 0 ) { initialRes = fabs(phi); initialRes = max(initialRes, 1.0e-12); } if ( (iter >= minIter && fabs(phi) < absTol) || ( iter >= minIter && ( fabs(phi) / initialRes ) < relTol ) ) { // Add damage evolution double S = mGIc / mSigmaF; status->mPlastMultIncNew = plastMultInc; double damageInc = status->mPlastMultIncNew / S; status->mDamageNew = status->mDamageOld + damageInc; if ( status->mDamageNew > 1.0 ) { status->mDamageNew = 1.0; } if(mSemiExplicit) { // computeTraction(answer, tractionTrial, status->mPlastMultIncOld); answer.beScaled( ( 1.0 - status->mDamageOld ), answer ); } else { answer.beScaled( ( 1.0 - status->mDamageNew ), answer ); } status->mTractionNew = answer; // Jim status->letTempJumpBe(jump); status->letTempFirstPKTractionBe(answer); status->letTempTractionBe(answer); return; } // Numerical Jacobian FloatArray tractionPert(3); computeTraction(tractionPert, tractionTrial, plastMultInc + eps); double TNormalPert = tractionPert.at(3); double TTangPert = sqrt( pow(tractionPert.at(1), 2.0) + pow(tractionPert.at(2), 2.0) ); double phiPert = computeYieldFunction(TNormalPert, TTangPert); double Jac = ( phiPert - phi ) / eps; plastMultInc -= ( 1.0 / Jac ) * phi; } } OOFEM_ERROR("No convergence in."); }
YieldPolynomial::YieldPolynomial(YieldCurve& yield_){ yield=yield_; computeYieldFunction(); }