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

CrystalPlasticityModel_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 "Teuchos_TestForException.hpp"
00008 #include "Phalanx_DataLayout.hpp"
00009 #include "Albany_Utils.hpp"
00010 
00011 //#define  PRINT_DEBUG
00012 #define  PRINT_OUTPUT
00013 //#define  DECOUPLE
00014 #include <typeinfo>
00015 #include <Sacado_Traits.hpp>
00016 namespace LCM
00017 {
00018 
00019 //------------------------------------------------------------------------------
00020 template<typename EvalT, typename Traits>
00021 CrystalPlasticityModel<EvalT, Traits>::
00022 CrystalPlasticityModel(Teuchos::ParameterList* p,
00023     const Teuchos::RCP<Albany::Layouts>& dl) :
00024     LCM::ConstitutiveModel<EvalT, Traits>(p, dl),
00025     num_slip_(p->get<int>("Number of Slip Systems", 0))
00026 {
00027   slip_systems_.resize(num_slip_);
00028 #ifdef PRINT_DEBUG
00029   std::cout << ">>> in cp constructor\n";
00030   std::cout << ">>> parameter list:\n" << *p << std::endl;
00031 #endif
00032   Teuchos::ParameterList e_list = p->sublist("Crystal Elasticity");
00033   // assuming cubic symmetry
00034   c11_ = e_list.get<RealType>("C11");
00035   c12_ = e_list.get<RealType>("C12");
00036   c44_ = e_list.get<RealType>("C44");
00037   Intrepid::Tensor4<RealType> C(num_dims_);
00038   C.fill(Intrepid::ZEROS);
00039   for (int i = 0; i < num_dims_; ++i) {
00040     C(i,i,i,i) = c11_;
00041     for (int j = i+1; j < num_dims_; ++j) {
00042       C(i,i,j,j) = C(j,j,i,i) = c12_;
00043       C(i,j,i,j) = C(j,i,j,i) = c44_;
00044     }
00045   }
00046 // NOTE check if basis is given else default
00047 // NOTE default to coordinate axes and also construct 3rd direction if only 2 given
00048   orientation_.set_dimension(num_dims_);
00049   for (int i = 0; i < num_dims_; ++i) {
00050     std::vector<RealType> b_temp = e_list.get<Teuchos::Array<RealType> >(Albany::strint("Basis Vector", i+1)).toVector();
00051     RealType norm = 0.;
00052     for (int j = 0; j < num_dims_; ++j) {
00053       norm += b_temp[j]*b_temp[j];
00054     }
00055 // NOTE check zero, rh system
00056     norm = 1./std::sqrt(norm);
00057     for (int j = 0; j < num_dims_; ++j) {
00058       orientation_(i,j) = b_temp[j]*norm;
00059     }
00060   }
00061   // rotate elastic tensor and slip systems to match given orientation
00062   C_ = Intrepid::kronecker(orientation_,C);
00063   for (int num_ss; num_ss < num_slip_; ++num_ss) {
00064     Teuchos::ParameterList ss_list = p->sublist(Albany::strint("Slip System", num_ss+1));
00065 
00066     std::vector<RealType> s_temp = ss_list.get<Teuchos::Array<RealType> >("Slip Direction").toVector();
00067     slip_systems_[num_ss].s_ = orientation_*(Intrepid::Vector<RealType>(num_dims_, &s_temp[0]));
00068 
00069     std::vector<RealType> n_temp = ss_list.get<Teuchos::Array<RealType> >("Slip Normal").toVector();
00070     slip_systems_[num_ss].n_ = orientation_*(Intrepid::Vector<RealType>(num_dims_, &n_temp[0]));
00071 
00072     slip_systems_[num_ss].projector_ = Intrepid::dyad(slip_systems_[num_ss].s_, slip_systems_[num_ss].n_);
00073 
00074     slip_systems_[num_ss].tau_critical_ = ss_list.get<RealType>("Tau Critical");
00075     slip_systems_[num_ss].gamma_dot_0_ = ss_list.get<RealType>("Gamma Dot");
00076     slip_systems_[num_ss].gamma_exp_ = ss_list.get<RealType>("Gamma Exponent");
00077   }
00078 #ifdef PRINT_DEBUG
00079   std::cout << "<<< done with parameter list\n";
00080 #endif
00081 
00082   // define the dependent fields
00083   this->dep_field_map_.insert(std::make_pair("F", dl->qp_tensor));
00084   this->dep_field_map_.insert(std::make_pair("J", dl->qp_scalar));
00085   this->dep_field_map_.insert(std::make_pair("Delta Time", dl->workset_scalar));
00086 
00087   // retrive appropriate field name strings (ref to problems/FieldNameMap)
00088   std::string cauchy_string = (*field_name_map_)["Cauchy_Stress"];
00089   std::string Fp_string = (*field_name_map_)["Fp"];
00090   std::string L_string = (*field_name_map_)["Velocity_Gradient"]; // NOTE does not work
00091   std::string source_string = (*field_name_map_)["Mechanical_Source"];
00092 
00093   // define the evaluated fields
00094   this->eval_field_map_.insert(std::make_pair(cauchy_string, dl->qp_tensor));
00095   this->eval_field_map_.insert(std::make_pair(Fp_string, dl->qp_tensor));
00096   this->eval_field_map_.insert(std::make_pair(L_string, dl->qp_tensor));
00097   this->eval_field_map_.insert(std::make_pair(source_string, dl->qp_scalar));
00098   this->eval_field_map_.insert(std::make_pair("Time", dl->workset_scalar));
00099 
00100   // define the state variables
00101   //
00102   // stress
00103   this->num_state_variables_++;
00104   this->state_var_names_.push_back(cauchy_string);
00105   this->state_var_layouts_.push_back(dl->qp_tensor);
00106   this->state_var_init_types_.push_back("scalar");
00107   this->state_var_init_values_.push_back(0.0);
00108   this->state_var_old_state_flags_.push_back(false);
00109   this->state_var_output_flags_.push_back(true);
00110   //
00111   // Fp
00112   this->num_state_variables_++;
00113   this->state_var_names_.push_back(Fp_string);
00114   this->state_var_layouts_.push_back(dl->qp_tensor);
00115   this->state_var_init_types_.push_back("identity");
00116   this->state_var_init_values_.push_back(0.0);
00117   this->state_var_old_state_flags_.push_back(true);
00118   this->state_var_output_flags_.push_back(true);
00119   //
00120   // L
00121   this->num_state_variables_++;
00122   this->state_var_names_.push_back(L_string);
00123   this->state_var_layouts_.push_back(dl->qp_tensor);
00124   this->state_var_init_types_.push_back("identity");
00125   this->state_var_init_values_.push_back(0.0);
00126   this->state_var_old_state_flags_.push_back(true);
00127   this->state_var_output_flags_.push_back(true);
00128   //
00129   // mechanical source
00130   this->num_state_variables_++;
00131   this->state_var_names_.push_back(source_string);
00132   this->state_var_layouts_.push_back(dl->qp_scalar);
00133   this->state_var_init_types_.push_back("scalar");
00134   this->state_var_init_values_.push_back(0.0);
00135   this->state_var_old_state_flags_.push_back(false);
00136   this->state_var_output_flags_.push_back(true);
00137 
00138 #ifdef PRINT_DEBUG
00139   std::cout << "<<< done in cp constructor\n";
00140 #endif
00141 }
00142 //------------------------------------------------------------------------------
00143 template<typename EvalT, typename Traits>
00144 void CrystalPlasticityModel<EvalT, Traits>::
00145 computeState(typename Traits::EvalData workset,
00146     std::map<std::string, Teuchos::RCP<PHX::MDField<ScalarT> > > dep_fields,
00147     std::map<std::string, Teuchos::RCP<PHX::MDField<ScalarT> > > eval_fields)
00148 {
00149 #ifdef PRINT_DEBUG
00150   std::cout << ">>> in cp compute state\n";
00151 #endif
00152   // extract dependent MDFields
00153   PHX::MDField<ScalarT> def_grad = *dep_fields["F"];
00154   PHX::MDField<ScalarT> J = *dep_fields["J"];
00155   PHX::MDField<ScalarT> delta_time = *dep_fields["Delta Time"];
00156 
00157   // retrive appropriate field name strings
00158   std::string cauchy_string = (*field_name_map_)["Cauchy_Stress"];
00159   std::string Fp_string = (*field_name_map_)["Fp"];
00160   std::string L_string = (*field_name_map_)["Velocity_Gradient"];
00161   std::string source_string = (*field_name_map_)["Mechanical_Source"];
00162 
00163   // extract evaluated MDFields
00164   PHX::MDField<ScalarT> stress = *eval_fields[cauchy_string];
00165   PHX::MDField<ScalarT> plastic_deformation = *eval_fields[Fp_string];
00166   PHX::MDField<ScalarT> velocity_gradient = *eval_fields[L_string];
00167   PHX::MDField<ScalarT> source = *eval_fields[source_string];
00168   PHX::MDField<ScalarT> time = *eval_fields["Time"];
00169 
00170   // get state variables
00171   Albany::MDArray previous_plastic_deformation = (*workset.stateArrayPtr)[Fp_string + "_old"];
00172 
00173   ScalarT tau, dgamma;
00174   ScalarT g0, tauC, m;
00175   ScalarT dt = delta_time(0);
00176   ScalarT tcurrent = time(0);
00177   Intrepid::Tensor<ScalarT> Fp_temp(num_dims_),Fpinv(num_dims_);
00178   Intrepid::Tensor<ScalarT> F(num_dims_), Fp(num_dims_);
00179   Intrepid::Tensor<ScalarT> sigma(num_dims_), S(num_dims_);
00180   Intrepid::Tensor<ScalarT> L(num_dims_), expL(num_dims_);
00181   Intrepid::Tensor<RealType> P(num_dims_);
00182   I_=Intrepid::eye<RealType>(num_dims_);
00183 
00184 #ifdef PRINT_OUTPUT
00185   std::ofstream out("output.dat", std::fstream::app);
00186 #endif
00187 
00188   for (std::size_t cell(0); cell < workset.numCells; ++cell) {
00189     for (std::size_t pt(0); pt < num_pts_; ++pt) {
00190 #ifdef PRINT_OUTPUT
00191 //    std::cout << ">>> cell " << cell << " point " << pt << " <<<\n";
00192 #endif
00193       // fill local tensors
00194       F.fill(&def_grad(cell, pt, 0, 0));
00195       for (std::size_t i(0); i < num_dims_; ++i) {
00196         for (std::size_t j(0); j < num_dims_; ++j) {
00197           Fp(i, j) = ScalarT(previous_plastic_deformation(cell, pt, i, j));
00198         }
00199       }
00200 
00201       // compute stress 
00202       computeStress(F,Fp,sigma,S);
00203 #ifdef PRINT_OUTPUT
00204       double dgammas[24];
00205       double taus[24];
00206 #endif
00207       if (num_slip_ >0) { // crystal plasticity
00208         // compute velocity gradient
00209         L.fill(Intrepid::ZEROS);
00210         for (std::size_t s(0); s < num_slip_; ++s) {
00211           P  = slip_systems_[s].projector_; 
00212           // compute resolved shear stresses
00213           tau = Intrepid::dotdot(P,S);
00214           int sign = tau < 0 ? -1 : 1;
00215           // compute  dgammas
00216           g0   = slip_systems_[s].gamma_dot_0_;
00217           tauC = slip_systems_[s].tau_critical_;
00218           m    = slip_systems_[s].gamma_exp_;
00219           dgamma = dt*g0*std::fabs(std::pow(tau/tauC,m))*sign;
00220           L += (dgamma* P);
00221 #ifdef PRINT_OUTPUT
00222           dgammas[s] = Sacado::ScalarValue<ScalarT>::eval(dgamma);
00223           taus[s] = Sacado::ScalarValue<ScalarT>::eval(tau);
00224 #endif
00225         }
00226         // update plastic deformation gradient
00227         expL = Intrepid::exp(L);
00228         Fp_temp = expL * Fp;
00229         Fp = Fp_temp;
00230         // recompute stress
00231         computeStress(F,Fp,sigma,S);
00232       }
00233       source(cell, pt) = 0.0;
00234       for (std::size_t i(0); i < num_dims_; ++i) {
00235         for (std::size_t j(0); j < num_dims_; ++j) {
00236           plastic_deformation(cell, pt, i, j) = Fp(i, j);
00237           stress(cell, pt, i, j) = sigma(i, j);
00238           velocity_gradient(cell, pt, i, j) = L(i, j);
00239         }
00240       }
00241 #ifdef PRINT_OUTPUT
00242       if (cell == 0 && pt == 0) {
00243       out << std::setprecision(12) << Sacado::ScalarValue<ScalarT>::eval(tcurrent) << " ";
00244       for (std::size_t i(0); i < num_dims_; ++i) {
00245         for (std::size_t j(0); j < num_dims_; ++j) {
00246           out << std::setprecision(12) <<  Sacado::ScalarValue<ScalarT>::eval(F(i,j)) << " ";
00247         }
00248       }
00249       for (std::size_t i(0); i < num_dims_; ++i) {
00250         for (std::size_t j(0); j < num_dims_; ++j) {
00251           out << std::setprecision(12) << Sacado::ScalarValue<ScalarT>::eval(Fp(i,j)) << " ";
00252         }
00253       }
00254       for (std::size_t i(0); i < num_dims_; ++i) {
00255         for (std::size_t j(0); j < num_dims_; ++j) {
00256           out << std::setprecision(12) <<  Sacado::ScalarValue<ScalarT>::eval(sigma(i,j)) << " ";
00257         }
00258       }
00259       for (std::size_t i(0); i < num_dims_; ++i) {
00260         for (std::size_t j(0); j < num_dims_; ++j) {
00261           out << std::setprecision(12) <<  Sacado::ScalarValue<ScalarT>::eval(L(i,j)) << " ";
00262         }
00263       }
00264       for (std::size_t s(0); s < num_slip_; ++s) {
00265         out << std::setprecision(12) <<  dgammas[s] << " ";
00266       }
00267       for (std::size_t s(0); s < num_slip_; ++s) {
00268         out << std::setprecision(12) <<  taus[s] << " ";
00269       }
00270       out << "\n";
00271       }
00272 #endif
00273     }
00274   }
00275 #ifdef PRINT_DEBUG
00276   std::cout << "<<< done in cp compute state\n" << std::flush;
00277 #endif
00278 }
00279 //------------------------------------------------------------------------------
00280 template<typename EvalT, typename Traits>
00281 void CrystalPlasticityModel<EvalT, Traits>::
00282 computeStress(Intrepid::Tensor<ScalarT> const & F,
00283               Intrepid::Tensor<ScalarT> const & Fp,
00284               Intrepid::Tensor<ScalarT>       & sigma, 
00285               Intrepid::Tensor<ScalarT>       & S) 
00286 
00287 {
00288   // Saint Venant–Kirchhoff model
00289   Fpinv_ = Intrepid::inverse(Fp);
00290 #ifdef DECOUPLE
00291   std::cout << "ELASTIC STRESS ONLY\n";
00292   Fe_ = F;
00293 #else
00294   Fe_ = F * Fpinv_;
00295 #endif
00296   E_ = 0.5*( Intrepid::transpose(Fe_) * Fe_ - I_);
00297   S = Intrepid::dotdot(C_,E_);
00298   sigma = (1.0 / Intrepid::det(F) ) * F* S * Intrepid::transpose(F);
00299 }
00300 //------------------------------------------------------------------------------
00301 }
00302 

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