00001
00002
00003
00004
00005
00006
00007 #include "Teuchos_TestForException.hpp"
00008 #include "Phalanx_DataLayout.hpp"
00009 #include "Albany_Utils.hpp"
00010
00011
00012 #define PRINT_OUTPUT
00013
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
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
00047
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
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
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
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
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"];
00091 std::string source_string = (*field_name_map_)["Mechanical_Source"];
00092
00093
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
00101
00102
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
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
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
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
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
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
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
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
00192 #endif
00193
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
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) {
00208
00209 L.fill(Intrepid::ZEROS);
00210 for (std::size_t s(0); s < num_slip_; ++s) {
00211 P = slip_systems_[s].projector_;
00212
00213 tau = Intrepid::dotdot(P,S);
00214 int sign = tau < 0 ? -1 : 1;
00215
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
00227 expL = Intrepid::exp(L);
00228 Fp_temp = expL * Fp;
00229 Fp = Fp_temp;
00230
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
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