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

ThermoMechanicalStress_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 #include "Teuchos_TestForException.hpp"
00007 #include "Phalanx_DataLayout.hpp"
00008 
00009 #include "Intrepid_FunctionSpaceTools.hpp"
00010 
00011 #include <Intrepid_MiniTensor.h>
00012 #include <Sacado_MathFunctions.hpp>
00013 
00014 #include <typeinfo>
00015 
00016 namespace LCM {
00017 
00018 //**********************************************************************
00019   template<typename EvalT, typename Traits>
00020   ThermoMechanicalStress<EvalT, Traits>::ThermoMechanicalStress(
00021       const Teuchos::ParameterList& p) :
00022       F_array(p.get<std::string>("DefGrad Name"),
00023           p.get<Teuchos::RCP<PHX::DataLayout> >("QP Tensor Data Layout")), J_array(
00024           p.get<std::string>("DetDefGrad Name"),
00025           p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout")), shearModulus(
00026           p.get<std::string>("Shear Modulus Name"),
00027           p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout")), bulkModulus(
00028           p.get<std::string>("Bulk Modulus Name"),
00029           p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout")), temperature(
00030           p.get<std::string>("Temperature Name"),
00031           p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout")), yieldStrength(
00032           p.get<std::string>("Yield Strength Name"),
00033           p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout")), hardeningModulus(
00034           p.get<std::string>("Hardening Modulus Name"),
00035           p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout")), satMod(
00036           p.get<std::string>("Saturation Modulus Name"),
00037           p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout")), satExp(
00038           p.get<std::string>("Saturation Exponent Name"),
00039           p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout")), deltaTime(
00040           p.get<std::string>("Delta Time Name"),
00041           p.get<Teuchos::RCP<PHX::DataLayout> >("Workset Scalar Data Layout")), stress(
00042           p.get<std::string>("Stress Name"),
00043           p.get<Teuchos::RCP<PHX::DataLayout> >("QP Tensor Data Layout")), Fp(
00044           p.get<std::string>("Fp Name"),
00045           p.get<Teuchos::RCP<PHX::DataLayout> >("QP Tensor Data Layout")), eqps(
00046           p.get<std::string>("eqps Name"),
00047           p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout")), mechSource(
00048           p.get<std::string>("Mechanical Source Name"),
00049           p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout")), thermalExpansionCoeff(
00050           p.get<RealType>("Thermal Expansion Coefficient")), refTemperature(
00051           p.get<RealType>("Reference Temperature"))
00052   {
00053     // Pull out numQPs and numDims from a Layout
00054     Teuchos::RCP<PHX::DataLayout> tensor_dl = p.get<
00055         Teuchos::RCP<PHX::DataLayout> >("QP Tensor Data Layout");
00056     std::vector<PHX::DataLayout::size_type> dims;
00057     tensor_dl->dimensions(dims);
00058     numQPs = dims[1];
00059     numDims = dims[2];
00060 
00061     this->addDependentField(F_array);
00062     this->addDependentField(J_array);
00063     this->addDependentField(shearModulus);
00064     this->addDependentField(bulkModulus);
00065     this->addDependentField(yieldStrength);
00066     this->addDependentField(hardeningModulus);
00067     this->addDependentField(satMod);
00068     this->addDependentField(satExp);
00069     this->addDependentField(temperature);
00070     this->addDependentField(deltaTime);
00071 
00072     fpName = p.get<std::string>("Fp Name") + "_old";
00073     eqpsName = p.get<std::string>("eqps Name") + "_old";
00074     this->addEvaluatedField(stress);
00075     this->addEvaluatedField(Fp);
00076     this->addEvaluatedField(eqps);
00077     this->addEvaluatedField(mechSource);
00078 
00079     this->setName("ThermoMechanical Stress" + PHX::TypeString<EvalT>::value);
00080 
00081   }
00082 
00083 //**********************************************************************
00084   template<typename EvalT, typename Traits>
00085   void ThermoMechanicalStress<EvalT, Traits>::postRegistrationSetup(
00086       typename Traits::SetupData d, PHX::FieldManager<Traits>& fm)
00087   {
00088     this->utils.setFieldData(stress, fm);
00089     this->utils.setFieldData(Fp, fm);
00090     this->utils.setFieldData(eqps, fm);
00091     this->utils.setFieldData(F_array, fm);
00092     this->utils.setFieldData(J_array, fm);
00093     this->utils.setFieldData(shearModulus, fm);
00094     this->utils.setFieldData(bulkModulus, fm);
00095     this->utils.setFieldData(temperature, fm);
00096     this->utils.setFieldData(hardeningModulus, fm);
00097     this->utils.setFieldData(satMod, fm);
00098     this->utils.setFieldData(satExp, fm);
00099     this->utils.setFieldData(yieldStrength, fm);
00100     this->utils.setFieldData(mechSource, fm);
00101     this->utils.setFieldData(deltaTime, fm);
00102   }
00103 
00104 //**********************************************************************
00105   template<typename EvalT, typename Traits>
00106   void ThermoMechanicalStress<EvalT, Traits>::evaluateFields(
00107       typename Traits::EvalData workset)
00108   {
00109     bool print = false;
00110     //if (typeid(ScalarT) == typeid(RealType)) print = true;
00111 
00112     if (print) std::cout << " *** ThermoMechanicalStress *** " << std::endl;
00113 
00114     // declare some ScalarT's to be used later
00115     ScalarT J, Jm23, K, H, Y, siginf, delta;
00116     ScalarT f, dgam;
00117     ScalarT deltaTemp;
00118     ScalarT mu, mubar;
00119     ScalarT smag;
00120     ScalarT pressure;
00121     ScalarT sq23 = std::sqrt(2. / 3.);
00122 
00123     // local Tensors
00124     Intrepid::Tensor<ScalarT> F(3), Fpold(3), Fpinv(3), Cpinv(3);
00125     Intrepid::Tensor<ScalarT> be(3), s(3), N(3), A(3), expA(3);
00126 
00127     // grab the time step
00128     ScalarT dt = deltaTime(0);
00129 
00130     // get old state variables
00131     Albany::MDArray Fpold_array = (*workset.stateArrayPtr)[fpName];
00132     Albany::MDArray eqpsold = (*workset.stateArrayPtr)[eqpsName];
00133 
00134     for (std::size_t cell = 0; cell < workset.numCells; ++cell) {
00135       for (std::size_t qp = 0; qp < numQPs; ++qp) {
00136         // Fill in tensors from MDArray data
00137         for (std::size_t i = 0; i < numDims; ++i) {
00138           for (std::size_t j = 0; j < numDims; ++j) {
00139             Fpold(i, j) = Fpold_array(cell, qp, i, j);
00140             F(i, j) = F_array(cell, qp, i, j);
00141           }
00142         }
00143 
00144         // local qp values (for readibility)
00145         J = J_array(cell, qp);
00146         Jm23 = std::pow(J, -2. / 3.);
00147         mu = shearModulus(cell, qp);
00148         K = bulkModulus(cell, qp);
00149         H = hardeningModulus(cell, qp);
00150         Y = yieldStrength(cell, qp);
00151         siginf = satMod(cell, qp);
00152         delta = satExp(cell, qp);
00153         deltaTemp = temperature(cell, qp) - refTemperature;
00154 
00155         // initialize plastic work
00156         mechSource(cell, qp) = 0.0;
00157 
00158         // compute the pressure
00159         pressure = 0.5 * K
00160             * ((J - 1 / J)
00161                 - 3 * thermalExpansionCoeff * deltaTemp * (1 + 1 / (J * J)));
00162 
00163         // compute trial intermediate configuration
00164         Fpinv = Intrepid::inverse(Fpold);
00165         Cpinv = Fpinv * Intrepid::transpose(Fpinv);
00166         be = F * Cpinv * Intrepid::transpose(F);
00167 
00168         // compute the trial deviatoric stress
00169         mubar = ScalarT(Intrepid::trace(be) / 3.) * mu;
00170         s = mu * Intrepid::dev(be);
00171 
00172         // check for yielding
00173         //smag = 0.0;
00174         //if ( norm(s) > 1.e-15 )
00175         smag = Intrepid::norm(s);
00176         f = smag
00177             - sq23
00178                 * (Y + H * eqpsold(cell, qp)
00179                     + siginf * (1. - std::exp(-delta * eqpsold(cell, qp))));
00180 
00181         dgam = 0.0;
00182 
00183         if (f > 1E-6) {
00184           // return mapping algorithm
00185           bool converged = false;
00186           ScalarT g = f;
00187           ScalarT G = H * eqpsold(cell, qp)
00188               + siginf * (1. - std::exp(-delta * eqpsold(cell, qp)));
00189           ScalarT dg = (-2. * mubar) * (1. + H / (3. * mubar));
00190           ScalarT dG = 0.0;
00191           ;
00192           ScalarT alpha = 0.0;
00193           ScalarT res = 0.0;
00194           int count = 0;
00195 
00196           while (!converged && count < 50) {
00197             count++;
00198 
00199             dgam -= g / dg;
00200 
00201             alpha = eqpsold(cell, qp) + sq23 * dgam;
00202 
00203             G = H * alpha + siginf * (1. - std::exp(-delta * alpha));
00204             ;
00205             dG = H + delta * siginf * std::exp(-delta * alpha);
00206             ;
00207 
00208             g = smag - (2. * mubar * dgam + sq23 * (Y + G));
00209             dg = -2. * mubar * (1. + dG / (3. * mubar));
00210 
00211             res = std::abs(g);
00212             if (res < 1.e-6 || res / f < 1.e-6) converged = true;
00213 
00214             TEUCHOS_TEST_FOR_EXCEPTION( count > 50, std::runtime_error,
00215                 std::endl << "Error in return mapping, count = " << count << "\nres = " << res << "\nrelres = " << res/f << "\ng = " << g << "\ndg = " << dg << "\nalpha = " << alpha << std::endl);
00216 
00217           }
00218 
00219           // plastic direction
00220           N = ScalarT(1 / smag) * s;
00221 
00222           // updated deviatoric stress
00223           s -= ScalarT(2. * mubar * dgam) * N;
00224 
00225           // update eqps
00226           eqps(cell, qp) = alpha;
00227 
00228           // exponential map to get Fp
00229           A = dgam * N;
00230           expA = Intrepid::exp<ScalarT>(A);
00231 
00232           // set plastic work
00233           if (dt > 0.0) mechSource(cell, qp) = sq23 * dgam / dt
00234               * (Y + G + temperature(cell, qp) * 1.0);
00235 
00236           for (std::size_t i = 0; i < numDims; ++i) {
00237             for (std::size_t j = 0; j < numDims; ++j) {
00238               Fp(cell, qp, i, j) = 0.0;
00239               for (std::size_t p = 0; p < numDims; ++p) {
00240                 Fp(cell, qp, i, j) += expA(i, p) * Fpold(p, j);
00241               }
00242             }
00243           }
00244         } else {
00245           // set state variables to old values
00246           //dp(cell, qp) = 0.0;
00247           eqps(cell, qp) = eqpsold(cell, qp);
00248           for (std::size_t i = 0; i < numDims; ++i)
00249             for (std::size_t j = 0; j < numDims; ++j)
00250               Fp(cell, qp, i, j) = Fpold_array(cell, qp, i, j);
00251         }
00252 
00253         // compute stress
00254         for (std::size_t i = 0; i < numDims; ++i) {
00255           for (std::size_t j = 0; j < numDims; ++j) {
00256             stress(cell, qp, i, j) = s(i, j) / J;
00257           }
00258           stress(cell, qp, i, i) += pressure;
00259         }
00260 
00261         // update be
00262         be = ScalarT(1 / mu) * s +
00263             ScalarT(Intrepid::trace(be) / 3) * Intrepid::eye<ScalarT>(3);
00264 
00265         if (print) {
00266           std::cout << "    sig : ";
00267           for (unsigned int i(0); i < numDims; ++i)
00268             for (unsigned int j(0); j < numDims; ++j)
00269               std::cout << stress(cell, qp, i, j) << " ";
00270           std::cout << std::endl;
00271 
00272           std::cout << "    s   : ";
00273           for (unsigned int i(0); i < numDims; ++i)
00274             for (unsigned int j(0); j < numDims; ++j)
00275               std::cout << s(i, j) << " ";
00276           std::cout << std::endl;
00277 
00278           std::cout << "    work: " << mechSource(cell, qp) << std::endl;
00279           std::cout << "    dgam: " << dgam << std::endl;
00280           std::cout << "    smag: " << smag << std::endl;
00281           std::cout << "    n(s): " << Intrepid::norm(s) << std::endl;
00282           std::cout << "    temp: " << temperature(cell, qp) << std::endl;
00283           std::cout << "    Dtem: " << deltaTemp << std::endl;
00284           std::cout << "       Y: " << yieldStrength(cell, qp) << std::endl;
00285           std::cout << "       H: " << hardeningModulus(cell, qp) << std::endl;
00286           std::cout << "       S: " << satMod(cell, qp) << std::endl;
00287         }
00288       }
00289     }
00290   }
00291 //**********************************************************************
00292 
00293 }

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