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

NeohookeanModel_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 namespace LCM
00012 {
00013 
00014 //----------------------------------------------------------------------------
00015 template<typename EvalT, typename Traits>
00016 NeohookeanModel<EvalT, Traits>::
00017 NeohookeanModel(Teuchos::ParameterList* p,
00018                 const Teuchos::RCP<Albany::Layouts>& dl) :
00019   LCM::ConstitutiveModel<EvalT, Traits>(p, dl)
00020 {
00021   std::string F_string = (*field_name_map_)["F"];
00022   std::string J_string = (*field_name_map_)["J"];
00023   std::string cauchy = (*field_name_map_)["Cauchy_Stress"];
00024 
00025   // define the dependent fields
00026   this->dep_field_map_.insert(std::make_pair(F_string, dl->qp_tensor));
00027   this->dep_field_map_.insert(std::make_pair(J_string, dl->qp_scalar));
00028   this->dep_field_map_.insert(std::make_pair("Poissons Ratio", dl->qp_scalar));
00029   this->dep_field_map_.insert(std::make_pair("Elastic Modulus", dl->qp_scalar));
00030 
00031   // define the evaluated fields
00032   this->eval_field_map_.insert(std::make_pair(cauchy, dl->qp_tensor));
00033   this->eval_field_map_.insert(std::make_pair("Energy", dl->qp_scalar));
00034   this->eval_field_map_.insert(
00035       std::make_pair("Material Tangent", dl->qp_tensor4));
00036 
00037   // define the state variables
00038   this->num_state_variables_++;
00039   this->state_var_names_.push_back(cauchy);
00040   this->state_var_layouts_.push_back(dl->qp_tensor);
00041   this->state_var_init_types_.push_back("scalar");
00042   this->state_var_init_values_.push_back(0.0);
00043   this->state_var_old_state_flags_.push_back(false);
00044   this->state_var_output_flags_.push_back(p->get<bool>("Output Cauchy Stress", false));
00045 }
00046 //----------------------------------------------------------------------------
00047 template<typename EvalT, typename Traits>
00048 void NeohookeanModel<EvalT, Traits>::
00049 computeState(typename Traits::EvalData workset,
00050     std::map<std::string, Teuchos::RCP<PHX::MDField<ScalarT> > > dep_fields,
00051     std::map<std::string, Teuchos::RCP<PHX::MDField<ScalarT> > > eval_fields)
00052 {
00053   std::string F_string = (*field_name_map_)["F"];
00054   std::string J_string = (*field_name_map_)["J"];
00055   std::string cauchy = (*field_name_map_)["Cauchy_Stress"];
00056 
00057   // extract dependent MDFields
00058   PHX::MDField<ScalarT> def_grad = *dep_fields[F_string];
00059   PHX::MDField<ScalarT> J = *dep_fields[J_string];
00060   PHX::MDField<ScalarT> poissons_ratio = *dep_fields["Poissons Ratio"];
00061   PHX::MDField<ScalarT> elastic_modulus = *dep_fields["Elastic Modulus"];
00062   // extract evaluated MDFields
00063   PHX::MDField<ScalarT> stress = *eval_fields[cauchy];
00064   PHX::MDField<ScalarT> energy = *eval_fields["Energy"];
00065   PHX::MDField<ScalarT> tangent = *eval_fields["Material Tangent"];
00066   ScalarT kappa;
00067   ScalarT mu, mubar;
00068   ScalarT Jm53, Jm23;
00069   ScalarT smag;
00070 
00071   Intrepid::Tensor<ScalarT> F(num_dims_), b(num_dims_), sigma(num_dims_);
00072   Intrepid::Tensor<ScalarT> I(Intrepid::eye<ScalarT>(num_dims_));
00073   Intrepid::Tensor<ScalarT> s(num_dims_), n(num_dims_);
00074 
00075   Intrepid::Tensor4<ScalarT> dsigmadb;
00076   Intrepid::Tensor4<ScalarT> I1(Intrepid::identity_1<ScalarT>(num_dims_));
00077   Intrepid::Tensor4<ScalarT> I3(Intrepid::identity_3<ScalarT>(num_dims_));
00078 
00079   for (std::size_t cell(0); cell < workset.numCells; ++cell) {
00080     for (std::size_t pt(0); pt < num_pts_; ++pt) {
00081       kappa =
00082           elastic_modulus(cell, pt)
00083               / (3. * (1. - 2. * poissons_ratio(cell, pt)));
00084       mu =
00085           elastic_modulus(cell, pt) / (2. * (1. + poissons_ratio(cell, pt)));
00086       Jm53 = std::pow(J(cell, pt), -5. / 3.);
00087       Jm23 = Jm53 * J(cell, pt);
00088 
00089       F.fill(&def_grad(cell, pt, 0, 0));
00090       b = F * transpose(F);
00091       mubar = (1.0 / 3.0) * mu * Jm23 * Intrepid::trace(b);
00092 
00093       sigma = 0.5 * kappa * (J(cell, pt) - 1. / J(cell, pt)) * I
00094           + mu * Jm53 * Intrepid::dev(b);
00095 
00096       for (std::size_t i = 0; i < num_dims_; ++i) {
00097         for (std::size_t j = 0; j < num_dims_; ++j) {
00098           stress(cell, pt, i, j) = sigma(i, j);
00099         }
00100       }
00101 
00102       if (compute_energy_) { // compute energy
00103         energy(cell, pt) =
00104             0.5 * kappa
00105                 * (0.5 * (J(cell, pt) * J(cell, pt) - 1.0)
00106                     - std::log(J(cell, pt)))
00107                 + 0.5 * mu * (Jm23 * Intrepid::trace(b) - 3.0);
00108       }
00109 
00110       if (compute_tangent_) { // compute tangent
00111 
00112         s = Intrepid::dev(sigma);
00113         smag = Intrepid::norm(s);
00114         n = s / smag;
00115 
00116         dsigmadb =
00117             kappa * J(cell, pt) * J(cell, pt) * I3
00118                 - kappa * (J(cell, pt) * J(cell, pt) - 1.0) * I1
00119                 + 2.0 * mubar * (I1 - (1.0 / 3.0) * I3)
00120                 - 2.0 / 3.0 * smag
00121                     * (Intrepid::tensor(n, I) + Intrepid::tensor(I, n));
00122 
00123         for (std::size_t i = 0; i < num_dims_; ++i) {
00124           for (std::size_t j = 0; j < num_dims_; ++j) {
00125             for (std::size_t k = 0; k < num_dims_; ++k) {
00126               for (std::size_t l = 0; l < num_dims_; ++l) {
00127                 tangent(cell, pt, i, j, k, l) = dsigmadb(i, j, k, l);
00128               }
00129             }
00130           }
00131         }
00132       }
00133     }
00134   }
00135 
00136   if (have_temperature_) {
00137     for (std::size_t cell(0); cell < workset.numCells; ++cell) {
00138       for (std::size_t pt(0); pt < num_pts_; ++pt) {
00139         F.fill(&def_grad(cell,pt,0,0));
00140         ScalarT J = Intrepid::det(F);
00141         sigma.fill(&stress(cell,pt,0,0));
00142         sigma -= 3.0 * expansion_coeff_ * (1.0 + 1.0 / (J*J))
00143           * (temperature_(cell,pt) - ref_temperature_) * I;
00144 
00145         for (std::size_t i = 0; i < num_dims_; ++i) {
00146           for (std::size_t j = 0; j < num_dims_; ++j) {
00147             stress(cell, pt, i, j) = sigma(i, j);
00148           }
00149         }
00150       }
00151     }
00152   }
00153 }
00154 //----------------------------------------------------------------------------
00155 }
00156 

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