void SurfaceBasis<EvalT, Traits>:: computeCurrentBaseVectors(const SFC & midplaneCoords, PHX::MDField<ScalarT, Cell, QuadPoint, Dim, Dim> basis) { for (int cell(0); cell < midplaneCoords.dimension(0); ++cell) { // get the midplane coordinates std::vector<Intrepid::Vector<ScalarT> > midplaneNodes(numPlaneNodes); for (std::size_t node(0); node < numPlaneNodes; ++node) midplaneNodes[node] = Intrepid::Vector<ScalarT>(3, &midplaneCoords(cell, node, 0)); Intrepid::Vector<ScalarT> g_0(0, 0, 0), g_1(0, 0, 0), g_2(0, 0, 0); //compute the base vectors for (std::size_t pt(0); pt < numQPs; ++pt) { g_0.clear(); g_1.clear(); g_2.clear(); for (std::size_t node(0); node < numPlaneNodes; ++node) { g_0 += refGrads(node, pt, 0) * midplaneNodes[node]; g_1 += refGrads(node, pt, 1) * midplaneNodes[node]; } g_2 = cross(g_0, g_1) / norm(cross(g_0, g_1)); basis(cell, pt, 0, 0) = g_0(0); basis(cell, pt, 0, 1) = g_0(1); basis(cell, pt, 0, 2) = g_0(2); basis(cell, pt, 1, 0) = g_1(0); basis(cell, pt, 1, 1) = g_1(1); basis(cell, pt, 1, 2) = g_1(2); basis(cell, pt, 2, 0) = g_2(0); basis(cell, pt, 2, 1) = g_2(1); basis(cell, pt, 2, 2) = g_2(2); } } }
tensor RMC01YieldSurface::dFods(const EPState *EPS) const { tensor dFoverds( 2, def_dim_2, 0.0); // double p = EPS->getStress().p_hydrostatic(); double q = EPS->getStress().q_deviatoric(); double theta = EPS->getStress().theta(); // double temp_phi = EPS->getScalarVar(1)*3.14159265358979/180.0; // double temp_cohesive = EPS->getScalarVar(2); tensor DpoDs = EPS->getStress().dpoverds(); // dp/ds tensor DqoDs = EPS->getStress().dqoverds(); // dq/ds tensor DthetaoDs = EPS->getStress().dthetaoverds(); // d(theta)/ds // double a1 = -6*sin(temp_phi)/(3.0-sin(temp_phi)); // double a2 = -6*temp_cohesive*cos(temp_phi)/(3.0-sin(temp_phi)); double alfa = EPS->getScalarVar(1); // double k = EPS->getScalarVar(2); double a1 = (3.0*1.7320508076*alfa) / (2.0+1.7320508076*alfa); double e = (3.0-a1)/(3.0+a1); double Frou = g_0(theta, e); double Frou_prime = g_prime(theta, e); double dFoverdp = alfa*(-3.0); // double dFoverdq = Frou; // double dFoverdtheta = q*Frou_prime; double dFoverdq = Frou/1.7320508076; double dFoverdtheta = q*Frou_prime/1.7320508076; dFoverds = DpoDs * dFoverdp + DqoDs * dFoverdq + DthetaoDs * dFoverdtheta; // dF/ds return dFoverds; }
tensor RMC01PotentialSurface::dQods(const EPState *EPS) const { tensor dQoverds( 2, def_dim_2, 0.0); // double p = EPS->getStress().p_hydrostatic(); // p double q = EPS->getStress().q_deviatoric(); // q double theta = EPS->getStress().theta(); // theta // double temp_phi = EPS->getScalarVar(1)*3.14159265358979/180.0; // frictional angle // double temp_cohesive = EPS->getScalarVar(2); // cohesion tensor DpoDs = EPS->getStress().dpoverds(); // dp/ds tensor DqoDs = EPS->getStress().dqoverds(); // dq/ds tensor DthetaoDs = EPS->getStress().dthetaoverds(); // d(theta)/ds double alfa = EPS->getScalarVar(1); // Take alfa & k as internal variables // double k = EPS->getScalarVar(2); // instead of phi & conhesive double a1 = (3.0*1.7320508076*alfa) / (2.0+1.7320508076*alfa); // double a1 = -6*sin(temp_phi)/(3.0-sin(temp_phi)); // double a2 = -6*temp_cohesive*cos(temp_phi)/(3.0-sin(temp_phi)); double e = (3.0-a1)/(3.0+a1); double Frou = g_0(theta, e); // r(theta) double Frou_prime = g_prime(theta, e); // r'(theta) // double dQoverdp = a1; // dQ/dp // double dQoverdq = Frou; // dQ/dq // double dQoverdtheta = q*Frou_prime; // dQ/d(theta) double dQoverdp = alfa*(-3.0); // dQ/dp double dQoverdq = Frou/1.7320508076; // dQ/dq double dQoverdtheta = q*Frou_prime/1.7320508076; // dQ/d(theta) dQoverds = DpoDs * dQoverdp + DqoDs * dQoverdq + DthetaoDs * dQoverdtheta; return dQoverds; }
tensor RMC01PotentialSurface::d2Qods2( const EPState *EPS ) const { tensor d2Qoverds2( 4, def_dim_4, 0.0); // d2Q/ds2(pqmn) // double p = EPS->getStress().p_hydrostatic(); // p double q = EPS->getStress().q_deviatoric(); // q double theta = EPS->getStress().theta(); // theta // double temp_phi = EPS->getScalarVar(1)*3.14159265358979/180.0; // frictional angle // double temp_cohesive = EPS->getScalarVar(2); // conhesion double alfa = EPS->getScalarVar(1); // double k = EPS->getScalarVar(2); double a1 = (3.0*1.7320508076*alfa) / (2.0+1.7320508076*alfa); tensor DpoDs = EPS->getStress().dpoverds(); // dp/ds tensor DqoDs = EPS->getStress().dqoverds(); // dq/ds tensor DthetaoDs = EPS->getStress().dthetaoverds(); // d(theta)/ds tensor D2poDs2 = EPS->getStress().d2poverds2(); // d2p/ds2 tensor D2qoDs2 = EPS->getStress().d2qoverds2(); // d2q/ds2 tensor D2thetaoDs2 = EPS->getStress().d2thetaoverds2(); // d2(theta)/ds2 // double a1 = -6*sin(temp_phi)/(3.0-sin(temp_phi)); // double a2 = -6*temp_cohesive*cos(temp_phi)/(3.0-sin(temp_phi)); double e = (3.0-a1)/(3.0+a1); double Frou = g_0(theta, e); // r(theta) double Frou_prime = g_prime(theta, e); // r'(theta) double Frou_second = g_second(theta, e); // r"(theta) // double dQoverdp = a1; // dQ/dp // double dQoverdq = Frou; // dQ/dq // double dQoverdtheta = q*Frou_prime; // dQ/d(theta) double dQoverdp = alfa*(-3.0); // dQ/dp double dQoverdq = Frou/1.7320508076; // dQ/dq double dQoverdtheta = q*Frou_prime/1.7320508076; // dQ/d(theta) // double a23 = Frou_prime; // d2Q/dqd(theta) // double a32 = a23; // d2Q/d(theta)dq // double a33 = q * Frou_second; // d2Q/d(theta)2 double a23 = Frou_prime/1.7320508076; // d2Q/dqd(theta) double a32 = a23/1.7320508076; // d2Q/d(theta)dq double a33 = q * Frou_second/1.7320508076; // d2Q/d(theta)2 // d2Qoverds2 = DthetaoDs("mn") * DqoDs("pq") * a23 + // DqoDs("mn") * DthetaoDs("pq") * a32 + // DthetaoDs("mn") * DthetaoDs("pq") * a33 + // D2poDs2("pqmn") * dQoverdp + // D2qoDs2("pqmn") * dQoverdq + // D2thetaoDs2("pqmn") * dQoverdtheta; d2Qoverds2 = DqoDs("pq") * DthetaoDs("mn") * a23 + DthetaoDs("pq") * DqoDs("mn") * a32 + DthetaoDs("pq") * DthetaoDs("mn") * a33 + D2poDs2("pqmn") * dQoverdp + D2qoDs2("pqmn") * dQoverdq + D2thetaoDs2("pqmn") * dQoverdtheta; return d2Qoverds2; }
/* heres another comment */ int g(int a, float *b) { switch (a) { case 0: return g_0(b); break; case 1: return g_1(b); break; default: return 1; break; } }
double RMC01YieldSurface::f(const EPState *EPS) const { double p = EPS->getStress().p_hydrostatic(); // double q = EPS->getStress().q_deviatoric(); // q double theta = EPS->getStress().theta(); // theta // double temp_phi = EPS->getScalarVar(1)*3.14159265358979/180.0; // frictional angle // double temp_cohesive = EPS->getScalarVar(2); // cohesion // double a1 = -6*sin(temp_phi)/(3.0-sin(temp_phi)); // double a2 = -6*temp_cohesive*cos(temp_phi)/(3.0-sin(temp_phi)); double alfa = EPS->getScalarVar(1); // Take alfa & k as internal variables double k = EPS->getScalarVar(2); // instead of phi & conhesive double a1 = (3.0*1.7320508076*alfa) / (2.0+1.7320508076*alfa); double e = (3.0-a1)/(3.0+a1); // ratio of tensile radius to compressive radius double Frou = g_0(theta, e); //double f = a1*p+q*Frou+a2; // yield fuction double f = alfa*p*(-3.0) + Frou*q/1.7320508076 - k; // new form return f; }
void SurfaceBasis<EvalT, Traits>::computeDualBaseVectors( const MFC & midplaneCoords, const PHX::MDField<MeshScalarT, Cell, QuadPoint, Dim, Dim> basis, PHX::MDField<MeshScalarT, Cell, QuadPoint, Dim> normal, PHX::MDField<MeshScalarT, Cell, QuadPoint, Dim, Dim> dualBasis) { std::size_t worksetSize = midplaneCoords.dimension(0); Intrepid::Vector<MeshScalarT> g_0(0, 0, 0), g_1(0, 0, 0), g_2(0, 0, 0), g0(0, 0, 0), g1(0, 0, 0), g2(0, 0, 0); for (std::size_t cell(0); cell < worksetSize; ++cell) { for (std::size_t pt(0); pt < numQPs; ++pt) { g_0 = Intrepid::Vector<MeshScalarT>(3, &basis(cell, pt, 0, 0)); g_1 = Intrepid::Vector<MeshScalarT>(3, &basis(cell, pt, 1, 0)); g_2 = Intrepid::Vector<MeshScalarT>(3, &basis(cell, pt, 2, 0)); normal(cell, pt, 0) = g_2(0); normal(cell, pt, 1) = g_2(1); normal(cell, pt, 2) = g_2(2); g0 = cross(g_1, g_2) / dot(g_0, cross(g_1, g_2)); g1 = cross(g_0, g_2) / dot(g_1, cross(g_0, g_2)); g2 = cross(g_0, g_1) / dot(g_2, cross(g_0, g_1)); dualBasis(cell, pt, 0, 0) = g0(0); dualBasis(cell, pt, 0, 1) = g0(1); dualBasis(cell, pt, 0, 2) = g0(2); dualBasis(cell, pt, 1, 0) = g1(0); dualBasis(cell, pt, 1, 1) = g1(1); dualBasis(cell, pt, 1, 2) = g1(2); dualBasis(cell, pt, 2, 0) = g2(0); dualBasis(cell, pt, 2, 1) = g2(1); dualBasis(cell, pt, 2, 2) = g2(2); } } }
void SurfaceVectorGradient<EvalT, Traits>:: evaluateFields(typename Traits::EvalData workset) { for (std::size_t cell=0; cell < workset.numCells; ++cell) { for (std::size_t pt=0; pt < numQPs; ++pt) { Intrepid::Vector<ScalarT> g_0(3, ¤tBasis(cell, pt, 0, 0)); Intrepid::Vector<ScalarT> g_1(3, ¤tBasis(cell, pt, 1, 0)); Intrepid::Vector<ScalarT> g_2(3, ¤tBasis(cell, pt, 2, 0)); Intrepid::Vector<ScalarT> G_2(3, &refNormal(cell, pt, 0)); Intrepid::Vector<ScalarT> d(3, &jump(cell, pt, 0)); Intrepid::Vector<ScalarT> G0(3, &refDualBasis(cell, pt, 0, 0)); Intrepid::Vector<ScalarT> G1(3, &refDualBasis(cell, pt, 1, 0)); Intrepid::Vector<ScalarT> G2(3, &refDualBasis(cell, pt, 2, 0)); Intrepid::Tensor<ScalarT> Fpar(Intrepid::bun(g_0, G0) + Intrepid::bun(g_1, G1) + Intrepid::bun(g_2, G2)); // for Jay: bun() Intrepid::Tensor<ScalarT> Fper((1 / thickness) * Intrepid::bun(d, G_2)); Intrepid::Tensor<ScalarT> F = Fpar + Fper; defGrad(cell, pt, 0, 0) = F(0, 0); defGrad(cell, pt, 0, 1) = F(0, 1); defGrad(cell, pt, 0, 2) = F(0, 2); defGrad(cell, pt, 1, 0) = F(1, 0); defGrad(cell, pt, 1, 1) = F(1, 1); defGrad(cell, pt, 1, 2) = F(1, 2); defGrad(cell, pt, 2, 0) = F(2, 0); defGrad(cell, pt, 2, 1) = F(2, 1); defGrad(cell, pt, 2, 2) = F(2, 2); J(cell,pt) = Intrepid::det(F); } } if (weightedAverage) { ScalarT Jbar, wJbar, vol; for (std::size_t cell=0; cell < workset.numCells; ++cell) { Jbar = 0.0; vol = 0.0; for (std::size_t qp=0; qp < numQPs; ++qp) { Jbar += weights(cell,qp) * std::log( J(cell,qp) ); vol += weights(cell,qp); } Jbar /= vol; // Jbar = std::exp(Jbar); for (std::size_t qp=0; qp < numQPs; ++qp) { for (std::size_t i=0; i < numDims; ++i) { for (std::size_t j=0; j < numDims; ++j) { wJbar = std::exp( (1-alpha) * Jbar + alpha * std::log( J(cell,qp) ) ); defGrad(cell,qp,i,j) *= std::pow( wJbar / J(cell,qp) ,1./3. ); } } J(cell,qp) = wJbar; } } } }
void TvergaardHutchinsonModel<EvalT, Traits>::computeState( typename Traits::EvalData workset, DepFieldMap dep_fields, FieldMap eval_fields) { // extract dependent MDFields auto jump = *dep_fields["Vector Jump"]; auto basis = *dep_fields["Current Basis"]; // extract evaluated MDFields auto traction = *eval_fields["Cohesive_Traction"]; auto traction_normal = *eval_fields["Normal_Traction"]; auto traction_shear = *eval_fields["Shear_Traction"]; auto jump_normal = *eval_fields["Normal_Jump"]; auto jump_shear = *eval_fields["Shear_Jump"]; for (int cell(0); cell < workset.numCells; ++cell) { for (int pt(0); pt < num_pts_; ++pt) { // current basis vector minitensor::Vector<ScalarT> g_0( minitensor::Source::ARRAY, 3, basis, cell, pt, 0, 0); minitensor::Vector<ScalarT> g_1( minitensor::Source::ARRAY, 3, basis, cell, pt, 1, 0); minitensor::Vector<ScalarT> n( minitensor::Source::ARRAY, 3, basis, cell, pt, 2, 0); // construct orthogonal unit basis minitensor::Vector<ScalarT> t_0(0.0, 0.0, 0.0), t_1(0.0, 0.0, 0.0); t_0 = g_0 / norm(g_0); t_1 = cross(n, t_0); // construct transformation matrix Q (2nd order tensor) minitensor::Tensor<ScalarT> Q(3, minitensor::Filler::ZEROS); // manually fill Q = [t_0; t_1; n]; Q(0, 0) = t_0(0); Q(1, 0) = t_0(1); Q(2, 0) = t_0(2); Q(0, 1) = t_1(0); Q(1, 1) = t_1(1); Q(2, 1) = t_1(2); Q(0, 2) = n(0); Q(1, 2) = n(1); Q(2, 2) = n(2); // global and local jump minitensor::Vector<ScalarT> jump_global( minitensor::Source::ARRAY, 3, jump, cell, pt, 0); minitensor::Vector<ScalarT> jump_local(3); jump_local = minitensor::dot(minitensor::transpose(Q), jump_global); // define shear and normal components of jump // needed for interpenetration // Note: need to protect sqrt around zero when using Sacado ScalarT JumpNormal, JumpShear, IntermediateValue; JumpNormal = jump_local(2); IntermediateValue = jump_local(0) * jump_local(0) + jump_local(1) * jump_local(1); if (IntermediateValue > 0.0) JumpShear = sqrt(IntermediateValue); else JumpShear = 0.0; // matrix beta that controls relative effect of shear and normal opening minitensor::Tensor<ScalarT> beta(3, minitensor::Filler::ZEROS); beta(0, 0) = beta_0; beta(1, 1) = beta_1; beta(2, 2) = beta_2; // compute scalar effective jump ScalarT jump_eff; IntermediateValue = minitensor::dot(jump_local, minitensor::dot(beta, jump_local)); if (IntermediateValue > 0.0) jump_eff = sqrt(IntermediateValue); else jump_eff = 0.0; // traction-separation law from Tvergaard-Hutchinson 1992 ScalarT sigma_eff; // Sacado::ScalarValue<ScalarT>::eval if (jump_eff <= delta_1) sigma_eff = sigma_c * jump_eff / delta_1; else if (jump_eff > delta_1 && jump_eff <= delta_2) sigma_eff = sigma_c; else if (jump_eff > delta_2 && jump_eff <= delta_c) sigma_eff = sigma_c * (delta_c - jump_eff) / (delta_c - delta_2); else sigma_eff = 0.0; // construct traction vector minitensor::Vector<ScalarT> traction_local(3); traction_local.clear(); if (jump_eff != 0) traction_local = minitensor::dot(beta, jump_local) * sigma_eff / jump_eff; // norm of the local shear components of the traction ScalarT TractionShear; IntermediateValue = traction_local(0) * traction_local(0) + traction_local(1) * traction_local(1); if (IntermediateValue > 0.0) TractionShear = sqrt(IntermediateValue); else TractionShear = 0.0; // global traction vector minitensor::Vector<ScalarT> traction_global(3); traction_global = minitensor::dot(Q, traction_local); traction(cell, pt, 0) = traction_global(0); traction(cell, pt, 1) = traction_global(1); traction(cell, pt, 2) = traction_global(2); // update state variables traction_normal(cell, pt) = traction_local(2); traction_shear(cell, pt) = TractionShear; jump_normal(cell, pt) = JumpNormal; jump_shear(cell, pt) = JumpShear; } } }