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

CreepModel_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 <Intrepid_MiniTensor.h>
00008 #include "Teuchos_TestForException.hpp"
00009 #include "Phalanx_DataLayout.hpp"
00010 
00011 #include "LocalNonlinearSolver.hpp"
00012 
00013 namespace LCM
00014 {
00015 
00016 //------------------------------------------------------------------------------
00017 template<typename EvalT, typename Traits>
00018 CreepModel<EvalT, Traits>::
00019 CreepModel(Teuchos::ParameterList* p,
00020     const Teuchos::RCP<Albany::Layouts>& dl) :
00021     LCM::ConstitutiveModel<EvalT, Traits>(p, dl),
00022     creep_initial_guess(p->get<RealType>("Initial Creep Guess", 1.1e-4))
00023 {
00024   // retrive appropriate field name strings
00025   std::string cauchy_string = (*field_name_map_)["Cauchy_Stress"];
00026   std::string Fp_string = (*field_name_map_)["Fp"];
00027   std::string eqps_string = (*field_name_map_)["eqps"];
00028   std::string source_string = (*field_name_map_)["Mechanical_Source"];
00029   std::string F_string = (*field_name_map_)["F"];
00030   std::string J_string = (*field_name_map_)["J"];
00031 
00032   // define the dependent fields
00033   this->dep_field_map_.insert(std::make_pair(F_string, dl->qp_tensor));
00034   this->dep_field_map_.insert(std::make_pair(J_string, dl->qp_scalar));
00035   this->dep_field_map_.insert(std::make_pair("Poissons Ratio", dl->qp_scalar));
00036   this->dep_field_map_.insert(std::make_pair("Elastic Modulus", dl->qp_scalar));
00037   this->dep_field_map_.insert(std::make_pair("Yield Strength", dl->qp_scalar));
00038   this->dep_field_map_.insert(
00039       std::make_pair("Hardening Modulus", dl->qp_scalar));
00040   this->dep_field_map_.insert(std::make_pair("Delta Time", dl->workset_scalar));
00041 
00042   // define the evaluated fields
00043   this->eval_field_map_.insert(std::make_pair(cauchy_string, dl->qp_tensor));
00044   this->eval_field_map_.insert(std::make_pair(Fp_string, dl->qp_tensor));
00045   this->eval_field_map_.insert(std::make_pair(eqps_string, dl->qp_scalar));
00046   if (have_temperature_) {
00047     this->eval_field_map_.insert(std::make_pair(source_string, dl->qp_scalar));
00048   }
00049 
00050   // define the state variables
00051   //
00052   // stress
00053   this->num_state_variables_++;
00054   this->state_var_names_.push_back(cauchy_string);
00055   this->state_var_layouts_.push_back(dl->qp_tensor);
00056   this->state_var_init_types_.push_back("scalar");
00057   this->state_var_init_values_.push_back(0.0);
00058   this->state_var_old_state_flags_.push_back(false);
00059   this->state_var_output_flags_.push_back(p->get<bool>("Output Cauchy Stress", false));
00060   //
00061   // Fp
00062   this->num_state_variables_++;
00063   this->state_var_names_.push_back(Fp_string);
00064   this->state_var_layouts_.push_back(dl->qp_tensor);
00065   this->state_var_init_types_.push_back("identity");
00066   this->state_var_init_values_.push_back(0.0);
00067   this->state_var_old_state_flags_.push_back(true);
00068   this->state_var_output_flags_.push_back(p->get<bool>("Output Fp", false));
00069   //
00070   // eqps
00071   this->num_state_variables_++;
00072   this->state_var_names_.push_back(eqps_string);
00073   this->state_var_layouts_.push_back(dl->qp_scalar);
00074   this->state_var_init_types_.push_back("scalar");
00075   this->state_var_init_values_.push_back(0.0);
00076   this->state_var_old_state_flags_.push_back(true);
00077   this->state_var_output_flags_.push_back(p->get<bool>("Output eqps", false));
00078   //
00079   // mechanical source
00080   if (have_temperature_) {
00081     this->num_state_variables_++;
00082     this->state_var_names_.push_back(source_string);
00083     this->state_var_layouts_.push_back(dl->qp_scalar);
00084     this->state_var_init_types_.push_back("scalar");
00085     this->state_var_init_values_.push_back(0.0);
00086     this->state_var_old_state_flags_.push_back(false);
00087     this->state_var_output_flags_.push_back(p->get<bool>("Output Mechanical Source", false));
00088   }
00089 }
00090 //------------------------------------------------------------------------------
00091 template<typename EvalT, typename Traits>
00092 void CreepModel<EvalT, Traits>::
00093 computeState(typename Traits::EvalData workset,
00094     std::map<std::string, Teuchos::RCP<PHX::MDField<ScalarT> > > dep_fields,
00095     std::map<std::string, Teuchos::RCP<PHX::MDField<ScalarT> > > eval_fields)
00096 {
00097   std::string cauchy_string = (*field_name_map_)["Cauchy_Stress"];
00098   std::string Fp_string     = (*field_name_map_)["Fp"];
00099   std::string eqps_string   = (*field_name_map_)["eqps"];
00100   std::string source_string = (*field_name_map_)["Mechanical_Source"];
00101   std::string F_string      = (*field_name_map_)["F"];
00102   std::string J_string      = (*field_name_map_)["J"];
00103 
00104   // extract dependent MDFields
00105   PHX::MDField<ScalarT> def_grad         = *dep_fields[F_string];
00106   PHX::MDField<ScalarT> J                = *dep_fields[J_string];
00107   PHX::MDField<ScalarT> poissons_ratio   = *dep_fields["Poissons Ratio"];
00108   PHX::MDField<ScalarT> elastic_modulus  = *dep_fields["Elastic Modulus"];
00109   PHX::MDField<ScalarT> yieldStrength    = *dep_fields["Yield Strength"];
00110   PHX::MDField<ScalarT> hardeningModulus = *dep_fields["Hardening Modulus"];
00111   PHX::MDField<ScalarT> delta_time       = *dep_fields["Delta Time"];
00112 
00113   // extract evaluated MDFields
00114   PHX::MDField<ScalarT> stress = *eval_fields[cauchy_string];
00115   PHX::MDField<ScalarT> Fp     = *eval_fields[Fp_string];
00116   PHX::MDField<ScalarT> eqps   = *eval_fields[eqps_string];
00117   PHX::MDField<ScalarT> source;
00118   if (have_temperature_) {
00119     source = *eval_fields[source_string];
00120   }
00121 
00122   // get State Variables
00123   Albany::MDArray Fpold = (*workset.stateArrayPtr)[Fp_string + "_old"];
00124   Albany::MDArray eqpsold = (*workset.stateArrayPtr)[eqps_string + "_old"];
00125 
00126   ScalarT kappa, mu, mubar, K, Y;
00127   ScalarT Jm23, trace, p, dgam, a0, a1;
00128   ScalarT sq23(std::sqrt(2. / 3.));
00129 
00130   Intrepid::Tensor<ScalarT> F(num_dims_), be(num_dims_), s(num_dims_), sigma(
00131       num_dims_);
00132   Intrepid::Tensor<ScalarT> N(num_dims_), A(num_dims_), expA(num_dims_), Fpnew(
00133       num_dims_);
00134   Intrepid::Tensor<ScalarT> I(Intrepid::eye<ScalarT>(num_dims_));
00135   Intrepid::Tensor<ScalarT> Fpn(num_dims_), Fpinv(num_dims_), Cpinv(num_dims_);
00136 
00137   
00138   for (std::size_t cell(0); cell < workset.numCells; ++cell) {
00139     for (std::size_t pt(0); pt < num_pts_; ++pt) {
00140       kappa = elastic_modulus(cell, pt)
00141           / (3. * (1. - 2. * poissons_ratio(cell, pt)));
00142       mu = elastic_modulus(cell, pt) / (2. * (1. + poissons_ratio(cell, pt)));
00143       K = hardeningModulus(cell, pt);
00144       Y = yieldStrength(cell, pt);
00145       Jm23 = std::pow(J(cell, pt), -2. / 3.);
00146 
00147       // fill local tensors
00148       F.fill(&def_grad(cell, pt, 0, 0));
00149       for (std::size_t i(0); i < num_dims_; ++i) {
00150         for (std::size_t j(0); j < num_dims_; ++j) {
00151           Fpn(i, j) = ScalarT(Fpold(cell, pt, i, j));
00152         }
00153       }
00154 
00155       // compute trial state
00156       Fpinv = Intrepid::inverse(Fpn);
00157       Cpinv = Fpinv * Intrepid::transpose(Fpinv);
00158       be = Jm23 * F * Cpinv * Intrepid::transpose(F);
00159 
00160       a0 = Intrepid::norm(Intrepid::dev(be));
00161       a1 = Intrepid::trace(be); 
00162 
00163       s = mu * Intrepid::dev(be);
00164       mubar = Intrepid::trace(be) * mu / (num_dims_);
00165 
00166       // check yield condition
00167       if (a0 > 1E-12) {
00168         // return mapping algorithm
00169         bool converged = false;
00170         ScalarT alpha = 0.0;
00171         ScalarT res = 0.0;
00172         int count = 0;
00173         dgam = 0.0;
00174 
00175         LocalNonlinearSolver<EvalT, Traits> solver;
00176 
00177         std::vector<ScalarT> F(1);
00178         std::vector<ScalarT> dFdX(1);
00179         std::vector<ScalarT> X(1);
00180 
00181         X[0] = creep_initial_guess;
00182   F[0] =
00183     std::pow(X[0], 2./K) 
00184     - std::pow(Y, 2./K) * std::pow(mu, 2.) * std::pow(delta_time(0), 2./K)
00185     * ( std::pow(a0, 2.) + 4./9. * std::pow(X[0], 2.) * std::pow(a1, 2.)
00186         - 4./3. * X[0] * a0 * a1 
00187         ) ;
00188 
00189   dFdX[0] =
00190     2./K * std::pow(X[0], (2./K - 1.)) 
00191     - std::pow(Y, 2./K) * std::pow(mu, 2.) * std::pow(delta_time(0), 2./K)
00192     * (8./9. * X[0] * std::pow(a1, 2.) - 4./3. * a0 * a1);
00193 
00194         while (!converged && count < 30)
00195         {
00196           count++;
00197           solver.solve(dFdX, X, F);
00198           alpha = eqpsold(cell, pt) + sq23 * X[0];
00199 
00200     F[0] =
00201       std::pow(X[0], 2./K) 
00202       - std::pow(Y, 2./K) * std::pow(mu, 2.) 
00203       * std::pow(delta_time(0), 2./K)
00204       * ( std::pow(a0, 2.) + 4./9. * std::pow(X[0], 2.) * std::pow(a1, 2.)
00205     - 4./3. * X[0] * a0 * a1 
00206     ) ;
00207 
00208     dFdX[0] =
00209       2./K * std::pow(X[0], (2./K - 1.)) 
00210       - std::pow(Y, 2./K) * std::pow(mu, 2.) 
00211       * std::pow(delta_time(0), 2./K)
00212       * (8./9. * X[0] * std::pow(a1, 2.) - 4./3. * a0 * a1);
00213     
00214           res = std::abs(F[0]);
00215           if (res < 1.e-11 )
00216             converged = true;
00217 
00218           TEUCHOS_TEST_FOR_EXCEPTION(count > 30, std::runtime_error,
00219               std::endl <<
00220               "Error in return mapping, count = " <<
00221               count <<
00222               "\nres = " << res <<
00223               "\ng = " << F[0] <<
00224               "\ndg = " << dFdX[0] <<
00225               "\nalpha = " << alpha << std::endl);
00226         }
00227         solver.computeFadInfo(dFdX, X, F);
00228         dgam = X[0];
00229 
00230         // plastic direction
00231   N =  s / Intrepid::norm(s);
00232 
00233         // update s
00234         s -= 2 * mubar * dgam * N;
00235 
00236         // update eqps
00237         eqps(cell, pt) = alpha;
00238 
00239         // mechanical source
00240         if (have_temperature_ && delta_time(0) > 0) {
00241           source(cell, pt) = (sq23 * dgam / delta_time(0)
00242             * (Y + temperature_(cell,pt))) / (density_ * heat_capacity_);
00243         }
00244 
00245         // exponential map to get Fpnew
00246         A = dgam * N;
00247         expA = Intrepid::exp(A);
00248         Fpnew = expA * Fpn;
00249         for (std::size_t i(0); i < num_dims_; ++i) {
00250           for (std::size_t j(0); j < num_dims_; ++j) {
00251             Fp(cell, pt, i, j) = Fpnew(i, j);
00252           }
00253         }
00254       } else {
00255         std::cout << "hit alternate condition" << std::endl;
00256         eqps(cell, pt) = eqpsold(cell, pt);
00257         if (have_temperature_) source(cell, pt) = 0.0;
00258         for (std::size_t i(0); i < num_dims_; ++i) {
00259           for (std::size_t j(0); j < num_dims_; ++j) {
00260             Fp(cell, pt, i, j) = Fpn(i, j);
00261           }
00262         }
00263       }
00264 
00265       // compute pressure
00266       p = 0.5 * kappa * (J(cell, pt) - 1. / (J(cell, pt)));
00267 
00268       // compute stress
00269       sigma = p * I + s / J(cell, pt);
00270       for (std::size_t i(0); i < num_dims_; ++i) {
00271         for (std::size_t j(0); j < num_dims_; ++j) {
00272           stress(cell, pt, i, j) = sigma(i, j);
00273         }
00274       }
00275     }
00276   }
00277 
00278   if (have_temperature_) {
00279     for (std::size_t cell(0); cell < workset.numCells; ++cell) {
00280       for (std::size_t pt(0); pt < num_pts_; ++pt) {
00281         F.fill(&def_grad(cell,pt,0,0));
00282         ScalarT J = Intrepid::det(F);
00283         sigma.fill(&stress(cell,pt,0,0));
00284         sigma -= 3.0 * expansion_coeff_ * (1.0 + 1.0 / (J*J))
00285           * (temperature_(cell,pt) - ref_temperature_) * I;
00286         for (std::size_t i = 0; i < num_dims_; ++i) {
00287           for (std::size_t j = 0; j < num_dims_; ++j) {
00288             stress(cell, pt, i, j) = sigma(i, j);
00289           }
00290         }
00291       }
00292     }
00293   }
00294 
00295 }
00296 //------------------------------------------------------------------------------
00297 }
00298 

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