• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

J2Stress_Def.hpp

Go to the documentation of this file.
00001 //*****************************************************************//
00002 //    Albany 2.0:  Copyright 2012 Sandia Corporation               //
00003 //    This Software is released under the BSD license detailed     //
00004 //    in the file "license.txt" in the top-level Albany directory  //
00005 //*****************************************************************//
00006 
00007 #include "Teuchos_TestForException.hpp"
00008 #include "Phalanx_DataLayout.hpp"
00009 
00010 #include "Intrepid_FunctionSpaceTools.hpp"
00011 #include "LocalNonlinearSolver.hpp"
00012 
00013 namespace LCM {
00014 
00015 //**********************************************************************
00016 template<typename EvalT, typename Traits>
00017 J2Stress<EvalT, Traits>::
00018 J2Stress(const Teuchos::ParameterList& p) :
00019   defgrad          (p.get<std::string>             ("DefGrad Name"),
00020             p.get<Teuchos::RCP<PHX::DataLayout> >("QP Tensor Data Layout") ),
00021   J                (p.get<std::string>             ("DetDefGrad Name"),
00022             p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout") ),
00023   elasticModulus   (p.get<std::string>             ("Elastic Modulus Name"),
00024             p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout") ),
00025   poissonsRatio    (p.get<std::string>             ("Poissons Ratio Name"),
00026             p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout") ),
00027   yieldStrength    (p.get<std::string>             ("Yield Strength Name"),
00028             p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout") ),
00029   hardeningModulus (p.get<std::string>             ("Hardening Modulus Name"),
00030             p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout") ),
00031   satMod           (p.get<std::string>             ("Saturation Modulus Name"),
00032             p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout") ),
00033   satExp           (p.get<std::string>             ("Saturation Exponent Name"),
00034             p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout") ),
00035   stress           (p.get<std::string>             ("Stress Name"),
00036             p.get<Teuchos::RCP<PHX::DataLayout> >("QP Tensor Data Layout") ),
00037   Fp               (p.get<std::string>             ("Fp Name"),
00038             p.get<Teuchos::RCP<PHX::DataLayout> >("QP Tensor Data Layout") ),
00039   eqps             (p.get<std::string>             ("Eqps Name"),
00040             p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout") )
00041 {
00042   // Pull out numQPs and numDims from a Layout
00043   Teuchos::RCP<PHX::DataLayout> tensor_dl =
00044     p.get< Teuchos::RCP<PHX::DataLayout> >("QP Tensor Data Layout");
00045   std::vector<PHX::DataLayout::size_type> dims;
00046   tensor_dl->dimensions(dims);
00047   numQPs  = dims[1];
00048   numDims = dims[2];
00049   worksetSize = dims[0];
00050 
00051   this->addDependentField(defgrad);
00052   this->addDependentField(J);
00053   this->addDependentField(elasticModulus);
00054   this->addDependentField(poissonsRatio);
00055   this->addDependentField(yieldStrength);
00056   this->addDependentField(hardeningModulus);
00057   this->addDependentField(satMod);
00058   this->addDependentField(satExp);
00059   // PoissonRatio not used in 1D stress calc
00060   //  if (numDims>1) this->addDependentField(poissonsRatio);
00061 
00062   fpName = p.get<std::string>("Fp Name")+"_old";
00063   eqpsName = p.get<std::string>("Eqps Name")+"_old";
00064   this->addEvaluatedField(stress);
00065   this->addEvaluatedField(Fp);
00066   this->addEvaluatedField(eqps);
00067 
00068   // scratch space FCs
00069   be.resize(numDims, numDims);
00070   s.resize(numDims, numDims);
00071   N.resize(numDims, numDims);
00072   A.resize(numDims, numDims);
00073   expA.resize(numDims, numDims);
00074   Fpinv.resize(worksetSize, numQPs, numDims, numDims);
00075   FpinvT.resize(worksetSize, numQPs, numDims, numDims);
00076   Cpinv.resize(worksetSize, numQPs, numDims, numDims);
00077   tmp.resize(numDims, numDims);
00078   tmp2.resize(numDims, numDims);
00079 
00080   this->setName("J2 Stress"+PHX::TypeString<EvalT>::value);
00081 
00082 }
00083 
00084 //**********************************************************************
00085 template<typename EvalT, typename Traits>
00086 void J2Stress<EvalT, Traits>::
00087 postRegistrationSetup(typename Traits::SetupData d,
00088                       PHX::FieldManager<Traits>& fm)
00089 {
00090   this->utils.setFieldData(stress,fm);
00091   this->utils.setFieldData(defgrad,fm);
00092   this->utils.setFieldData(J,fm);
00093   this->utils.setFieldData(elasticModulus,fm);
00094   this->utils.setFieldData(hardeningModulus,fm);
00095   this->utils.setFieldData(yieldStrength,fm);
00096   this->utils.setFieldData(satMod,fm);
00097   this->utils.setFieldData(satExp,fm);
00098   this->utils.setFieldData(Fp,fm);
00099   this->utils.setFieldData(eqps,fm);
00100   if (numDims>1) this->utils.setFieldData(poissonsRatio,fm);
00101 }
00102 
00103 //**********************************************************************
00104 template<typename EvalT, typename Traits>
00105 void J2Stress<EvalT, Traits>::
00106 evaluateFields(typename Traits::EvalData workset)
00107 {
00108   typedef Intrepid::FunctionSpaceTools FST;
00109   typedef Intrepid::RealSpaceTools<ScalarT> RST;
00110 
00111   bool print = false;
00112   //if (typeid(ScalarT) == typeid(RealType)) print = true;
00113   std::cout.precision(15);
00114 
00115   if(print) std::cout << "========= J2 STRESS_DEF ============= " << std::endl;
00116 
00117   ScalarT kappa;
00118   ScalarT mu, mubar;
00119   ScalarT K, Y, siginf, delta;
00120   ScalarT Jm23;
00121   ScalarT trace;
00122   ScalarT smag2, smag, f, p, dgam;
00123   ScalarT sq23 = std::sqrt(2./3.);
00124 
00125   Albany::MDArray Fpold = (*workset.stateArrayPtr)[fpName];
00126   Albany::MDArray eqpsold = (*workset.stateArrayPtr)[eqpsName];
00127 
00128   // compute Cp_{n}^{-1}
00129   // AGS MAY NEED TO ALLOCATE Fpinv FpinvT Cpinv  with actual workse size
00130   // to prevent going past the end of Fpold.
00131   RST::inverse(Fpinv, Fpold);
00132   RST::transpose(FpinvT, Fpinv);
00133   FST::tensorMultiplyDataData<ScalarT>(Cpinv, Fpinv, FpinvT);
00134 
00135   for (std::size_t cell=0; cell < workset.numCells; ++cell)
00136   {
00137     for (std::size_t qp=0; qp < numQPs; ++qp)
00138     {
00139 
00140     if(print) std::cout << "defgrad tensor at cell " << cell
00141                               << ", quadrature point " << qp << ":" << std::endl;
00142     if(print) std::cout << "  " << defgrad(cell, qp, 0, 0);
00143     if(print) std::cout << "  " << defgrad(cell, qp, 0, 1);
00144     if(print) std::cout << "  " << defgrad(cell, qp, 0, 2) << std::endl;
00145     if(print) std::cout << "  " << defgrad(cell, qp, 1, 0);
00146     if(print) std::cout << "  " << defgrad(cell, qp, 1, 1);
00147     if(print) std::cout << "  " << defgrad(cell, qp, 1, 2) << std::endl;
00148     if(print) std::cout << "  " << defgrad(cell, qp, 2, 0);
00149     if(print) std::cout << "  " << defgrad(cell, qp, 2, 1);
00150     if(print) std::cout << "  " << defgrad(cell, qp, 2, 2) << std::endl;
00151 
00152       // local parameters
00153       kappa  = elasticModulus(cell,qp)/(3. * (1. - 2. * poissonsRatio(cell,qp)));
00154       mu     = elasticModulus(cell,qp)/(2. * (1. + poissonsRatio(cell,qp)));
00155       K      = hardeningModulus(cell,qp);
00156       Y      = yieldStrength(cell,qp);
00157       siginf = satMod(cell,qp);
00158       delta  = satExp(cell,qp);
00159       Jm23   = std::pow( J(cell,qp), -2./3. );
00160 
00161       //if(print) std::cout << "kappa: " << kappa << std::endl;
00162       //if(print) std::cout << "mu   : " << mu << std::endl;
00163       //if(print) std::cout << "K    : " << K << std::endl;
00164       //if(print) std::cout << "Y    : " << Y << std::endl;
00165 
00166       if(print) std::cout << "J    : " << J(cell,qp) << std::endl;
00167       if(print) std::cout << "Jm23    : " << Jm23 << std::endl;
00168 
00169 
00170       be.initialize(0.0);
00171       // Compute Trial State
00172       for (std::size_t i=0; i < numDims; ++i)
00173       {
00174   for (std::size_t j=0; j < numDims; ++j)
00175   {
00176     for (std::size_t p=0; p < numDims; ++p)
00177     {
00178       for (std::size_t q=0; q < numDims; ++q)
00179       {
00180         be(i,j) += Jm23 * defgrad(cell,qp,i,p)
00181             * Cpinv(cell,qp,p,q) * defgrad(cell,qp,j,q);
00182       }
00183     }
00184   }
00185       }
00186 
00187       trace = 0.0;
00188       for (std::size_t i=0; i < numDims; ++i)
00189   trace += be(i,i);
00190       trace /= numDims;
00191       mubar = trace*mu;
00192       for (std::size_t i=0; i < numDims; ++i)
00193       {
00194   for (std::size_t j=0; j < numDims; ++j)
00195   {
00196     s(i,j) = mu * be(i,j);
00197   }
00198   s(i,i) -= mu * trace;
00199       }
00200 
00201       // check for yielding
00202       // smag = s.norm();
00203       smag2 = 0.0; smag = 0.0;
00204       for (std::size_t i=0; i < numDims; ++i)
00205   for (std::size_t j=0; j < numDims; ++j)
00206     smag2 += s(i,j) * s(i,j);
00207 
00208       if ( Sacado::ScalarValue<ScalarT>::eval(smag2) > 0.0 )
00209         smag = std::sqrt(smag2);
00210 
00211       f = smag - sq23 * ( Y + K * eqpsold(cell,qp)
00212           + siginf * ( 1. - exp( -delta * eqpsold(cell,qp) ) ) );
00213 
00214       if(print) std::cout << "smag : " << smag << std::endl;
00215       if(print) std::cout << "eqpsold: " << eqpsold(cell,qp) << std::endl;
00216       if(print) std::cout << "K      : " << K << std::endl;
00217       if(print) std::cout << "Y      : " << Y << std::endl;
00218       if(print) std::cout << "f      : " << f << std::endl;
00219 
00220       if (f > 1E-12)
00221       {
00222   // return mapping algorithm
00223   bool converged = false;
00224   ScalarT g = f;
00225   ScalarT H = K * eqpsold(cell,qp)
00226         + siginf*(1. - exp(-delta * eqpsold(cell,qp) ) );
00227     ScalarT H2 = 0.0;
00228   ScalarT dg = ( -2. * mubar ) * ( 1. + H / ( 3. * mubar ) );
00229   ScalarT dH = 0.0;
00230     ScalarT dH2 = 0.0;
00231   ScalarT alpha = 0.0;
00232     ScalarT alpha2 = 0.0;
00233   ScalarT res = 0.0;
00234   int count = 0;
00235   dgam = 0.0;
00236 
00237         LocalNonlinearSolver<EvalT, Traits> solver;
00238 
00239         std::vector<ScalarT> F(1);
00240         std::vector<ScalarT> dFdX(1);
00241         std::vector<ScalarT> X(1);
00242 
00243         F[0] = f;
00244         X[0] = 0.0;
00245         dFdX[0] = ( -2. * mubar ) * ( 1. + H / ( 3. * mubar ) );
00246   while (!converged && count < 30)
00247   {
00248     count++;
00249 
00250     //dgam = ( f / ( 2. * mubar) ) / ( 1. + K / ( 3. * mubar ) );
00251     //dgam -= g/dg;
00252           solver.solve(dFdX,X,F);
00253 
00254           //RealType X0 = Sacado::ScalarValue<ScalarT>::eval(X[0]);
00255           //alpha2 = eqpsold(cell,qp) + sq23 * X0;
00256 
00257           ScalarT X0 = X[0];
00258           alpha2 = eqpsold(cell, qp) + sq23 * X0;
00259 
00260     //H = K * alpha + siginf*( 1. - exp( -delta * alpha ) );
00261     //dH = K + delta * siginf * exp( -delta * alpha );
00262 
00263     H2 = K * alpha2 + siginf*( 1. - exp( -delta * alpha2 ) );
00264     dH2 = K + delta * siginf * exp( -delta * alpha2 );
00265 
00266     //g = smag -  ( 2. * mubar * dgam + sq23 * ( Y + H ) );
00267     //dg = -2. * mubar * ( 1. + dH / ( 3. * mubar ) );    \
00268 
00269           F[0] = smag -  ( 2. * mubar * X0 + sq23 * ( Y + H2 ) );
00270           dFdX[0] = -2. * mubar * ( 1. + dH2 / ( 3. * mubar ) );
00271 
00272     res = std::abs(F[0]);
00273     if ( res < 1.e-11 || res/f < 1.E-11 )
00274       converged = true;
00275 
00276     TEUCHOS_TEST_FOR_EXCEPTION( count > 30, std::runtime_error,
00277            std::endl << "Error in return mapping, count = " << count <<
00278                                     "\nres = " << res <<
00279                                     "\nrelres = " << res/f <<
00280                                     "\ng = " << F[0] <<
00281                                     "\ndg = " << dFdX[0] <<
00282                                     "\nalpha = " << alpha2 << std::endl);
00283 
00284         }
00285 
00286         solver.computeFadInfo(dFdX,X,F);
00287 
00288         dgam = X[0];
00289 
00290         // plastic direction
00291         for (std::size_t i=0; i < numDims; ++i)
00292           for (std::size_t j=0; j < numDims; ++j)
00293             N(i,j) = (1/smag) * s(i,j);
00294 
00295         for (std::size_t i=0; i < numDims; ++i)
00296           for (std::size_t j=0; j < numDims; ++j)
00297             s(i,j) -= 2. * mubar * dgam * N(i,j);
00298 
00299         // update eqps
00300         //eqps(cell,qp) = eqpsold(cell,qp) + sqrt(2./3.) * dgam;
00301         eqps(cell,qp) = alpha2;
00302 
00303         // exponential map to get Fp
00304         for (std::size_t i=0; i < numDims; ++i)
00305           for (std::size_t j=0; j < numDims; ++j)
00306             A(i,j) = dgam * N(i,j);
00307 
00308         exponential_map(expA, A);
00309 
00310         // std::cout << "expA: \n";
00311         // for (std::size_t i=0; i < numDims; ++i)
00312         //   for (std::size_t j=0; j < numDims; ++j)
00313         //    std::cout << Sacado::ScalarValue<ScalarT>::eval(expA(i,j)) << " ";
00314         // std::cout << std::endl;
00315 
00316         for (std::size_t i=0; i < numDims; ++i)
00317         {
00318           for (std::size_t j=0; j < numDims; ++j)
00319           {
00320             Fp(cell,qp,i,j) = 0.0;
00321             for (std::size_t p=0; p < numDims; ++p)
00322             {
00323               Fp(cell,qp,i,j) += expA(i,p) * Fpold(cell,qp,p,j);
00324             }
00325           }
00326         }
00327       }
00328       else
00329       {
00330         // set state variables to old values
00331         eqps(cell, qp) = eqpsold(cell,qp);
00332         for (std::size_t i=0; i < numDims; ++i)
00333           for (std::size_t j=0; j < numDims; ++j)
00334             Fp(cell,qp,i,j) = Fpold(cell,qp,i,j);
00335       }
00336 
00337       if(print) std::cout << "after, eqps:  " << eqps(cell, qp) << std::endl;;
00338 
00339 
00340       // compute pressure
00341       p = 0.5 * kappa * ( J(cell,qp) - 1 / ( J(cell,qp) ) );
00342 
00343       // compute stress
00344       for (std::size_t i=0; i < numDims; ++i)
00345       {
00346         for (std::size_t j=0; j < numDims; ++j)
00347         {
00348           stress(cell,qp,i,j) = s(i,j) / J(cell,qp);
00349         }
00350         stress(cell,qp,i,i) += p;
00351       }
00352 
00353 
00354     if(print) std::cout << "stress tensor at cell " << cell
00355                               << ", quadrature point " << qp << ":" << std::endl;
00356     if(print) std::cout << "  " << stress(cell, qp, 0, 0);
00357     if(print) std::cout << "  " << stress(cell, qp, 0, 1);
00358     if(print) std::cout << "  " << stress(cell, qp, 0, 2) << std::endl;
00359     if(print) std::cout << "  " << stress(cell, qp, 1, 0);
00360     if(print) std::cout << "  " << stress(cell, qp, 1, 1);
00361     if(print) std::cout << "  " << stress(cell, qp, 1, 2) << std::endl;
00362     if(print) std::cout << "  " << stress(cell, qp, 2, 0);
00363     if(print) std::cout << "  " << stress(cell, qp, 2, 1);
00364     if(print) std::cout << "  " << stress(cell, qp, 2, 2) << std::endl;
00365 
00366     if(print) std::cout << "Fp tensor at cell " << cell
00367                               << ", quadrature point " << qp << ":" << std::endl;
00368     if(print) std::cout << "  " << Fp(cell, qp, 0, 0);
00369     if(print) std::cout << "  " << Fp(cell, qp, 0, 1);
00370     if(print) std::cout << "  " << Fp(cell, qp, 0, 2) << std::endl;
00371     if(print) std::cout << "  " << Fp(cell, qp, 1, 0);
00372     if(print) std::cout << "  " << Fp(cell, qp, 1, 1);
00373     if(print) std::cout << "  " << Fp(cell, qp, 1, 2) << std::endl;
00374     if(print) std::cout << "  " << Fp(cell, qp, 2, 0);
00375     if(print) std::cout << "  " << Fp(cell, qp, 2, 1);
00376     if(print) std::cout << "  " << Fp(cell, qp, 2, 2) << std::endl;
00377     }
00378   }
00379 
00380 
00381   // Since Intrepid will later perform calculations on the entire workset size
00382   // and not just the used portion, we must fill the excess with reasonable
00383   // values. Leaving this out leads to inversion of 0 tensors.
00384   for (std::size_t cell=workset.numCells; cell < worksetSize; ++cell)
00385     for (std::size_t qp=0; qp < numQPs; ++qp)
00386       for (std::size_t i=0; i < numDims; ++i)
00387           Fp(cell,qp,i,i) = 1.0;
00388 
00389 
00390   //std::cout << "===================================== "<< std::endl;
00391 
00392 }
00393 //**********************************************************************
00394 template<typename EvalT, typename Traits>
00395 void
00396 J2Stress<EvalT, Traits>::exponential_map(Intrepid::FieldContainer<ScalarT> & expA,
00397     const Intrepid::FieldContainer<ScalarT> A)
00398 {
00399   tmp.initialize(0.0);
00400   expA.initialize(0.0);
00401 
00402   bool converged = false;
00403   ScalarT norm0 = norm(A);
00404 
00405   for (std::size_t i=0; i < numDims; ++i)
00406   {
00407     tmp(i,i) = 1.0;
00408   }
00409 
00410   ScalarT k = 0.0;
00411   while (!converged)
00412   {
00413     // expA += tmp
00414     for (std::size_t i=0; i < numDims; ++i)
00415       for (std::size_t j=0; j < numDims; ++j)
00416         expA(i,j) += tmp(i,j);
00417 
00418     tmp2.initialize(0.0);
00419     for (std::size_t i=0; i < numDims; ++i)
00420       for (std::size_t j=0; j < numDims; ++j)
00421         for (std::size_t p=0; p < numDims; ++p)
00422           tmp2(i,j) += A(i,p) * tmp(p,j);
00423 
00424     // tmp = tmp2
00425     k = k + 1.0;
00426     for (std::size_t i=0; i < numDims; ++i)
00427       for (std::size_t j=0; j < numDims; ++j)
00428         tmp(i,j) = (1/k) * tmp2(i,j);
00429 
00430     if (norm(tmp)/norm0 < 1.E-14 ) converged = true;
00431 
00432     TEUCHOS_TEST_FOR_EXCEPTION( k > 50.0, std::runtime_error,
00433                           std::endl << "Error in exponential map, k = " << k <<
00434                           "\nnorm0 = " << norm0 <<
00435                           "\nnorm = " << norm(tmp)/norm0 <<
00436                           "\nA = \n" << A << std::endl);
00437 
00438   }
00439 }
00440 //**********************************************************************
00441 template<typename EvalT, typename Traits>
00442 typename EvalT::ScalarT
00443 J2Stress<EvalT, Traits>::norm(Intrepid::FieldContainer<ScalarT> A)
00444 {
00445   ScalarT max(0.0), colsum;
00446 
00447   for (std::size_t i(0); i < numDims; ++i)
00448   {
00449     colsum = 0.0;
00450     for (std::size_t j(0); j < numDims; ++j)
00451       colsum += std::abs(A(i,j));
00452     max = (colsum > max) ? colsum : max;
00453   }
00454 
00455   return max;
00456 }
00457 //**********************************************************************
00458 } // end LCM
00459 

Generated on Wed Mar 26 2014 18:36:39 for Albany: a Trilinos-based PDE code by  doxygen 1.7.1