//send back the stress const XC::Vector &XC::DruckerPragerPlaneStrain::getStress() { stress(0) = mSigma(0); stress(1) = mSigma(1); stress(2) = mSigma(3); return stress; }
int DruckerPrager::updateElasticParam( ) { double Sigma_mean = 0.0; if ( mElastFlag == 1 && mFlag == 1){ Sigma_mean = -one3*(mSigma(0)+mSigma(1)+mSigma(2)); if (Sigma_mean < 0.0) Sigma_mean = 0.0; // prevents modulus update for cases where tension exists mK = mKref * pow(1+(Sigma_mean/mPatm), 0.5); mG = mGref * pow(1+(Sigma_mean/mPatm), 0.5); mCe = mK * mIIvol + 2*mG*mIIdev; mFlag = 0; //opserr << "Plastic Integrator -->" << "K = " << mK << " G =" << mG << endln; } else if ( mElastFlag != 1 ){ mFlag = 1; } return 0; }
void QPSolver::convertQFormat() { int numCols = mSigma.cols(); int numRows = mSigma.rows(); mQSubi.clear(); mQSubj.clear(); mQValues.clear(); for (int ithRow = 0; ithRow < numRows; ++ithRow) { for (int ithCol = 0; ithCol < numCols; ++ithCol) { if (ithRow < ithCol || mSigma(ithRow, ithCol) == 0.0) continue; mQSubi.push_back(ithRow); mQSubj.push_back(ithCol); mQValues.push_back(mSigma(ithRow, ithCol)); } } }
//--------------------Plasticity------------------------------------- //plasticity integration routine void DruckerPrager:: plastic_integrator( ) { bool okay; // boolean variable to ensure satisfaction of multisurface kuhn tucker conditions double f1; double f2; double norm_eta; double Invariant_1; double Invariant_ep; double norm_ep; double norm_dev_ep; Vector epsilon_e(6); Vector s(6); Vector eta(6); Vector dev_ep(6); Vector Jact(2); double fTOL; double gTOL; fTOL = 0.0; gTOL = -1.0e-10; double NormCep; double alpha1; // hardening parameter for DP surface double alpha2; // hardening parameter for tension cut-off Vector n(6); // normal to the yield surface in strain space Vector R(2); // residual vector Vector gamma(2); // vector of consistency parameters Vector dgamma(2); // incremental vector of consistency parameters Matrix g(2,2); // jacobian of the corner region (return map) Matrix g_contra(2,2); // inverse of jacobian of the corner region // set trial state: // epsilon_n1_p_trial = ..._n1_p = ..._n_p mEpsilon_n1_p = mEpsilon_n_p; // alpha1_n+1_trial mAlpha1_n1 = mAlpha1_n; // alpha2_n+1_trial mAlpha2_n1 = mAlpha2_n; // beta_n+1_trial mBeta_n1 = mBeta_n; // epsilon_elastic = epsilon_n+1 - epsilon_n_p epsilon_e = mEpsilon - mEpsilon_n1_p; // trial stress mSigma = mCe*epsilon_e; // deviator stress tensor: s = 2G * IIdev * epsilon_e //I1_trial Invariant_1 = ( mSigma(0) + mSigma(1) + mSigma(2) ); // s_n+1_trial s = mSigma - (Invariant_1/3.0)*mI1; //eta_trial = s_n+1_trial - beta_n; eta = s - mBeta_n; // compute yield function value (contravariant norm) norm_eta = sqrt(eta(0)*eta(0) + eta(1)*eta(1) + eta(2)*eta(2) + 2*(eta(3)*eta(3) + eta(4)*eta(4) + eta(5)*eta(5))); // f1_n+1_trial f1 = norm_eta + mrho*Invariant_1 - root23*Kiso(mAlpha1_n1); // f2_n+1_trial f2 = Invariant_1 - T(mAlpha2_n1); // update elastic bulk and shear moduli this->updateElasticParam(); // check trial state int count = 1; if ((f1<=fTOL) && (f2<=fTOL) || mElastFlag < 2) { okay = true; // trial state = elastic state - don't need to do any updates. mCep = mCe; count = 0; // set state variables for recorders Invariant_ep = mEpsilon_n1_p(0)+mEpsilon_n1_p(1)+mEpsilon_n1_p(2); norm_ep = sqrt(mEpsilon_n1_p(0)*mEpsilon_n1_p(0) + mEpsilon_n1_p(1)*mEpsilon_n1_p(1) + mEpsilon_n1_p(2)*mEpsilon_n1_p(2) + 0.5*(mEpsilon_n1_p(3)*mEpsilon_n1_p(3) + mEpsilon_n1_p(4)*mEpsilon_n1_p(4) + mEpsilon_n1_p(5)*mEpsilon_n1_p(5))); dev_ep = mEpsilon_n1_p - one3*Invariant_ep*mI1; norm_dev_ep = sqrt(dev_ep(0)*dev_ep(0) + dev_ep(1)*dev_ep(1) + dev_ep(2)*dev_ep(2) + 0.5*(dev_ep(3)*dev_ep(3) + dev_ep(4)*dev_ep(4) + dev_ep(5)*dev_ep(5))); mState(0) = Invariant_1; mState(1) = norm_eta; mState(2) = Invariant_ep; mState(3) = norm_dev_ep; mState(4) = norm_ep; return; } else { // plastic correction required okay = false; // determine number of active surfaces. size & fill Jact if ( (f1 > fTOL ) && (f2 <= fTOL) ) { // f1 surface only Jact(0) = 1; Jact(1) = 0; } else if ( (f1 <= fTOL ) && (f2 > fTOL) ) { // f2 surface only Jact(0) = 0; Jact(1) = 1; } else if ( (f1 > fTOL ) && (f2 > fTOL) ) { // both surfaces active Jact(0) = 1; Jact(1) = 1; } } //-----------------MultiSurface Placity Return Map-------------------------------------- while (!okay) { alpha1 = mAlpha1_n; alpha2 = mAlpha2_n; // n = eta / norm_eta; (contravaraint) if (norm_eta < 1.0e-13) { n.Zero(); } else { n = eta/norm_eta; } // initialize R, gamma1, gamma2, dgamma1, dgamma2 = 0 R.Zero(); gamma.Zero(); dgamma.Zero(); // initialize g such that det(g) = 1 g(0,0) = 1; g(1,1) = 1; g(1,0) = 0; g(0,1) = 0; // Newton procedure to compute nonlinear gamma1 and gamma2 //initialize terms for (int i = 0; i < 2; i++) { if (Jact(i) == 1) { R(0) = norm_eta - (2*mG + two3*mHprime)*gamma(0) + mrho*Invariant_1 - 9*mK*mrho*mrho_bar*gamma(0) - 9*mK*mrho*gamma(1) - root23*Kiso(alpha1); g(0,0) = -2*mG - two3*(mHprime + Kisoprime(alpha1)) - 9*mK*mrho*mrho_bar; } else if (Jact(i) == 2) { R(1) = Invariant_1 - 9*mK*mrho_bar*gamma(0) - 9*mK*gamma(1) - T(alpha2); g(1,1) = -9*mK + mdelta2*T(alpha2); } } if (Jact(0) == 1 && Jact(1) == 1) { g(0,1) = -9*mK*mrho; g(1,0) = mrho_bar*(-9*mK + mdelta2*T(alpha2)); } g.Invert(g_contra); // iteration counter int m = 0; //iterate while ((fabs(R.Norm()) > 1e-10) && (m < 10)) { dgamma = -1*g_contra * R; gamma += dgamma; //update alpha1 and alpha2 alpha1 = mAlpha1_n + root23*gamma(0); alpha2 = mAlpha2_n + mrho_bar*gamma(0) + gamma(1); // reset g & R matrices g(0,0) = 1; g(1,1) = 1; g(1,0) = 0; g(0,1) = 0; R.Zero(); for (int i = 0; i < 2; i++) { if (Jact(i) == 1) { R(0) = norm_eta - (2*mG + two3*mHprime)*gamma(0) + mrho*Invariant_1 - 9*mK*mrho*mrho_bar*gamma(0) - 9*mK*mrho*gamma(1) - root23*Kiso(alpha1); g(0,0) = -2*mG - two3*(mHprime + Kisoprime(alpha1)) - 9*mK*mrho*mrho_bar; } else if (Jact(i) == 2) { R(1) = Invariant_1 - 9*mK*mrho_bar*gamma(0) - 9*mK*gamma(1) - T(alpha2); g(1,1) = -9*mK + mdelta2*T(alpha2); } } if (Jact(0) == 1 && Jact(1) == 1) { g(0,1) = -9*mK*mrho; g(1,0) = mrho_bar*(-9*mK + mdelta2*T(alpha2)); } g.Invert(g_contra); m++; } // check maintain Kuhn-Tucker conditions f1 = norm_eta - (2*mG + two3*mHprime)*gamma(0) + mrho*Invariant_1 -9*mK*mrho*mrho_bar*gamma(0) - 9*mK*mrho*gamma(1) - root23*Kiso(alpha1); f2 = Invariant_1 - 9*mK*mrho_bar*gamma(0) - 9*mK*gamma(1) - T(alpha2); if ( count > 100 ) { okay = true; break; } // check active surfaces if ((Jact(0) == 1) && (Jact(1) == 0)) { // f2 may be > or < f2_tr because of softening of f2 related to alpha1 if (f2 >= fTOL) { // okay = false; Jact(0) = 1; Jact(1) = 1; count += 1; } else { okay = true; } } else if ((Jact(0) == 0) && (Jact(1) == 1)) { // f1 will always be less than f1_tr okay = true; } else if ((Jact(0) == 1) && (Jact(1) == 1)) { if ((gamma(0) <= gTOL) && (gamma(1) > gTOL)){ // okay = false; Jact(0) = 0; Jact(1) = 1; count += 1; } else if ((gamma(0) > gTOL) && (gamma(1) <= gTOL)){ // okay = false; Jact(0) = 1; Jact(1) = 0; count += 1; } else if ((gamma(0) > gTOL) && (gamma(1) > gTOL)) { okay = true; } } if ( (count > 3) && (!okay) ) { Jact(0) = 1; Jact(1) = 1; count += 100; } if ( count > 3 ) { opserr << "Jact = " << Jact; opserr << "count = " << count << endln; } } // end of while(!okay) loop //update everything and exit! Vector b1(6); Vector b2(6); Vector n_covar(6); Vector temp1(6); Vector temp2(6); // update alpha1 and alpha2 mAlpha1_n1 = alpha1; mAlpha2_n1 = alpha2; //update epsilon_n1_p //first calculate n_covar // n_a = G_ab * n^b = covariant n_covar(0) = n(0); n_covar(1) = n(1); n_covar(2) = n(2); n_covar(3) = 2*n(3); n_covar(4) = 2*n(4); n_covar(5) = 2*n(5); mEpsilon_n1_p = mEpsilon_n_p + (mrho_bar*gamma(0) + gamma(1))*mI1 + gamma(0)*n_covar; Invariant_ep = mEpsilon_n1_p(0)+mEpsilon_n1_p(1)+mEpsilon_n1_p(2); norm_ep = sqrt(mEpsilon_n1_p(0)*mEpsilon_n1_p(0) + mEpsilon_n1_p(1)*mEpsilon_n1_p(1) + mEpsilon_n1_p(2)*mEpsilon_n1_p(2) + 0.5*(mEpsilon_n1_p(3)*mEpsilon_n1_p(3) + mEpsilon_n1_p(4)*mEpsilon_n1_p(4) + mEpsilon_n1_p(5)*mEpsilon_n1_p(5))); dev_ep = mEpsilon_n1_p - one3*Invariant_ep*mI1; norm_dev_ep = sqrt(dev_ep(0)*dev_ep(0) + dev_ep(1)*dev_ep(1) + dev_ep(2)*dev_ep(2) + 0.5*(dev_ep(3)*dev_ep(3) + dev_ep(4)*dev_ep(4) + dev_ep(5)*dev_ep(5))); // update sigma mSigma -= (3*mK*mrho_bar*gamma(0) + 3*mK*gamma(1))*mI1 + 2*mG*gamma(0)*n; s -= 2*mG*gamma(0) * n; Invariant_1 -= 9*mK*mrho_bar*gamma(0) + 9*mK*gamma(1); //mSigma = s + Invariant_1/3.0 * mI1; //update beta_n1 mBeta_n1 = mBeta_n - (two3*mHprime*gamma(0))*n; //eta_n+1 = s_n+1 - beta_n+1; eta = s - mBeta_n1; norm_eta = sqrt(eta(0)*eta(0) + eta(1)*eta(1) + eta(2)*eta(2) + 2*(eta(3)*eta(3) + eta(4)*eta(4) + eta(5)*eta(5))); // update Cep // note: Cep is contravariant if ((Jact(0) == 1) && (Jact(1) == 0)) { b1 = 2*mG*n + 3*mK*mrho*mI1; b2.Zero(); } else if ((Jact(0) == 0) && (Jact(1) == 1)){ b1.Zero(); b2 = 3*mK*mI1; } else if ((Jact(0) == 1) && (Jact(1) == 1)){ b1 = 2*mG*n + 3*mK*mrho*mI1; b2 = 3*mK*mI1; } temp1 = g_contra(0,0)*b1 + g_contra(0,1)*b2; temp2 = mrho_bar*temp1 + g_contra(1,0)*b1 + g_contra(1,1)*b2; NormCep = 0.0; for (int i = 0; i < 6; i++){ for (int j = 0; j < 6; j++) { mCep(i,j) = mCe(i,j) + 3*mK * mI1(i)*temp2(j) + 2*mG * n(i)*temp1(j) - 4*mG*mG/norm_eta*gamma(0) * (mIIdev(i,j) - n(i)*n(j)); NormCep += mCep(i,j)*mCep(i,j); } } if ( NormCep < 1e-10){ mCep = 1.0e-3 * mCe; opserr << "NormCep = " << NormCep << endln; } mState(0) = Invariant_1; mState(1) = norm_eta; mState(2) = Invariant_ep; mState(3) = norm_dev_ep; mState(4) = norm_ep; return; }
void QPSolver::preSolve() { if (mMethodType == SM_Normal) { mU = MatrixXd::Identity(mNumVar, mNumVar); mCU = mc; mSigma = mQ; mAU = mA; } else if (mMethodType == SM_SVD) { JacobiSVD<MatrixXd> svd(mQ, ComputeThinU | ComputeThinV); mU = svd.matrixU(); VectorXd singularValues = svd.singularValues(); mSigma = MatrixXd::Zero(mNumVar, mNumVar); for (int i = 0; i < singularValues.size(); ++i) { mSigma(i, i) = singularValues[i]; } MatrixXd uTrans = mU.transpose(); mCU = uTrans * mc; mAU = mA * mU; //MatrixXd recoveredQ = mU * mSigma * uTrans; //for (int i = 0; i < recoveredQ.rows(); ++i) //{ // for (int j = 0; j < recoveredQ.cols(); ++j) // { // if (abs((recoveredQ(i, j) - mQ(i, j)) / mQ(i, j)) > 1e-6) // LOG(INFO) << "(" << i << ", " << j << "): " << recoveredQ(i, j) << ": " << mQ(i, j); // } //} } else if (mMethodType == SM_Separable) { const MatrixXd& lhs = mLhs; int numRows = lhs.rows(); mNumVarOriginal = mNumVar; mNumConOriginal = mNumCon; mNumVar += numRows; mNumCon += numRows; mSigma = MatrixXd::Zero(mNumVar, mNumVar); mSigma.block(mNumVarOriginal, mNumVarOriginal, numRows, numRows) = MatrixXd::Identity(numRows, numRows); mCU = VectorXd::Zero(mNumVar); mCU.head(mNumVarOriginal) = mc.head(mNumVarOriginal); mAU = MatrixXd::Zero(mNumCon, mNumVar); if (mNumConOriginal) mAU.block(0, 0, mNumConOriginal, mNumVarOriginal) = mA; mAU.block(mNumConOriginal, 0, numRows, mNumVarOriginal) = lhs; mAU.block(mNumConOriginal, mNumVarOriginal, numRows, numRows) = -MatrixXd::Identity(numRows, numRows); VectorXd newLbc = VectorXd::Zero(mNumCon); VectorXd newUbc = VectorXd::Zero(mNumCon); VectorXi newBLowerBounded = VectorXi::Zero(mNumCon); VectorXi newBUpperBounded = VectorXi::Zero(mNumCon); if (mNumConOriginal) { newLbc.head(mNumConOriginal) = mlbc; newUbc.head(mNumConOriginal) = mubc; newBLowerBounded.head(mNumConOriginal) = mbConstraintLowerBounded; newBUpperBounded.head(mNumConOriginal) = mbConstraintUpperBounded; } newBLowerBounded.tail(numRows) = VectorXi::Constant(numRows, 1); newBUpperBounded.tail(numRows) = VectorXi::Constant(numRows, 1); mlbc = newLbc; mubc = newUbc; mbConstraintLowerBounded = newBLowerBounded; mbConstraintUpperBounded = newBUpperBounded; VectorXd newLb = VectorXd::Zero(mNumVar); VectorXd newUb = VectorXd::Zero(mNumVar); VectorXi newValueLowerBounded = VectorXi::Zero(mNumVar); VectorXi newValueUpperBounded = VectorXi::Zero(mNumVar); newLb.head(mNumVarOriginal) = mlb; newUb.head(mNumVarOriginal) = mub; newValueLowerBounded.head(mNumVarOriginal) = mbLowerBounded; newValueUpperBounded.head(mNumVarOriginal) = mbUpperBounded; mlb = newLb; mub = newUb; mbLowerBounded = newValueLowerBounded; mbUpperBounded = newValueUpperBounded; } }