tensor DPYieldSurface01::xi_t1( const EPState *EPS) const { tensor dFoverds( 2, def_dim_2, 0.0); tensor I2("I", 2, def_dim_2); stresstensor S = EPS->getStress().deviator(); double p = EPS->getStress().p_hydrostatic(); p = p - Pc; stresstensor alpha = EPS->getTensorVar( 1 ); // getting alpha_ij from EPState stresstensor r = S * (1.0 / p); //for p = sig_kk/3 stresstensor r_bar = r - alpha; stresstensor norm2 = r_bar("ij") * r_bar("ij"); double norm = sqrt( norm2.trace() ); stresstensor n; if ( norm >= d_macheps() ) { n = r_bar *(1.0 / norm ); } else { opserr << "DPYieldSurface01::dFods |n_ij| = 0, divide by zero! Program exits.\n"; exit(-1); } return (-1.0) * n * p; }
tensor DPYieldSurface01::dFods(const EPState *EPS) const { tensor dFoverds( 2, def_dim_2, 0.0); tensor I2("I", 2, def_dim_2); stresstensor S = EPS->getStress().deviator(); //S.reportshort("S"); double p = EPS->getStress().p_hydrostatic(); p = p - Pc; //printf("Here we go! p %f\n", p); stresstensor alpha = EPS->getTensorVar( 1 ); // getting alpha_ij from EPState //alpha.reportshort("alpha"); //stresstensor n = EPS->getTensorVar( 3 ); // getting n_ij from EPState //n.reportshort("n"); //------------------------------------------------- // might be moved to Evolution Law stresstensor r = S * (1.0 / p); //r.reportshort("r"); stresstensor r_bar = r - alpha; //r_bar.reportshort("r_bar"); stresstensor norm2 = r_bar("ij") * r_bar("ij"); double norm = sqrt( norm2.trace() ); //opserr << "d_macheps " << d_macheps() << endlnn; stresstensor n; if ( norm >= d_macheps() ) { n = r_bar*(1.0 / norm ); } else { opserr << "DPYieldSurface01::dFods |n_ij| = 0, divide by zero! Program exits.\n"; exit(-1); } //EPS->setTensorVar( 3, n); //update n_ij// //------------------------------------------------- double m = EPS->getScalarVar( 1 ); //tensorial multiplication produces 1st-order tensor //tensor temp = n("ij") * n("ij"); //double temp1 = temp.trace(); //printf("==== n_ij*n_ij %e\n", temp1); //!!Very important: N = n_pq * alpha_pq +sqrt(2/3)*m (always) = n_pq*r_pq(not hold when not on the yield surface) tensor temp = n("ij") * alpha("ij"); double N = temp.trace() + sqrt(2.0/3.0)*m; //printf(" N = %e\n", N); dFoverds = n - N *I2 *(1.0/3.0); return dFoverds; }
double XC::MDEvolutionLaw::getKp( EPState *EPS , double dummy) { //clog << "el-pl EPS: " << *EPS ; //========================================================================= //calculate n_ij XC::stresstensor S = EPS->getStress().deviator(); double p = EPS->getStress().p_hydrostatic(); XC::stresstensor alpha = EPS->getTensorVar( 1 ); // alpha_ij XC::stresstensor r = S * (1.0 / p); //r.reportshort("r"); XC::stresstensor r_bar = r - alpha; XC::stresstensor norm2 = r_bar("ij") * r_bar("ij"); double norm = sqrt( norm2.trace() ); XC::stresstensor n; if ( norm >= d_macheps() ){ n = ( r - alpha ) *(1.0 / norm ); } else { ::printf(" \n\n n_ij not defined!!!! Program exits\n"); exit(1); } //========================================================================= //calculating b_ij //Calculate the state parameters xi double e = EPS->getScalarVar(3); double ec = getec_ref() - getLambda() * log( p/getp_ref() ); double xi = e - ec; //Calculating the lode angle theta double J2_bar = r_bar.Jinvariant2(); double J3_bar = r_bar.Jinvariant3(); double tempd = 3.0*pow(3.0, 0.5)/2.0*J3_bar/ pow( J2_bar, 1.5); if (tempd > 1.0 ) tempd = 1.0; //bug. if tempd = 1.00000000003, acos gives nan if (tempd < -1.0 ) tempd = -1.0; double theta = acos( tempd ) / 3.0; //calculate the alpha_theta_b and alpha_theta_d double m = EPS->getScalarVar(1); double c = getMe() / getMc(); double cd = getke_d() / getkc_d(); XC::stresstensor alpha_theta_d = n("ij") * (g_WW(theta, c) * Mc + g_WW(theta, cd) * kc_d * xi - m) * pow(2.0/3.0, 0.5); double cb = getke_b() / getkc_b(); if ( xi > 0.0 ) xi = 0.0; // < -xi > XC::stresstensor alpha_theta_b = n("ij") * (g_WW(theta, c) * Mc - g_WW(theta, cb) * kc_b * xi - m) * pow(2.0/3.0, 0.5); alpha_theta_b.null_indices(); //========================================================================= // calculating h XC::stresstensor b; b = alpha_theta_b - alpha; b.null_indices(); XC::stresstensor d; d = alpha_theta_d - alpha; d.null_indices(); double alpha_c_b = g_WW(0.0, c) * Mc + g_WW(0.0, cb) * kc_b * (-xi) - m; double b_ref = 2.0 * pow(2.0/3.0, 0.5) * alpha_c_b; BJtensor temp1 = b("ij") * n("ij"); double bn = temp1.trace(); temp1 = d("ij") * n("ij"); double dn = temp1.trace(); // Calculating A XC::stresstensor F = EPS->getTensorVar( 2 ); // getting F_ij from XC::EPState temp1 = F("ij") * n("ij"); double temp = temp1.trace(); if (temp < 0) temp = 0; double A = Ao*(1.0 + temp); double h = getho() * fabs(bn) / ( b_ref - fabs(bn) ); clog << "ho =" << getho() << " h =" << h << std::endl; //========================================================================= double Kp = h * bn + pow(2.0/3.0, 0.5) * getCm() * ( 1.0 + geteo() ) * A * dn; //double Kp = pow(2.0/3.0, 0.5) * getCm() * ( 1.0 + geteo() ) * A * dn; Kp = Kp * p; return Kp; }
void XC::MDEvolutionLaw::UpdateAllVars( EPState *EPS, double dlamda) { //========================================================================= //calculate n_ij XC::stresstensor S = EPS->getStress().deviator(); double p = EPS->getStress().p_hydrostatic(); XC::stresstensor alpha = EPS->getTensorVar( 1 ); // alpha_ij // Find the norm of alpha BJtensor norm_alphat = alpha("ij") * alpha("ij"); double norm_alpha = sqrt( norm_alphat.trace() ); XC::stresstensor r = S * (1.0 / p); //r.reportshort("r"); XC::stresstensor r_bar = r - alpha; XC::stresstensor norm2 = r_bar("ij") * r_bar("ij"); double norm = sqrt( norm2.trace() ); XC::stresstensor n; if ( norm >= d_macheps() ){ n = ( r - alpha ) *(1.0 / norm ); } else { ::printf(" \n\n n_ij not defined!!!! Program exits\n"); exit(1); } //EPS->setTensorVar( 3, n); //update n_ij// // Update E_Young corresponding to current stress state double p_atm = 100.0; //Kpa, atmospheric pressure double E = EPS->getE(); // old E_Young double E_new = EPS->getEo() * pow( (p/p_atm), geta() ); EPS->setE( E_new ); // Update void ratio double e = EPS->getScalarVar(3); double D = EPS->getScalarVar(2); double elastic_strain_vol = EPS->getdElasticStrain().Iinvariant1(); double plastic_strain_vol = EPS->getdPlasticStrain().Iinvariant1(); double de_p = -( 1.0 + e ) * plastic_strain_vol; // plastic change of void ratio ?? e or eo? double de_e = -( 1.0 + e ) * elastic_strain_vol; // elastic change of void ratio ???? clog << "get dPlasticStrain-vol" << plastic_strain_vol << std::endl; clog << "get dElasticStrain-vol" << elastic_strain_vol << std::endl; clog << "^^^^^^^^^^^ de_e = " << de_e << " de_p = " << de_p << std::endl; double new_e = e + de_p + de_e; EPS->setScalarVar( 3, new_e ); // Updating e //Calculate the state parameters xi double ec = getec_ref() - getLambda() * log( p/getp_ref() ); double xi = e - ec; // Update D double m = EPS->getScalarVar(1); XC::stresstensor F = EPS->getTensorVar( 2 ); // getting F_ij from XC::EPState BJtensor temp_tensor = F("ij") * n("ij"); double temp = temp_tensor.trace(); if (temp < 0) temp = 0; double A = Ao*(1.0 + temp); //Calculating the lode angle theta double J2_bar = r_bar.Jinvariant2(); double J3_bar = r_bar.Jinvariant3(); double tempd = 3.0*pow(3.0, 0.5)/2.0*J3_bar/ pow( J2_bar, 1.5); if (tempd > 1.0 ) tempd = 1.0; //bug. if tempd = 1.00000000003, acos gives nan if (tempd < -1.0 ) tempd = -1.0; double theta = acos( tempd ) / 3.0; //========================================================================= //calculate the alpha_theta_b and alpha_theta_d double c = getMe() / getMc(); double cd = getke_d() / getkc_d(); double alpha_theta_dd = (g_WW(theta, c) * Mc + g_WW(theta, cd) * kc_d * xi - m); XC::stresstensor alpha_theta_d = n("ij") * alpha_theta_dd * pow(2.0/3.0, 0.5); double cb = getke_b() / getkc_b(); if ( xi > 0 ) xi = 0.0; // < -xi > double alpha_theta_bd = (g_WW(theta, c) * Mc + g_WW(theta, cb) * kc_b * (-xi) - m); XC::stresstensor alpha_theta_b = n("ij") *alpha_theta_bd * pow(2.0/3.0, 0.5); alpha_theta_b.null_indices(); XC::stresstensor b; b = alpha_theta_b - alpha; b.null_indices(); XC::stresstensor d; d = alpha_theta_d - alpha; d.null_indices(); BJtensor temp1 = d("ij") * n("ij"); temp1.null_indices(); double D_new = temp1.trace() * A; //Check the restrictions on D if ( (xi > 0.0) && ( D_new < 0.0) ) D_new = 0.0; EPS->setScalarVar(2, D_new); // Updating D //EPS->setScalarVar(2, 0.0); // Updating D //========================================================================= // Update m double dm = dlamda * getCm() * ( 1.0 + e ) * D; EPS->setScalarVar(1, m + dm); // Updating m clog << std::endl << "dm = " << dm << std::endl; //========================================================================= // Update alpha //calculate b_ref double alpha_c_b = g_WW(0.0, c) * Mc + g_WW(0.0, cb) * kc_b * (-xi) - m; double b_ref = 2.0 * pow(2.0/3.0, 0.5) * alpha_c_b; temp1 = b("ij") * n("ij"); double bn = temp1.trace(); clog << "xxxxxxxxxxxxxxxxxxx bn " << bn << std::endl; double h = getho() * fabs(bn) / ( b_ref - fabs(bn) ); //h = h + pow(2.0/3.0, 0.5) * getCm() * ( 1.0 + geteo() ) * A * bn; clog << " ||b|| " << (alpha_theta_bd - norm_alpha) << std::endl; clog << " dlamda " << dlamda << " h = " << h << std::endl; XC::stresstensor dalpha; dalpha = dlamda * h * b("ij"); //dalpha.null_indices(); clog << "delta alpha =" << dalpha << std::endl; //dalpha.reportshortpqtheta("\n dalpha "); alpha = alpha + dalpha; alpha.null_indices(); //alpha.reportshort("Alpha"); EPS->setTensorVar(1, alpha); //========================================================================= // Update F XC::stresstensor dF; if ( D > 0.0 ) D = 0.0; dF = dlamda * getCf() * (-D) * ( getFmax() * n("ij") + F("ij") ); //clog << "dF" << dF; F = F - dF; EPS->setTensorVar(2, F); }
void XC::MDEvolutionLaw::setInitD(EPState *EPS) { //========================================================================= //calculate n_ij XC::stresstensor S = EPS->getStress().deviator(); double p = EPS->getStress().p_hydrostatic(); XC::stresstensor alpha = EPS->getTensorVar( 1 ); // alpha_ij // Find the norm of alpha BJtensor norm_alphat = alpha("ij") * alpha("ij"); double norm_alpha = sqrt( norm_alphat.trace() ); XC::stresstensor r = S * (1.0 / p); //r.reportshort("r"); XC::stresstensor r_bar = r - alpha; XC::stresstensor norm2 = r_bar("ij") * r_bar("ij"); double norm = sqrt( norm2.trace() ); XC::stresstensor n; if ( norm >= d_macheps() ){ n = ( r - alpha ) *(1.0 / norm ); } else { ::printf(" \n\n n_ij not defined!!!! Program exits\n"); exit(1); } //Calculate the state parameters xi double e = EPS->getScalarVar(3); double ec = getec_ref() - getLambda() * log( p/getp_ref() ); double xi = e - ec; //calculating A double m = EPS->getScalarVar(1); XC::stresstensor F = EPS->getTensorVar( 2 ); // getting F_ij from XC::EPState BJtensor temp_tensor = F("ij") * n("ij"); double temp = temp_tensor.trace(); if (temp < 0) temp = 0; double A = Ao*(1.0 + temp); //Calculating the lode angle theta double J2_bar = r_bar.Jinvariant2(); double J3_bar = r_bar.Jinvariant3(); double tempd = 3.0*pow(3.0, 0.5)/2.0*J3_bar/ pow( J2_bar, 1.5); if (tempd > 1.0 ) tempd = 1.0; //bug. if tempd = 1.00000000003, acos gives nan if (tempd < -1.0 ) tempd = -1.0; double theta = acos( tempd ) / 3.0; //========================================================================= //calculate the alpha_theta_b and alpha_theta_d double c = getMe() / getMc(); double cd = getke_d() / getkc_d(); double alpha_theta_dd = (g_WW(theta, c) * Mc + g_WW(theta, cd) * kc_d * xi - m); XC::stresstensor alpha_theta_d = n("ij") * alpha_theta_dd * pow(2.0/3.0, 0.5); XC::stresstensor d; d = alpha_theta_d - alpha; d.null_indices(); BJtensor temp1 = d("ij") * n("ij"); temp1.null_indices(); double D_new = temp1.trace() * A; //Check the restrictions on D if ( (xi > 0.0) && ( D_new < 0.0) ) D_new = 0.0; EPS->setScalarVar(2, D_new); // Updating D }