00001
00002
00003
00004
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
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
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
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
00051
00052
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
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
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
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
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
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
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
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
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
00167 if (a0 > 1E-12) {
00168
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
00231 N = s / Intrepid::norm(s);
00232
00233
00234 s -= 2 * mubar * dgam * N;
00235
00236
00237 eqps(cell, pt) = alpha;
00238
00239
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
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
00266 p = 0.5 * kappa * (J(cell, pt) - 1. / (J(cell, pt)));
00267
00268
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