00001
00002
00003
00004
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
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
00111
00112 if (print) std::cout << " *** ThermoMechanicalStress *** " << std::endl;
00113
00114
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
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
00128 ScalarT dt = deltaTime(0);
00129
00130
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
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
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
00156 mechSource(cell, qp) = 0.0;
00157
00158
00159 pressure = 0.5 * K
00160 * ((J - 1 / J)
00161 - 3 * thermalExpansionCoeff * deltaTemp * (1 + 1 / (J * J)));
00162
00163
00164 Fpinv = Intrepid::inverse(Fpold);
00165 Cpinv = Fpinv * Intrepid::transpose(Fpinv);
00166 be = F * Cpinv * Intrepid::transpose(F);
00167
00168
00169 mubar = ScalarT(Intrepid::trace(be) / 3.) * mu;
00170 s = mu * Intrepid::dev(be);
00171
00172
00173
00174
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
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
00220 N = ScalarT(1 / smag) * s;
00221
00222
00223 s -= ScalarT(2. * mubar * dgam) * N;
00224
00225
00226 eqps(cell, qp) = alpha;
00227
00228
00229 A = dgam * N;
00230 expA = Intrepid::exp<ScalarT>(A);
00231
00232
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
00246
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
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
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 }