00001
00002
00003
00004
00005
00006 #include "Teuchos_TestForException.hpp"
00007 #include "Phalanx_DataLayout.hpp"
00008
00009 #include "Intrepid_FunctionSpaceTools.hpp"
00010 #include "LocalNonlinearSolver.hpp"
00011
00012 #include <typeinfo>
00013
00014 namespace LCM {
00015
00016
00017 template<typename EvalT, typename Traits>
00018 J2Damage<EvalT, Traits>::J2Damage(const Teuchos::ParameterList& p) :
00019 defgrad(p.get<std::string>("DefGrad Name"),
00020 p.get<Teuchos::RCP<PHX::DataLayout> >("QP Tensor Data Layout")), J(
00021 p.get<std::string>("DetDefGrad Name"),
00022 p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout")), bulkModulus(
00023 p.get<std::string>("Bulk Modulus Name"),
00024 p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout")), shearModulus(
00025 p.get<std::string>("Shear Modulus Name"),
00026 p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout")), yieldStrength(
00027 p.get<std::string>("Yield Strength Name"),
00028 p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout")), hardeningModulus(
00029 p.get<std::string>("Hardening Modulus Name"),
00030 p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout")), satMod(
00031 p.get<std::string>("Saturation Modulus Name"),
00032 p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout")), satExp(
00033 p.get<std::string>("Saturation Exponent Name"),
00034 p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout")), damage(
00035 p.get<std::string>("Damage Name"),
00036 p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout")), stress(
00037 p.get<std::string>("Stress Name"),
00038 p.get<Teuchos::RCP<PHX::DataLayout> >("QP Tensor Data Layout")), dp(
00039 p.get<std::string>("DP Name"),
00040 p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout")), seff(
00041 p.get<std::string>("Effective Stress Name"),
00042 p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout")), energy(
00043 p.get<std::string>("Energy Name"),
00044 p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout")), Fp(
00045 p.get<std::string>("Fp Name"),
00046 p.get<Teuchos::RCP<PHX::DataLayout> >("QP Tensor Data Layout")), eqps(
00047 p.get<std::string>("Eqps Name"),
00048 p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout"))
00049 {
00050
00051 Teuchos::RCP<PHX::DataLayout> tensor_dl = p.get<
00052 Teuchos::RCP<PHX::DataLayout> >("QP Tensor Data Layout");
00053 std::vector<PHX::DataLayout::size_type> dims;
00054 tensor_dl->dimensions(dims);
00055 numQPs = dims[1];
00056 numDims = dims[2];
00057
00058 std::size_t worksetSize = dims[0];
00059
00060 this->addDependentField(defgrad);
00061 this->addDependentField(J);
00062 this->addDependentField(bulkModulus);
00063 this->addDependentField(shearModulus);
00064 this->addDependentField(yieldStrength);
00065 this->addDependentField(hardeningModulus);
00066 this->addDependentField(satMod);
00067 this->addDependentField(satExp);
00068 this->addDependentField(damage);
00069
00070 fpName = p.get<std::string>("Fp Name") + "_old";
00071 eqpsName = p.get<std::string>("Eqps Name") + "_old";
00072 this->addEvaluatedField(stress);
00073 this->addEvaluatedField(dp);
00074 this->addEvaluatedField(seff);
00075 this->addEvaluatedField(energy);
00076 this->addEvaluatedField(Fp);
00077 this->addEvaluatedField(eqps);
00078
00079
00080 Fpinv.resize(worksetSize, numQPs, numDims, numDims);
00081 FpinvT.resize(worksetSize, numQPs, numDims, numDims);
00082 Cpinv.resize(worksetSize, numQPs, numDims, numDims);
00083
00084 this->setName("Stress" + PHX::TypeString<EvalT>::value);
00085
00086 }
00087
00088
00089 template<typename EvalT, typename Traits>
00090 void J2Damage<EvalT, Traits>::postRegistrationSetup(
00091 typename Traits::SetupData d, PHX::FieldManager<Traits>& fm)
00092 {
00093 this->utils.setFieldData(stress, fm);
00094 this->utils.setFieldData(dp, fm);
00095 this->utils.setFieldData(seff, fm);
00096 this->utils.setFieldData(energy, fm);
00097 this->utils.setFieldData(defgrad, fm);
00098 this->utils.setFieldData(J, fm);
00099 this->utils.setFieldData(bulkModulus, fm);
00100 this->utils.setFieldData(shearModulus, fm);
00101 this->utils.setFieldData(hardeningModulus, fm);
00102 this->utils.setFieldData(yieldStrength, fm);
00103 this->utils.setFieldData(satMod, fm);
00104 this->utils.setFieldData(satExp, fm);
00105 this->utils.setFieldData(damage, fm);
00106 this->utils.setFieldData(Fp, fm);
00107 this->utils.setFieldData(eqps, fm);
00108 }
00109
00110
00111 template<typename EvalT, typename Traits>
00112 void J2Damage<EvalT, Traits>::evaluateFields(
00113 typename Traits::EvalData workset)
00114 {
00115 LocalNonlinearSolver<EvalT, Traits> solver;
00116
00117 bool print = false;
00118
00119
00120 typedef Intrepid::FunctionSpaceTools FST;
00121 typedef Intrepid::RealSpaceTools<ScalarT> RST;
00122
00123 ScalarT kappa, H, H2, phi, phi_old;
00124 ScalarT mu, mubar;
00125 ScalarT K, Y, siginf, delta;
00126 ScalarT Jm23;
00127 ScalarT trd3;
00128 ScalarT smag, f, p, dgam;
00129 ScalarT sq23 = std::sqrt(2. / 3.);
00130
00131
00132 Intrepid::Tensor<ScalarT> be(3);
00133 Intrepid::Tensor<ScalarT> s(3);
00134 Intrepid::Tensor<ScalarT> N(3);
00135 Intrepid::Tensor<ScalarT> A(3);
00136 Intrepid::Tensor<ScalarT> expA(3);
00137
00138
00139
00140
00141
00142
00143 Albany::MDArray Fpold = (*workset.stateArrayPtr)[fpName];
00144 Albany::MDArray eqpsold = (*workset.stateArrayPtr)[eqpsName];
00145 Albany::MDArray phi_old_FC = (*workset.stateArrayPtr)["Damage_old"];
00146
00147
00148 RST::inverse(Fpinv, Fpold);
00149 RST::transpose(FpinvT, Fpinv);
00150 FST::tensorMultiplyDataData<ScalarT>(Cpinv, Fpinv, FpinvT);
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191 for (std::size_t cell = 0; cell < workset.numCells; ++cell) {
00192 for (std::size_t qp = 0; qp < numQPs; ++qp) {
00193
00194 kappa = bulkModulus(cell, qp);
00195 mu = shearModulus(cell, qp);
00196 K = hardeningModulus(cell, qp);
00197 Y = yieldStrength(cell, qp);
00198 siginf = satMod(cell, qp);
00199 delta = satExp(cell, qp);
00200 Jm23 = std::pow(J(cell, qp), -2. / 3.);
00201 phi_old = phi_old_FC(cell, qp);
00202
00203 phi = damage(cell, qp);
00204 H = (1.0 - phi);
00205 H2 = H * H;
00206
00207 be.clear();
00208
00209 for (std::size_t i = 0; i < numDims; ++i)
00210 for (std::size_t j = 0; j < numDims; ++j)
00211 for (std::size_t p = 0; p < numDims; ++p)
00212 for (std::size_t q = 0; q < numDims; ++q)
00213 be(i, j) += Jm23 * defgrad(cell, qp, i, p)
00214 * Cpinv(cell, qp, p, q) * defgrad(cell, qp, j, q);
00215
00216
00217
00218 trd3 = Intrepid::trace(be) / 3.;
00219 mubar = trd3 * mu;
00220 s = mu * (be - trd3 * Intrepid::eye<ScalarT>(3));
00221
00222
00223
00224
00225 smag = norm(s);
00226
00227 f = smag
00228 - sq23
00229 * (Y + K * eqpsold(cell, qp)
00230 + siginf * (1. - std::exp(-delta * eqpsold(cell, qp))));
00231
00232
00233
00234
00235
00236
00237
00238 if (f > 1E-8) {
00239
00240 bool converged = false;
00241 ScalarT g = f;
00242 ScalarT H = K * eqpsold(cell, qp)
00243 + siginf * (1. - std::exp(-delta * eqpsold(cell, qp)));
00244 ScalarT dg = (-2. * mubar) * (1. + H / (3. * mubar));
00245 ScalarT dH = 0.0;
00246 ;
00247 ScalarT alpha = 0.0;
00248 ScalarT res = 0.0;
00249 int count = 0;
00250 dgam = 0.0;
00251
00252 while (!converged) {
00253 count++;
00254
00255
00256 dgam -= g / dg;
00257
00258 alpha = eqpsold(cell, qp) + sq23 * dgam;
00259
00260
00261
00262 H = K * alpha + siginf * (1. - std::exp(-delta * alpha));
00263 dH = K + delta * siginf * std::exp(-delta * alpha);
00264
00265 g = smag - (2. * mubar * dgam + sq23 * (Y + H));
00266 dg = -2. * mubar * (1. + dH / (3. * mubar));
00267
00268 res = std::abs(g);
00269 if (res < 1.e-8 || res / f < 1.e-8) converged = true;
00270
00271 TEUCHOS_TEST_FOR_EXCEPTION( count > 50, std::runtime_error,
00272 std::endl << "Error in return mapping, count = " << count << "\nres = " << res << "\nrelres = " << res/f << "\ng = " << g << "\ndg = " << dg << "\nalpha = " << alpha << std::endl);
00273
00274 }
00275
00276
00277 dp(cell, qp) = dgam;
00278
00279
00280 N = ScalarT(1. / smag) * s;
00281
00282
00283 s -= ScalarT(2. * mubar * dgam) * N;
00284
00285
00286 eqps(cell, qp) = alpha;
00287
00288
00289 A = dgam * N;
00290 expA = Intrepid::exp<ScalarT>(A);
00291
00292
00293
00294
00295
00296
00297
00298 for (std::size_t i = 0; i < numDims; ++i) {
00299 for (std::size_t j = 0; j < numDims; ++j) {
00300 Fp(cell, qp, i, j) = 0.0;
00301 for (std::size_t p = 0; p < numDims; ++p) {
00302 Fp(cell, qp, i, j) += expA(i, p) * Fpold(cell, qp, p, j);
00303 }
00304 }
00305 }
00306 } else {
00307
00308 dp(cell, qp) = 0.0;
00309 eqps(cell, qp) = eqpsold(cell, qp);
00310 for (std::size_t i = 0; i < numDims; ++i)
00311 for (std::size_t j = 0; j < numDims; ++j)
00312 Fp(cell, qp, i, j) = Fpold(cell, qp, i, j);
00313 }
00314
00315
00316 p = 0.5 * kappa * (J(cell, qp) - 1 / (J(cell, qp)));
00317
00318
00319 for (std::size_t i = 0; i < numDims; ++i) {
00320 for (std::size_t j = 0; j < numDims; ++j) {
00321 stress(cell, qp, i, j) = s(i, j) / J(cell, qp);
00322
00323 }
00324 stress(cell, qp, i, i) += p;
00325 }
00326
00327
00328 for (std::size_t i = 0; i < numDims; ++i)
00329 for (std::size_t j = 0; j < numDims; ++j)
00330 stress(cell, qp, i, j) *= H2;
00331
00332
00333 be = ScalarT(1 / mu) * s + trd3 * Intrepid::eye<ScalarT>(3);
00334
00335
00336 energy(cell, qp) = 0.5 * kappa
00337 * (0.5 * (J(cell, qp) * J(cell, qp) - 1.0) - std::log(J(cell, qp)))
00338 + 0.5 * mu * (Intrepid::trace(be) - 3.0);
00339
00340
00341 seff(cell, qp) = Intrepid::norm(ScalarT(1.0 / J(cell, qp)) * s);
00342
00343 if (print) {
00344 std::cout << "********" << std::endl;
00345 std::cout << "damage : " << damage(cell, qp) << std::endl;
00346 std::cout << "phi : " << phi << std::endl;
00347 std::cout << "H2 : " << H2 << std::endl;
00348 std::cout << "stress : ";
00349 for (std::size_t i = 0; i < numDims; ++i)
00350 for (std::size_t j = 0; j < numDims; ++j)
00351 std::cout << stress(cell, qp, i, j) << " ";
00352 std::cout << std::endl;
00353 std::cout << "energy : " << energy(cell, qp) << std::endl;
00354 std::cout << "dp : " << dp(cell, qp) << std::endl;
00355 }
00356 }
00357 }
00358 }
00359
00360 }
00361