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

CapImplicit_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 #include "LocalNonlinearSolver.hpp"
00011 namespace LCM
00012 {
00013 
00014 //**********************************************************************
00015   template<typename EvalT, typename Traits>
00016   CapImplicit<EvalT, Traits>::
00017   CapImplicit(const Teuchos::ParameterList& p,
00018               const Teuchos::RCP<Albany::Layouts>& dl) :
00019     elasticModulus(p.get<std::string>("Elastic Modulus Name"),dl->qp_scalar),
00020     poissonsRatio(p.get<std::string>("Poissons Ratio Name"),dl->qp_scalar),
00021     strain(p.get<std::string>("Strain Name"),dl->qp_tensor),
00022     stress(p.get<std::string>("Stress Name"),dl->qp_tensor),
00023     backStress(p.get<std::string>("Back Stress Name"),dl->qp_tensor),
00024     capParameter(p.get<std::string>("Cap Parameter Name"),dl->qp_scalar),
00025     //friction(p.get<std::string>("Friction Name"),dl->qp_scalar),
00026     //dilatancy(p.get<std::string>("Dilatancy Name"),dl->qp_scalar),
00027     eqps(p.get<std::string>("Eqps Name"),dl->qp_scalar),
00028     //hardeningModulus(p.get<std::string>("Hardening Modulus Name"),dl->qp_scalar),
00029     volPlasticStrain(p.get<std::string>("Vol Plastic Strain Name"),dl->qp_scalar),
00030     A(p.get<RealType>("A Name")),
00031     B(p.get<RealType>("B Name")),
00032     C(p.get<RealType>("C Name")),
00033     theta(p.get<RealType>("Theta Name")),
00034     R(p.get<RealType>("R Name")),
00035     kappa0(p.get<RealType>("Kappa0 Name")),
00036     W(p.get<RealType>("W Name")),
00037     D1(p.get<RealType>("D1 Name")),
00038     D2(p.get<RealType>("D2 Name")),
00039     calpha(p.get<RealType>("Calpha Name")),
00040     psi(p.get<RealType>("Psi Name")),
00041     N(p.get<RealType>("N Name")),
00042     L(p.get<RealType>("L Name")),
00043     phi(p.get<RealType>("Phi Name")),
00044     Q(p.get<RealType>("Q Name"))
00045   {
00046     // Pull out numQPs and numDims from a Layout
00047     Teuchos::RCP<PHX::DataLayout> tensor_dl = p.get<
00048         Teuchos::RCP<PHX::DataLayout> >("QP Tensor Data Layout");
00049     std::vector<PHX::DataLayout::size_type> dims;
00050     tensor_dl->dimensions(dims);
00051     numQPs = dims[1];
00052     numDims = dims[2];
00053 
00054     this->addDependentField(elasticModulus);
00055     // PoissonRatio not used in 1D stress calc
00056     if (numDims > 1)
00057       this->addDependentField(poissonsRatio);
00058     this->addDependentField(strain);
00059 
00060     // state variable
00061     strainName = p.get<std::string>("Strain Name") + "_old";
00062     stressName = p.get<std::string>("Stress Name") + "_old";
00063     backStressName = p.get<std::string>("Back Stress Name") + "_old";
00064     capParameterName = p.get<std::string>("Cap Parameter Name") + "_old";
00065     eqpsName = p.get<std::string>("Eqps Name") + "_old";
00066     volPlasticStrainName = p.get<std::string>("Vol Plastic Strain Name")
00067         + "_old";
00068 
00069     // evaluated fields
00070     this->addEvaluatedField(stress);
00071     this->addEvaluatedField(backStress);
00072     this->addEvaluatedField(capParameter);
00073     //this->addEvaluatedField(friction);
00074     //this->addEvaluatedField(dilatancy);
00075     this->addEvaluatedField(eqps);
00076     //this->addEvaluatedField(hardeningModulus);
00077     this->addEvaluatedField(volPlasticStrain);
00078 
00079     this->setName("Stress" + PHX::TypeString<EvalT>::value);
00080 
00081   }
00082 
00083 //**********************************************************************
00084   template<typename EvalT, typename Traits>
00085   void CapImplicit<EvalT, Traits>::postRegistrationSetup(
00086       typename Traits::SetupData d, PHX::FieldManager<Traits>& fm)
00087   {
00088     this->utils.setFieldData(elasticModulus, fm);
00089     if (numDims > 1)
00090       this->utils.setFieldData(poissonsRatio, fm);
00091     this->utils.setFieldData(stress, fm);
00092     this->utils.setFieldData(strain, fm);
00093     this->utils.setFieldData(backStress, fm);
00094     this->utils.setFieldData(capParameter, fm);
00095     //this->utils.setFieldData(friction, fm);
00096     //this->utils.setFieldData(dilatancy, fm);
00097     this->utils.setFieldData(eqps, fm);
00098     //this->utils.setFieldData(hardeningModulus, fm);
00099     this->utils.setFieldData(volPlasticStrain, fm);
00100 
00101   }
00102 
00103 //**********************************************************************
00104 
00105   template<typename EvalT, typename Traits>
00106   void CapImplicit<EvalT, Traits>::evaluateFields(
00107       typename Traits::EvalData workset)
00108   {
00109 
00110     // previous state
00111     Albany::MDArray strainold = (*workset.stateArrayPtr)[strainName];
00112     Albany::MDArray stressold = (*workset.stateArrayPtr)[stressName];
00113     Albany::MDArray backStressold = (*workset.stateArrayPtr)[backStressName];
00114     Albany::MDArray capParameterold = (*workset.stateArrayPtr)[capParameterName];
00115     Albany::MDArray eqpsold = (*workset.stateArrayPtr)[eqpsName];
00116     Albany::MDArray volPlasticStrainold =
00117         (*workset.stateArrayPtr)[volPlasticStrainName];
00118 
00119     for (std::size_t cell = 0; cell < workset.numCells; ++cell) {
00120       for (std::size_t qp = 0; qp < numQPs; ++qp) {
00121         // local parameters
00122         ScalarT lame = elasticModulus(cell, qp) * poissonsRatio(cell, qp)
00123             / (1.0 + poissonsRatio(cell, qp))
00124             / (1.0 - 2.0 * poissonsRatio(cell, qp));
00125         ScalarT mu = elasticModulus(cell, qp) / 2.0
00126             / (1.0 + poissonsRatio(cell, qp));
00127         ScalarT bulkModulus = lame + (2. / 3.) * mu;
00128 
00129         // elastic matrix
00130         Intrepid::Tensor4<ScalarT> Celastic = lame
00131             * Intrepid::identity_3<ScalarT>(3)
00132             + mu
00133                 * (Intrepid::identity_1<ScalarT>(3)
00134                     + Intrepid::identity_2<ScalarT>(3));
00135 
00136         // elastic compliance tangent matrix
00137         Intrepid::Tensor4<ScalarT> compliance = (1. / bulkModulus / 9.)
00138             * Intrepid::identity_3<ScalarT>(3)
00139             + (1. / mu / 2.)
00140                 * (0.5
00141                     * (Intrepid::identity_1<ScalarT>(3)
00142                         + Intrepid::identity_2<ScalarT>(3))
00143                     - (1. / 3.) * Intrepid::identity_3<ScalarT>(3));
00144 
00145         // previous state
00146         Intrepid::Tensor<ScalarT>
00147         sigmaN(3, Intrepid::ZEROS),
00148         alphaN(3, Intrepid::ZEROS),
00149         strainN(3, Intrepid::ZEROS);
00150 
00151         // incremental strain tensor
00152         Intrepid::Tensor<ScalarT> depsilon(3);
00153         for (std::size_t i = 0; i < numDims; ++i) {
00154           for (std::size_t j = 0; j < numDims; ++j) {
00155             depsilon(i, j) = strain(cell, qp, i, j) - strainold(cell, qp, i, j);
00156             strainN(i, j) = strainold(cell, qp, i, j);
00157           }
00158         }
00159 
00160         // trial state
00161         Intrepid::Tensor<ScalarT> sigmaVal = Intrepid::dotdot(Celastic,
00162             depsilon);
00163         Intrepid::Tensor<ScalarT> alphaVal(3, Intrepid::ZEROS);
00164 
00165         for (std::size_t i = 0; i < numDims; ++i) {
00166           for (std::size_t j = 0; j < numDims; ++j) {
00167             sigmaVal(i, j) = sigmaVal(i, j) + stressold(cell, qp, i, j);
00168             alphaVal(i, j) = backStressold(cell, qp, i, j);
00169             sigmaN(i, j) = stressold(cell, qp, i, j);
00170             alphaN(i, j) = backStressold(cell, qp, i, j);
00171           }
00172         }
00173 
00174         ScalarT kappaVal = capParameterold(cell, qp);
00175         ScalarT dgammaVal = 0.0;
00176 
00177         // used in defining generalized hardening modulus
00178         ScalarT Htan(0.0);
00179 
00180         // define plastic strain increment, its two invariants: dev, and vol
00181         Intrepid::Tensor<ScalarT> deps_plastic(3, Intrepid::ZEROS);
00182         ScalarT deqps(0.0), devolps(0.0);
00183 
00184         // define temporary trial stress, used in computing plastic strain
00185         Intrepid::Tensor<ScalarT> sigmaTr = sigmaVal;
00186 
00187         std::vector<ScalarT> XXVal(13);
00188 
00189         // check yielding
00190         ScalarT f = compute_f(sigmaVal, alphaVal, kappaVal);
00191         XXVal = initialize(sigmaVal, alphaVal, kappaVal, dgammaVal);
00192 
00193         // local Newton loop
00194         if (f > 1.e-11) { // plastic yielding
00195 
00196           ScalarT normR, normR0, conv;
00197           bool kappa_flag = false;
00198           bool converged = false;
00199           int iter = 0;
00200 
00201           std::vector<ScalarT> R(13);
00202           std::vector<ScalarT> dRdX(13 * 13);
00203           LocalNonlinearSolver<EvalT, Traits> solver;
00204 
00205           while (!converged) {
00206 
00207             // assemble residual vector and local Jacobian
00208             compute_ResidJacobian(XXVal, R, dRdX, sigmaVal, alphaVal, kappaVal,
00209                 Celastic, kappa_flag);
00210 
00211             normR = 0.0;
00212             for (int i = 0; i < 13; i++)
00213               normR += R[i] * R[i];
00214 
00215             normR = std::sqrt(normR);
00216 
00217             if (iter == 0)
00218               normR0 = normR;
00219             if (normR0 != 0)
00220               conv = normR / normR0;
00221             else
00222               conv = normR0;
00223 
00224             if (conv < 1.e-11 || normR < 1.e-11)
00225               break;
00226 
00227             if(iter > 20)
00228               break;
00229 
00230             //TEUCHOS_TEST_FOR_EXCEPTION( iter > 20, std::runtime_error,
00231              // std::endl << "Error in return mapping, iter = " << iter << "\nres = " << normR << "\nrelres = " << conv << std::endl);
00232 
00233             std::vector<ScalarT> XXValK = XXVal;
00234             solver.solve(dRdX, XXValK, R);
00235 
00236             // put restrictions on kappa: only allows monotonic decreasing (cap hardening)
00237             if (XXValK[11] > XXVal[11]) {
00238               kappa_flag = true;
00239             }
00240             else {
00241               XXVal = XXValK;
00242               kappa_flag = false;
00243             }
00244 
00245             // debugging
00246             //XXVal = XXValK;
00247 
00248             iter++;
00249           } //end local NR
00250 
00251           // compute sensitivity information, and pack back to X.
00252           solver.computeFadInfo(dRdX, XXVal, R);
00253 
00254         } // end of plasticity
00255 
00256         // update
00257         sigmaVal(0, 0) = XXVal[0];
00258         sigmaVal(0, 1) = XXVal[5];
00259         sigmaVal(0, 2) = XXVal[4];
00260         sigmaVal(1, 0) = XXVal[5];
00261         sigmaVal(1, 1) = XXVal[1];
00262         sigmaVal(1, 2) = XXVal[3];
00263         sigmaVal(2, 0) = XXVal[4];
00264         sigmaVal(2, 1) = XXVal[3];
00265         sigmaVal(2, 2) = XXVal[2];
00266 
00267         alphaVal(0, 0) = XXVal[6];
00268         alphaVal(0, 1) = XXVal[10];
00269         alphaVal(0, 2) = XXVal[9];
00270         alphaVal(1, 0) = XXVal[10];
00271         alphaVal(1, 1) = XXVal[7];
00272         alphaVal(1, 2) = XXVal[8];
00273         alphaVal(2, 0) = XXVal[9];
00274         alphaVal(2, 1) = XXVal[8];
00275         alphaVal(2, 2) = -XXVal[6] - XXVal[7];
00276 
00277         kappaVal = XXVal[11];
00278 
00279         //dgammaVal = XXVal[12];
00280 
00281         //compute plastic strain increment deps_plastic = compliance ( sigma_tr - sigma_(n+1));
00282         Intrepid::Tensor<ScalarT> dsigma = sigmaTr - sigmaVal;
00283         deps_plastic = Intrepid::dotdot(compliance, dsigma);
00284 
00285         // compute its two invariants: devolps (volumetric) and deqps (deviatoric)
00286         devolps = Intrepid::trace(deps_plastic);
00287         Intrepid::Tensor<ScalarT> dev_plastic = deps_plastic
00288             - (1.0 / 3.0) * devolps * Intrepid::identity<ScalarT>(3);
00289         //deqps = std::sqrt(2./3.) * Intrepid::norm(dev_plastic);
00290         // use altenative definition, just differ by constants
00291         deqps = std::sqrt(2) * Intrepid::norm(dev_plastic);
00292 
00293         //
00294         // update
00295         //
00296         // dilatancy
00297         //if (deqps != 0)
00298           //dilatancy(cell, qp) = devolps / deqps;
00299         //else
00300           //dilatancy(cell, qp) = 0.0;
00301 
00302         // friction coefficient = dtau / dp;
00303         // previous p and tau
00304         //ScalarT pN(0.0), tauN(0.0);
00305         //Intrepid::Tensor<ScalarT> xi = sigmaN - alphaN;
00306         //pN = Intrepid::trace(xi);
00307         //pN = pN / 3.0;
00308         //Intrepid::Tensor<ScalarT> sN =
00309             //xi - pN * Intrepid::identity<ScalarT>(3.0);
00310         //qN = sqrt(3./2.) * Intrepid::norm(sN);
00311         //tauN = sqrt(1.0 / 2.0) * Intrepid::norm(sN);
00312 
00313         // current p, and tau
00314         //ScalarT p(0.0), tau(0.0);
00315         //xi = sigmaVal - alphaVal;
00316         //p = Intrepid::trace(xi);
00317         //p = p / 3.0;
00318         //Intrepid::Tensor<ScalarT> s = xi - p * Intrepid::identity<ScalarT>(3);
00319         //q = sqrt(3./2.) * Intrepid::norm(s);
00320         //tau = sqrt(1.0 / 2.0) * Intrepid::norm(s);
00321         //Intrepid::Tensor<ScalarT, 3> ds = s - sN;
00322 
00323         // difference
00324         //ScalarT dtau = tau - tauN;
00325         //ScalarT dtau = sqrt(1./2.) * Intrepid::norm(ds);
00326         //ScalarT dp = p - pN;
00327 
00328         // friction coefficient by finite difference
00329         //if (dp != 0)
00330           //friction(cell, qp) = dtau / dp;
00331         //else
00332           //friction(cell, qp) = 0.0;
00333 
00334         // hardening modulus
00335         // previous r(gamma)
00336         //ScalarT rN(0.0);
00337         //ScalarT evol3 = Intrepid::trace(strainN);
00338         //evol3 = evol3 / 3.;
00339         //Intrepid::Tensor<ScalarT> e = strainN
00340             //- evol3 * Intrepid::identity<ScalarT>(3);
00341         //rN = sqrt(2.) * Intrepid::norm(e);
00342 
00343         // current r(gamma)
00344         //ScalarT r(0.0);
00345         //Intrepid::Tensor<ScalarT> strainCurrent = strainN + depsilon;
00346         //evol3 = Intrepid::trace(strainCurrent);
00347         //evol3 = evol3 / 3.;
00348         //e = strainCurrent - evol3 * Intrepid::identity<ScalarT>(3);
00349         //r = sqrt(2.) * Intrepid::norm(e);
00350 
00351         // difference
00352         //ScalarT dr = r - rN;
00353         // tagent hardening modulus
00354         //if (dr != 0)
00355           //Htan = dtau / dr;
00356 
00357         //if (std::abs(1. - Htan / mu) > 0)
00358           //hardeningModulus(cell, qp) = Htan / (1. - Htan / mu);
00359         //else
00360           //hardeningModulus(cell, qp) = 0.0;
00361 
00362         // stress and back stress
00363         for (std::size_t i = 0; i < numDims; ++i) {
00364           for (std::size_t j = 0; j < numDims; ++j) {
00365             stress(cell, qp, i, j) = sigmaVal(i, j);
00366             backStress(cell, qp, i, j) = alphaVal(i, j);
00367           }
00368         }
00369 
00370         capParameter(cell, qp) = kappaVal;
00371         eqps(cell, qp) = eqpsold(cell, qp) + deqps;
00372         volPlasticStrain(cell, qp) = volPlasticStrainold(cell, qp) + devolps;
00373 
00374       } //loop over qps
00375 
00376     } //loop over cell
00377 
00378   } // end of evaluateFields
00379 
00380 //**********************************************************************
00381 // all local functions
00382   template<typename EvalT, typename Traits>
00383   typename CapImplicit<EvalT, Traits>::ScalarT CapImplicit<EvalT, Traits>::compute_f(
00384       Intrepid::Tensor<ScalarT> & sigma, Intrepid::Tensor<ScalarT> & alpha,
00385       ScalarT & kappa)
00386   {
00387 
00388     Intrepid::Tensor<ScalarT> xi = sigma - alpha;
00389 
00390     ScalarT I1 = Intrepid::trace(xi), p = I1 / 3.;
00391 
00392     Intrepid::Tensor<ScalarT> s = xi - p * Intrepid::identity<ScalarT>(3);
00393 
00394     ScalarT J2 = 0.5 * Intrepid::dotdot(s, s);
00395 
00396     ScalarT J3 = Intrepid::det(s);
00397 
00398     ScalarT Gamma = 1.0;
00399     if (psi != 0 && J2 != 0)
00400       Gamma =
00401           0.5
00402               * (1. - 3. * std::sqrt(3.0) * J3 / 2. / std::pow(J2, 1.5)
00403                   + (1. + 3.0 * std::sqrt(3.0) * J3 / 2. / std::pow(J2, 1.5))
00404                       / psi);
00405 
00406     ScalarT Ff_I1 = A - C * std::exp(B * I1) - theta * I1;
00407 
00408     ScalarT Ff_kappa = A - C * std::exp(B * kappa) - theta * kappa;
00409 
00410     ScalarT X = kappa - R * Ff_kappa;
00411 
00412     ScalarT Fc = 1.0;
00413 
00414     if ((kappa - I1) > 0 && ((X - kappa) != 0))
00415       Fc = 1.0 - (I1 - kappa) * (I1 - kappa) / (X - kappa) / (X - kappa);
00416 
00417     return Gamma * Gamma * J2 - Fc * (Ff_I1 - N) * (Ff_I1 - N);
00418   }
00419 
00420   template<typename EvalT, typename Traits>
00421   typename CapImplicit<EvalT, Traits>::DFadType CapImplicit<EvalT, Traits>::compute_f(
00422       Intrepid::Tensor<DFadType> & sigma, Intrepid::Tensor<DFadType> & alpha,
00423       DFadType & kappa)
00424   {
00425 
00426     Intrepid::Tensor<DFadType> xi = sigma - alpha;
00427 
00428     DFadType I1 = Intrepid::trace(xi), p = I1 / 3.;
00429 
00430     Intrepid::Tensor<DFadType> s = xi - p * Intrepid::identity<DFadType>(3);
00431 
00432     DFadType J2 = 0.5 * Intrepid::dotdot(s, s);
00433 
00434     DFadType J3 = Intrepid::det(s);
00435 
00436     DFadType Gamma = 1.0;
00437     if (psi != 0 && J2 != 0)
00438       Gamma =
00439           0.5
00440               * (1. - 3.0 * std::sqrt(3.0) * J3 / 2. / std::pow(J2, 1.5)
00441                   + (1. + 3.0 * std::sqrt(3.0) * J3 / 2. / std::pow(J2, 1.5))
00442                       / psi);
00443 
00444     DFadType Ff_I1 = A - C * std::exp(B * I1) - theta * I1;
00445 
00446     DFadType Ff_kappa = A - C * std::exp(B * kappa) - theta * kappa;
00447 
00448     DFadType X = kappa - R * Ff_kappa;
00449 
00450     DFadType Fc = 1.0;
00451 
00452     if ((kappa - I1) > 0 && ((X - kappa) != 0))
00453       Fc = 1.0 - (I1 - kappa) * (I1 - kappa) / (X - kappa) / (X - kappa);
00454 
00455     return Gamma * Gamma * J2 - Fc * (Ff_I1 - N) * (Ff_I1 - N);
00456   }
00457 
00458   template<typename EvalT, typename Traits>
00459   typename CapImplicit<EvalT, Traits>::D2FadType CapImplicit<EvalT, Traits>::compute_g(
00460       Intrepid::Tensor<D2FadType> & sigma, Intrepid::Tensor<D2FadType> & alpha,
00461       D2FadType & kappa)
00462   {
00463 
00464     Intrepid::Tensor<D2FadType> xi = sigma - alpha;
00465 
00466     D2FadType I1 = Intrepid::trace(xi), p = I1 / 3.;
00467 
00468     Intrepid::Tensor<D2FadType> s = xi - p * Intrepid::identity<D2FadType>(3);
00469 
00470     D2FadType J2 = 0.5 * Intrepid::dotdot(s, s);
00471 
00472     D2FadType J3 = Intrepid::det(s);
00473 
00474     D2FadType Gamma = 1.0;
00475     if (psi != 0 && J2 != 0)
00476       Gamma =
00477           0.5
00478               * (1. - 3.0 * std::sqrt(3.0) * J3 / 2. / std::pow(J2, 1.5)
00479                   + (1. + 3.0 * std::sqrt(3.0) * J3 / 2. / std::pow(J2, 1.5))
00480                       / psi);
00481 
00482     D2FadType Ff_I1 = A - C * std::exp(L * I1) - phi * I1;
00483 
00484     D2FadType Ff_kappa = A - C * std::exp(L * kappa) - phi * kappa;
00485 
00486     D2FadType X = kappa - Q * Ff_kappa;
00487 
00488     D2FadType Fc = 1.0;
00489 
00490     if ((kappa - I1) > 0 && ((X - kappa) != 0))
00491       Fc = 1.0 - (I1 - kappa) * (I1 - kappa) / (X - kappa) / (X - kappa);
00492 
00493     return Gamma * Gamma * J2 - Fc * (Ff_I1 - N) * (Ff_I1 - N);
00494   }
00495 
00496   template<typename EvalT, typename Traits>
00497   std::vector<typename CapImplicit<EvalT, Traits>::ScalarT> CapImplicit<EvalT,
00498       Traits>::initialize(Intrepid::Tensor<ScalarT> & sigmaVal,
00499       Intrepid::Tensor<ScalarT> & alphaVal, ScalarT & kappaVal,
00500       ScalarT & dgammaVal)
00501   {
00502     std::vector<ScalarT> XX(13);
00503 
00504     XX[0] = sigmaVal(0, 0);
00505     XX[1] = sigmaVal(1, 1);
00506     XX[2] = sigmaVal(2, 2);
00507     XX[3] = sigmaVal(1, 2);
00508     XX[4] = sigmaVal(0, 2);
00509     XX[5] = sigmaVal(0, 1);
00510     XX[6] = alphaVal(0, 0);
00511     XX[7] = alphaVal(1, 1);
00512     XX[8] = alphaVal(1, 2);
00513     XX[9] = alphaVal(0, 2);
00514     XX[10] = alphaVal(0, 1);
00515     XX[11] = kappaVal;
00516     XX[12] = dgammaVal;
00517 
00518     return XX;
00519   }
00520 
00521   template<typename EvalT, typename Traits>
00522   Intrepid::Tensor<typename CapImplicit<EvalT, Traits>::DFadType> CapImplicit<
00523       EvalT, Traits>::compute_dgdsigma(std::vector<DFadType> const & XX)
00524   {
00525     std::vector<D2FadType> D2XX(13);
00526 
00527     for (int i = 0; i < 13; ++i) {
00528       D2XX[i] = D2FadType(13, i, XX[i]);
00529     }
00530 
00531     Intrepid::Tensor<D2FadType> sigma(3), alpha(3);
00532 
00533     sigma(0, 0) = D2XX[0];
00534     sigma(0, 1) = D2XX[5];
00535     sigma(0, 2) = D2XX[4];
00536     sigma(1, 0) = D2XX[5];
00537     sigma(1, 1) = D2XX[1];
00538     sigma(1, 2) = D2XX[3];
00539     sigma(2, 0) = D2XX[4];
00540     sigma(2, 1) = D2XX[3];
00541     sigma(2, 2) = D2XX[2];
00542 
00543     alpha(0, 0) = D2XX[6];
00544     alpha(0, 1) = D2XX[10];
00545     alpha(0, 2) = D2XX[9];
00546     alpha(1, 0) = D2XX[10];
00547     alpha(1, 1) = D2XX[7];
00548     alpha(1, 2) = D2XX[8];
00549     alpha(2, 0) = D2XX[9];
00550     alpha(2, 1) = D2XX[8];
00551     alpha(2, 2) = -D2XX[6] - D2XX[7];
00552 
00553     D2FadType kappa = D2XX[11];
00554 
00555     D2FadType g = compute_g(sigma, alpha, kappa);
00556 
00557     Intrepid::Tensor<DFadType> dgdsigma(3);
00558 
00559     dgdsigma(0, 0) = g.dx(0);
00560     dgdsigma(0, 1) = g.dx(5);
00561     dgdsigma(0, 2) = g.dx(4);
00562     dgdsigma(1, 0) = g.dx(5);
00563     dgdsigma(1, 1) = g.dx(1);
00564     dgdsigma(1, 2) = g.dx(3);
00565     dgdsigma(2, 0) = g.dx(4);
00566     dgdsigma(2, 1) = g.dx(3);
00567     dgdsigma(2, 2) = g.dx(2);
00568 
00569     return dgdsigma;
00570   }
00571 
00572   template<typename EvalT, typename Traits>
00573   typename CapImplicit<EvalT, Traits>::DFadType CapImplicit<EvalT, Traits>::compute_Galpha(
00574       DFadType J2_alpha)
00575   {
00576     if (N != 0)
00577       return 1.0 - pow(J2_alpha, 0.5) / N;
00578     else
00579       return 0.0;
00580   }
00581 
00582   template<typename EvalT, typename Traits>
00583   Intrepid::Tensor<typename CapImplicit<EvalT, Traits>::DFadType> CapImplicit<
00584       EvalT, Traits>::compute_halpha(
00585       Intrepid::Tensor<DFadType> const & dgdsigma, DFadType const J2_alpha)
00586   {
00587 
00588     DFadType Galpha = compute_Galpha(J2_alpha);
00589 
00590     DFadType I1 = Intrepid::trace(dgdsigma), p = I1 / 3.0;
00591 
00592     Intrepid::Tensor<DFadType> s = dgdsigma
00593         - p * Intrepid::identity<DFadType>(3);
00594 
00595     //Intrepid::Tensor<DFadType, 3> halpha = calpha * Galpha * s; // * operator not defined;
00596     Intrepid::Tensor<DFadType> halpha(3);
00597     for (int i = 0; i < 3; i++) {
00598       for (int j = 0; j < 3; j++) {
00599         halpha(i, j) = calpha * Galpha * s(i, j);
00600       }
00601     }
00602 
00603     return halpha;
00604   }
00605 
00606   template<typename EvalT, typename Traits>
00607   typename CapImplicit<EvalT, Traits>::DFadType CapImplicit<EvalT, Traits>::compute_dedkappa(
00608       DFadType const kappa)
00609   {
00610 
00611     //******** use analytical expression
00612     ScalarT Ff_kappa0 = A - C * std::exp(L * kappa0) - phi * kappa0;
00613 
00614     ScalarT X0 = kappa0 - Q * Ff_kappa0;
00615 
00616     DFadType Ff_kappa = A - C * std::exp(L * kappa) - phi * kappa;
00617 
00618     DFadType X = kappa - Q * Ff_kappa;
00619 
00620     DFadType dedX = (D1 - 2. * D2 * (X - X0))
00621         * std::exp((D1 - D2 * (X - X0)) * (X - X0)) * W;
00622 
00623     DFadType dXdkappa = 1. + Q * C * L * exp(L * kappa) + Q * phi;
00624 
00625     return dedX * dXdkappa;
00626   }
00627 
00628   template<typename EvalT, typename Traits>
00629   typename CapImplicit<EvalT, Traits>::DFadType CapImplicit<EvalT, Traits>::compute_hkappa(
00630       DFadType const I1_dgdsigma, DFadType const dedkappa)
00631   {
00632     if (dedkappa != 0)
00633       return I1_dgdsigma / dedkappa;
00634     else
00635       return 0;
00636   }
00637 
00638   template<typename EvalT, typename Traits>
00639   void CapImplicit<EvalT, Traits>::compute_ResidJacobian(
00640       std::vector<ScalarT> const & XXVal, std::vector<ScalarT> & R,
00641       std::vector<ScalarT> & dRdX, const Intrepid::Tensor<ScalarT> & sigmaVal,
00642       const Intrepid::Tensor<ScalarT> & alphaVal, const ScalarT & kappaVal,
00643       Intrepid::Tensor4<ScalarT> const & Celastic, bool kappa_flag)
00644   {
00645 
00646     std::vector<DFadType> Rfad(13);
00647     std::vector<DFadType> XX(13);
00648     std::vector<ScalarT> XXtmp(13);
00649 
00650     // initialize DFadType local unknown vector Xfad
00651     // Note that since Xfad is a temporary variable that gets changed within local iterations
00652     // when we initialize Xfad, we only pass in the values of X, NOT the system sensitivity information
00653     for (int i = 0; i < 13; ++i) {
00654       XXtmp[i] = Sacado::ScalarValue<ScalarT>::eval(XXVal[i]);
00655       XX[i] = DFadType(13, i, XXtmp[i]);
00656     }
00657 
00658     Intrepid::Tensor<DFadType> sigma(3), alpha(3);
00659 
00660     sigma(0, 0) = XX[0];
00661     sigma(0, 1) = XX[5];
00662     sigma(0, 2) = XX[4];
00663     sigma(1, 0) = XX[5];
00664     sigma(1, 1) = XX[1];
00665     sigma(1, 2) = XX[3];
00666     sigma(2, 0) = XX[4];
00667     sigma(2, 1) = XX[3];
00668     sigma(2, 2) = XX[2];
00669 
00670     alpha(0, 0) = XX[6];
00671     alpha(0, 1) = XX[10];
00672     alpha(0, 2) = XX[9];
00673     alpha(1, 0) = XX[10];
00674     alpha(1, 1) = XX[7];
00675     alpha(1, 2) = XX[8];
00676     alpha(2, 0) = XX[9];
00677     alpha(2, 1) = XX[8];
00678     alpha(2, 2) = -XX[6] - XX[7];
00679 
00680     DFadType kappa = XX[11];
00681 
00682     DFadType dgamma = XX[12];
00683 
00684     DFadType f = compute_f(sigma, alpha, kappa);
00685 
00686     Intrepid::Tensor<DFadType> dgdsigma = compute_dgdsigma(XX);
00687 
00688     DFadType J2_alpha = 0.5 * Intrepid::dotdot(alpha, alpha);
00689 
00690     Intrepid::Tensor<DFadType> halpha = compute_halpha(dgdsigma, J2_alpha);
00691 
00692     DFadType I1_dgdsigma = Intrepid::trace(dgdsigma);
00693 
00694     DFadType dedkappa = compute_dedkappa(kappa);
00695 
00696     DFadType hkappa = compute_hkappa(I1_dgdsigma, dedkappa);
00697 
00698     DFadType t;
00699 
00700     t = 0;
00701     for (int i = 0; i < 3; i++) {
00702       for (int j = 0; j < 3; j++) {
00703         t = t + Celastic(0, 0, i, j) * dgdsigma(i, j);
00704       }
00705     }
00706     Rfad[0] = dgamma * t + sigma(0, 0) - sigmaVal(0, 0);
00707 
00708     t = 0;
00709     for (int i = 0; i < 3; i++) {
00710       for (int j = 0; j < 3; j++) {
00711         t = t + Celastic(1, 1, i, j) * dgdsigma(i, j);
00712       }
00713     }
00714     Rfad[1] = dgamma * t + sigma(1, 1) - sigmaVal(1, 1);
00715 
00716     t = 0;
00717     for (int i = 0; i < 3; i++) {
00718       for (int j = 0; j < 3; j++) {
00719         t = t + Celastic(2, 2, i, j) * dgdsigma(i, j);
00720       }
00721     }
00722     Rfad[2] = dgamma * t + sigma(2, 2) - sigmaVal(2, 2);
00723 
00724     t = 0;
00725     for (int i = 0; i < 3; i++) {
00726       for (int j = 0; j < 3; j++) {
00727         t = t + Celastic(1, 2, i, j) * dgdsigma(i, j);
00728       }
00729     }
00730     Rfad[3] = dgamma * t + sigma(1, 2) - sigmaVal(1, 2);
00731 
00732     t = 0;
00733     for (int i = 0; i < 3; i++) {
00734       for (int j = 0; j < 3; j++) {
00735         t = t + Celastic(0, 2, i, j) * dgdsigma(i, j);
00736       }
00737     }
00738     Rfad[4] = dgamma * t + sigma(0, 2) - sigmaVal(0, 2);
00739 
00740     t = 0;
00741     for (int i = 0; i < 3; i++) {
00742       for (int j = 0; j < 3; j++) {
00743         t = t + Celastic(0, 1, i, j) * dgdsigma(i, j);
00744       }
00745     }
00746     Rfad[5] = dgamma * t + sigma(0, 1) - sigmaVal(0, 1);
00747 
00748     Rfad[6] = dgamma * halpha(0, 0) - alpha(0, 0) + alphaVal(0, 0);
00749 
00750     Rfad[7] = dgamma * halpha(1, 1) - alpha(1, 1) + alphaVal(1, 1);
00751 
00752     Rfad[8] = dgamma * halpha(1, 2) - alpha(1, 2) + alphaVal(1, 2);
00753 
00754     Rfad[9] = dgamma * halpha(0, 2) - alpha(0, 2) + alphaVal(0, 2);
00755 
00756     Rfad[10] = dgamma * halpha(0, 1) - alpha(0, 1) + alphaVal(0, 1);
00757 
00758     if (kappa_flag == false)
00759       Rfad[11] = dgamma * hkappa - kappa + kappaVal;
00760     else
00761       Rfad[11] = 0;
00762 
00763     // debugging
00764 //  if(kappa_flag == false)Rfad[11] = -dgamma * hkappa - kappa + kappaVal;
00765 //  else Rfad[11] = 0;
00766 
00767     Rfad[12] = f;
00768 
00769     // get ScalarT Residual
00770     for (int i = 0; i < 13; i++)
00771       R[i] = Rfad[i].val();
00772 
00773     //std::cout << "in assemble_Resid, R= " << R[0] << " " << R[1] << " " << R[2] << " " << R[3]<< std::endl;
00774 
00775     // get Jacobian
00776     for (int i = 0; i < 13; i++)
00777       for (int j = 0; j < 13; j++)
00778         dRdX[i + 13 * j] = Rfad[i].dx(j);
00779 
00780     if (kappa_flag == true) {
00781       for (int j = 0; j < 13; j++)
00782         dRdX[11 + 13 * j] = 0.0;
00783 
00784       dRdX[11 + 13 * 11] = 1.0;
00785     }
00786 
00787   }
00788 
00789 } // end LCM

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