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

ElasticDamageModel_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 #include <typeinfo>
00011 
00012 namespace LCM
00013 {
00014 
00015 //------------------------------------------------------------------------------
00016 template<typename EvalT, typename Traits>
00017 ElasticDamageModel<EvalT, Traits>::
00018 ElasticDamageModel(Teuchos::ParameterList* p,
00019     const Teuchos::RCP<Albany::Layouts>& dl) :
00020     LCM::ConstitutiveModel<EvalT, Traits>(p, dl),
00021         max_damage_(p->get<RealType>("Maximum damage", 1.0)),
00022         saturation_(p->get<RealType>("Damage saturation", 0.0))
00023 {
00024   // define the dependent fields
00025   this->dep_field_map_.insert(std::make_pair("Strain", dl->qp_tensor));
00026   this->dep_field_map_.insert(std::make_pair("Poissons Ratio", dl->qp_scalar));
00027   this->dep_field_map_.insert(std::make_pair("Elastic Modulus", dl->qp_scalar));
00028 
00029   // retrieve appropriate field name strings
00030   std::string cauchy_string = (*field_name_map_)["Cauchy_Stress"];
00031   std::string energy_string = (*field_name_map_)["Matrix_Energy"];
00032   std::string damage_string = (*field_name_map_)["Matrix_Damage"];
00033 
00034   // define the evaluated fields
00035   this->eval_field_map_.insert(std::make_pair(cauchy_string, dl->qp_tensor));
00036   this->eval_field_map_.insert(std::make_pair(energy_string, dl->qp_scalar));
00037   this->eval_field_map_.insert(std::make_pair(damage_string, dl->qp_scalar));
00038   this->eval_field_map_.insert(
00039       std::make_pair("Material Tangent", dl->qp_tensor4));
00040 
00041   // define the state variables
00042   //
00043   // stress
00044   this->num_state_variables_++;
00045   this->state_var_names_.push_back(cauchy_string);
00046   this->state_var_layouts_.push_back(dl->qp_tensor);
00047   this->state_var_init_types_.push_back("scalar");
00048   this->state_var_init_values_.push_back(0.0);
00049   this->state_var_old_state_flags_.push_back(false);
00050   this->state_var_output_flags_.push_back(true);
00051   //
00052   // energy
00053   this->num_state_variables_++;
00054   this->state_var_names_.push_back(energy_string);
00055   this->state_var_layouts_.push_back(dl->qp_scalar);
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(true);
00059   this->state_var_output_flags_.push_back(true);
00060   //
00061   // damage
00062   this->num_state_variables_++;
00063   this->state_var_names_.push_back(damage_string);
00064   this->state_var_layouts_.push_back(dl->qp_scalar);
00065   this->state_var_init_types_.push_back("scalar");
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(true);
00069 
00070 }
00071 //------------------------------------------------------------------------------
00072 template<typename EvalT, typename Traits>
00073 void ElasticDamageModel<EvalT, Traits>::
00074 computeState(typename Traits::EvalData workset,
00075     std::map<std::string, Teuchos::RCP<PHX::MDField<ScalarT> > > dep_fields,
00076     std::map<std::string, Teuchos::RCP<PHX::MDField<ScalarT> > > eval_fields)
00077 {
00078   //bool print = false;
00079   //if (typeid(ScalarT) == typeid(RealType)) print = true;
00080   //cout.precision(15);
00081 
00082   // extract dependent MDFields
00083   PHX::MDField<ScalarT> strain = *dep_fields["Strain"];
00084   PHX::MDField<ScalarT> poissons_ratio = *dep_fields["Poissons Ratio"];
00085   PHX::MDField<ScalarT> elastic_modulus = *dep_fields["Elastic Modulus"];
00086 
00087   // retrieve appropriate field name strings
00088   std::string cauchy_string = (*field_name_map_)["Cauchy_Stress"];
00089   std::string energy_string = (*field_name_map_)["Matrix_Energy"];
00090   std::string damage_string = (*field_name_map_)["Matrix_Damage"];
00091 
00092   // extract evaluated MDFields
00093   PHX::MDField<ScalarT> stress = *eval_fields[cauchy_string];
00094   PHX::MDField<ScalarT> energy = *eval_fields[energy_string];
00095   PHX::MDField<ScalarT> damage = *eval_fields[damage_string];
00096   PHX::MDField<ScalarT> tangent = *eval_fields["Material Tangent"];
00097 
00098   // previous state
00099   Albany::MDArray energy_old =
00100       (*workset.stateArrayPtr)[energy_string + "_old"];
00101 
00102   ScalarT mu, lame;
00103   ScalarT alpha, damage_deriv;
00104 
00105   // Define some tensors for use
00106   Intrepid::Tensor<ScalarT> I(Intrepid::eye<ScalarT>(num_dims_));
00107   Intrepid::Tensor<ScalarT> epsilon(num_dims_), sigma(num_dims_);
00108 
00109   Intrepid::Tensor4<ScalarT> Ce(num_dims_);
00110   Intrepid::Tensor4<ScalarT> id4(num_dims_);
00111   Intrepid::Tensor4<ScalarT> id3(Intrepid::identity_3<ScalarT>(num_dims_));
00112 
00113   id4 = 0.5 * (Intrepid::identity_1<ScalarT>(num_dims_)
00114       + Intrepid::identity_2<ScalarT>(num_dims_));
00115 
00116   for (std::size_t cell = 0; cell < workset.numCells; ++cell) {
00117     for (std::size_t pt = 0; pt < num_pts_; ++pt) {
00118       // local parameters
00119       mu = elastic_modulus(cell, pt)
00120           / (2.0 * (1.0 + poissons_ratio(cell, pt)));
00121       lame = elastic_modulus(cell, pt) * poissons_ratio(cell, pt)
00122           / (1.0 + poissons_ratio(cell, pt))
00123           / (1.0 - 2.0 * poissons_ratio(cell, pt));
00124 
00125       // small strain tensor
00126       epsilon.fill(&strain(cell, pt, 0, 0));
00127 
00128       // undamaged elasticity tensor
00129       Ce = lame * id3 + 2.0 * mu * id4;
00130 
00131       // undamaged energy
00132       energy(cell, pt) =
00133           0.5 * Intrepid::dotdot(Intrepid::dotdot(epsilon, Ce), epsilon);
00134 
00135       // undamaged Cauchy stress
00136       sigma = Intrepid::dotdot(Ce, epsilon);
00137 
00138       // maximum thermodynamic force
00139       alpha = energy_old(cell, pt);
00140       if (energy(cell, pt) > alpha) alpha = energy(cell, pt);
00141 
00142       // damage term
00143       damage(cell, pt) = max_damage_
00144           * (1 - std::exp(-alpha / saturation_));
00145 
00146       // derivative of damage w.r.t alpha
00147       damage_deriv =
00148           max_damage_ / saturation_ * std::exp(-alpha / saturation_);
00149 
00150       // tangent for matrix considering damage
00151       Ce = (1.0 - damage(cell, pt)) * Ce
00152           - damage_deriv * Intrepid::tensor(sigma, sigma);
00153 
00154       // total Cauchy stress
00155       for (std::size_t i(0); i < num_dims_; ++i) {
00156         for (std::size_t j(0); j < num_dims_; ++j) {
00157           stress(cell, pt, i, j) =
00158               (1.0 - damage(cell, pt)) * sigma(i, j);
00159         }
00160       }
00161 
00162       // total tangent
00163       for (std::size_t i(0); i < num_dims_; ++i) {
00164         for (std::size_t j(0); j < num_dims_; ++j) {
00165           for (std::size_t k(0); k < num_dims_; ++k) {
00166             for (std::size_t l(0); l < num_dims_; ++l) {
00167 
00168               tangent(cell, pt, i, j, k, l) = Ce(i, j, k, l);
00169 
00170             }
00171           }
00172         }
00173       }
00174     } // pt
00175   } // cell
00176 }
00177 //----------------------------------------------------------------------------
00178 }

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