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

CapImplicitModel_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 #include <Intrepid_FunctionSpaceTools.hpp>
00007 #include <Intrepid_MiniTensor.h>
00008 #include <Teuchos_TestForException.hpp>
00009 #include <Phalanx_DataLayout.hpp>
00010 #include <typeinfo>
00011 
00012 #include "LocalNonlinearSolver.hpp"
00013 
00014 
00015 namespace LCM
00016 {
00017 
00018 //**********************************************************************
00019   template<typename EvalT, typename Traits>
00020   CapImplicitModel<EvalT, Traits>::
00021   CapImplicitModel(Teuchos::ParameterList* p,
00022     const Teuchos::RCP<Albany::Layouts>& dl) :
00023     LCM::ConstitutiveModel<EvalT, Traits>(p, dl),
00024     A(p->get<RealType>("A")),
00025     B(p->get<RealType>("B")),
00026     C(p->get<RealType>("C")),
00027     theta(p->get<RealType>("theta")),
00028     R(p->get<RealType>("R")),
00029     kappa0(p->get<RealType>("kappa0")),
00030     W(p->get<RealType>("W")),
00031     D1(p->get<RealType>("D1")),
00032     D2(p->get<RealType>("D2")),
00033     calpha(p->get<RealType>("calpha")),
00034     psi(p->get<RealType>("psi")),
00035     N(p->get<RealType>("N")),
00036     L(p->get<RealType>("L")),
00037     phi(p->get<RealType>("phi")),
00038     Q(p->get<RealType>("Q"))
00039   {
00040       // define the dependent fields
00041       this->dep_field_map_.insert(std::make_pair("Strain", dl->qp_tensor));
00042       this->dep_field_map_.insert(std::make_pair("Poissons Ratio", dl->qp_scalar));
00043       this->dep_field_map_.insert(std::make_pair("Elastic Modulus", dl->qp_scalar));
00044       
00045       // retrieve appropriate field name strings
00046       std::string cauchy_string = (*field_name_map_)["Cauchy_Stress"];
00047       std::string strain_string = (*field_name_map_)["Strain"];
00048       std::string backStress_string = (*field_name_map_)["Back_Stress"];
00049       std::string capParameter_string = (*field_name_map_)["Cap_Parameter"];
00050       std::string eqps_string = (*field_name_map_)["eqps"];
00051       std::string volPlasticStrain_string = (*field_name_map_)["volPlastic_Strain"];
00052       
00053       // define the evaluated fields
00054       this->eval_field_map_.insert(std::make_pair(cauchy_string, dl->qp_tensor));
00055       this->eval_field_map_.insert(std::make_pair(backStress_string, dl->qp_tensor));
00056       this->eval_field_map_.insert(std::make_pair(capParameter_string, dl->qp_scalar));
00057       this->eval_field_map_.insert(std::make_pair(eqps_string, dl->qp_scalar));
00058       this->eval_field_map_.insert(std::make_pair(volPlasticStrain_string, dl->qp_scalar));
00059       this->eval_field_map_.insert(
00060                                    std::make_pair("Material Tangent", dl->qp_tensor4));
00061       
00062       // define the state variables
00063       //
00064       // strain
00065       this->num_state_variables_++;
00066       this->state_var_names_.push_back(strain_string);
00067       this->state_var_layouts_.push_back(dl->qp_tensor);
00068       this->state_var_init_types_.push_back("scalar");
00069       this->state_var_init_values_.push_back(0.0);
00070       this->state_var_old_state_flags_.push_back(true);
00071       this->state_var_output_flags_.push_back(true);
00072       //
00073       // stress
00074       this->num_state_variables_++;
00075       this->state_var_names_.push_back(cauchy_string);
00076       this->state_var_layouts_.push_back(dl->qp_tensor);
00077       this->state_var_init_types_.push_back("scalar");
00078       this->state_var_init_values_.push_back(0.0);
00079       this->state_var_old_state_flags_.push_back(true);
00080       this->state_var_output_flags_.push_back(true);
00081       //
00082       // backStress
00083       this->num_state_variables_++;
00084       this->state_var_names_.push_back(backStress_string);
00085       this->state_var_layouts_.push_back(dl->qp_tensor);
00086       this->state_var_init_types_.push_back("scalar");
00087       this->state_var_init_values_.push_back(0.0);
00088       this->state_var_old_state_flags_.push_back(true);
00089       this->state_var_output_flags_.push_back(true);
00090       //
00091       // capParameter
00092       this->num_state_variables_++;
00093       this->state_var_names_.push_back(capParameter_string);
00094       this->state_var_layouts_.push_back(dl->qp_scalar);
00095       this->state_var_init_types_.push_back("scalar");
00096       this->state_var_init_values_.push_back(kappa0);
00097       this->state_var_old_state_flags_.push_back(true);
00098       this->state_var_output_flags_.push_back(true);
00099       //
00100       // eqps
00101       this->num_state_variables_++;
00102       this->state_var_names_.push_back(eqps_string);
00103       this->state_var_layouts_.push_back(dl->qp_scalar);
00104       this->state_var_init_types_.push_back("scalar");
00105       this->state_var_init_values_.push_back(0.0);
00106       this->state_var_old_state_flags_.push_back(true);
00107       this->state_var_output_flags_.push_back(true);
00108       //
00109       // volPlasticStrain
00110       this->num_state_variables_++;
00111       this->state_var_names_.push_back(volPlasticStrain_string);
00112       this->state_var_layouts_.push_back(dl->qp_scalar);
00113       this->state_var_init_types_.push_back("scalar");
00114       this->state_var_init_values_.push_back(0.0);
00115       this->state_var_old_state_flags_.push_back(true);
00116       this->state_var_output_flags_.push_back(true);
00117      
00118   }
00119 
00120 //**********************************************************************
00121   template<typename EvalT, typename Traits>
00122     void CapImplicitModel<EvalT, Traits>::
00123     computeState(typename Traits::EvalData workset,
00124       std::map<std::string, Teuchos::RCP<PHX::MDField<ScalarT> > > dep_fields,
00125       std::map<std::string, Teuchos::RCP<PHX::MDField<ScalarT> > > eval_fields)
00126   {
00127       
00128       // extract dependent MDFields
00129       PHX::MDField<ScalarT> strain = *dep_fields["Strain"];
00130       PHX::MDField<ScalarT> poissons_ratio = *dep_fields["Poissons Ratio"];
00131       PHX::MDField<ScalarT> elastic_modulus = *dep_fields["Elastic Modulus"];
00132       
00133       // retrieve appropriate field name strings
00134       std::string cauchy_string = (*field_name_map_)["Cauchy_Stress"];
00135       std::string strain_string = (*field_name_map_)["Strain"];
00136       std::string backStress_string = (*field_name_map_)["Back_Stress"];
00137       std::string capParameter_string = (*field_name_map_)["Cap_Parameter"];
00138       std::string eqps_string = (*field_name_map_)["eqps"];
00139       std::string volPlasticStrain_string = (*field_name_map_)["volPlastic_Strain"];
00140       
00141       // extract evaluated MDFields
00142       PHX::MDField<ScalarT> stress = *eval_fields[cauchy_string];
00143       PHX::MDField<ScalarT> backStress = *eval_fields[backStress_string];
00144       PHX::MDField<ScalarT> capParameter = *eval_fields[capParameter_string];
00145       PHX::MDField<ScalarT> eqps = *eval_fields[eqps_string];
00146       PHX::MDField<ScalarT> volPlasticStrain = *eval_fields[volPlasticStrain_string];
00147       PHX::MDField<ScalarT> tangent = *eval_fields["Material Tangent"];
00148       
00149       // get State Variables
00150       Albany::MDArray strainold = (*workset.stateArrayPtr)[strain_string + "_old"];
00151       Albany::MDArray stressold = (*workset.stateArrayPtr)[cauchy_string + "_old"];
00152       Albany::MDArray backStressold = (*workset.stateArrayPtr)[backStress_string + "_old"];
00153       Albany::MDArray capParameterold = (*workset.stateArrayPtr)[capParameter_string + "_old"];
00154       Albany::MDArray eqpsold = (*workset.stateArrayPtr)[eqps_string + "_old"];
00155       Albany::MDArray volPlasticStrainold =
00156       (*workset.stateArrayPtr)[volPlasticStrain_string + "_old"];
00157       
00158       
00159       for (std::size_t cell = 0; cell < workset.numCells; ++cell) {
00160           for (std::size_t qp = 0; qp < num_pts_; ++qp) {
00161               // local parameters
00162               ScalarT lame = elastic_modulus(cell, qp) * poissons_ratio(cell, qp)
00163               / (1.0 + poissons_ratio(cell, qp))
00164               / (1.0 - 2.0 * poissons_ratio(cell, qp));
00165               ScalarT mu = elastic_modulus(cell, qp) / 2.0
00166               / (1.0 + poissons_ratio(cell, qp));
00167               ScalarT bulkModulus = lame + (2. / 3.) * mu;
00168               
00169               // elastic matrix
00170               Intrepid::Tensor4<ScalarT> Celastic = lame
00171               * Intrepid::identity_3<ScalarT>(3)
00172               + mu
00173               * (Intrepid::identity_1<ScalarT>(3)
00174                  + Intrepid::identity_2<ScalarT>(3));
00175               
00176               // elastic compliance tangent matrix
00177               Intrepid::Tensor4<ScalarT> compliance = (1. / bulkModulus / 9.)
00178               * Intrepid::identity_3<ScalarT>(3)
00179               + (1. / mu / 2.)
00180               * (0.5
00181                  * (Intrepid::identity_1<ScalarT>(3)
00182                     + Intrepid::identity_2<ScalarT>(3))
00183                  - (1. / 3.) * Intrepid::identity_3<ScalarT>(3));
00184               
00185               // previous state
00186               Intrepid::Tensor<ScalarT>
00187               sigmaN(3, Intrepid::ZEROS),
00188               alphaN(3, Intrepid::ZEROS),
00189               strainN(3, Intrepid::ZEROS);
00190               
00191               // incremental strain tensor
00192               Intrepid::Tensor<ScalarT> depsilon(3);
00193               for (std::size_t i = 0; i < num_dims_; ++i) {
00194                   for (std::size_t j = 0; j < num_dims_; ++j) {
00195                       depsilon(i, j) = strain(cell, qp, i, j) - strainold(cell, qp, i, j);
00196                       strainN(i, j) = strainold(cell, qp, i, j);
00197                   }
00198               }
00199               
00200               // trial state
00201               Intrepid::Tensor<ScalarT> sigmaVal = Intrepid::dotdot(Celastic,
00202                                                                     depsilon);
00203               Intrepid::Tensor<ScalarT> alphaVal(3, Intrepid::ZEROS);
00204               
00205               for (std::size_t i = 0; i < num_dims_; ++i) {
00206                   for (std::size_t j = 0; j < num_dims_; ++j) {
00207                       sigmaVal(i, j) = sigmaVal(i, j) + stressold(cell, qp, i, j);
00208                       alphaVal(i, j) = backStressold(cell, qp, i, j);
00209                       sigmaN(i, j) = stressold(cell, qp, i, j);
00210                       alphaN(i, j) = backStressold(cell, qp, i, j);
00211                   }
00212               }
00213               
00214               ScalarT kappaVal = capParameterold(cell, qp);
00215               ScalarT dgammaVal = 0.0;
00216               
00217               // used in defining generalized hardening modulus
00218               ScalarT Htan(0.0);
00219               
00220               // define plastic strain increment, its two invariants: dev, and vol
00221               Intrepid::Tensor<ScalarT> deps_plastic(3, Intrepid::ZEROS);
00222               ScalarT deqps(0.0), devolps(0.0);
00223               
00224               // define temporary trial stress, used in computing plastic strain
00225               Intrepid::Tensor<ScalarT> sigmaTr = sigmaVal;
00226               
00227               std::vector<ScalarT> XXVal(13);
00228               
00229               // check yielding
00230               ScalarT f = compute_f(sigmaVal, alphaVal, kappaVal);
00231               XXVal = initialize(sigmaVal, alphaVal, kappaVal, dgammaVal);
00232               
00233               // local Newton loop
00234               if (f > 1.e-11) { // plastic yielding
00235                   
00236                   ScalarT normR, normR0, conv;
00237                   bool kappa_flag = false;
00238                   bool converged = false;
00239                   int iter = 0;
00240                   
00241                   std::vector<ScalarT> R(13);
00242                   std::vector<ScalarT> dRdX(13 * 13);
00243                   LocalNonlinearSolver<EvalT, Traits> solver;
00244                   
00245                   while (!converged) {
00246                       
00247                       // assemble residual vector and local Jacobian
00248                       compute_ResidJacobian(XXVal, R, dRdX, sigmaVal, alphaVal, kappaVal,
00249                                             Celastic, kappa_flag);
00250                       
00251                       normR = 0.0;
00252                       for (int i = 0; i < 13; i++)
00253                           normR += R[i] * R[i];
00254                       
00255                       normR = std::sqrt(normR);
00256                       
00257                       if (iter == 0)
00258                           normR0 = normR;
00259                       if (normR0 != 0)
00260                           conv = normR / normR0;
00261                       else
00262                           conv = normR0;
00263                       
00264                       if (conv < 1.e-11 || normR < 1.e-11)
00265                           break;
00266                       
00267                       if(iter > 20)
00268                           break;
00269                       
00270                       //TEUCHOS_TEST_FOR_EXCEPTION( iter > 20, std::runtime_error,
00271                       // std::endl << "Error in return mapping, iter = " << iter << "\nres = " << normR << "\nrelres = " << conv << std::endl);
00272                       
00273                       std::vector<ScalarT> XXValK = XXVal;
00274                       solver.solve(dRdX, XXValK, R);
00275                       
00276                       // put restrictions on kappa: only allows monotonic decreasing (cap hardening)
00277                       if (XXValK[11] > XXVal[11]) {
00278                           kappa_flag = true;
00279                       }
00280                       else {
00281                           XXVal = XXValK;
00282                           kappa_flag = false;
00283                       }
00284                       
00285                       // debugging
00286                       //XXVal = XXValK;
00287                       
00288                       iter++;
00289                   } //end local NR
00290                   
00291                   // compute sensitivity information, and pack back to X.
00292                   solver.computeFadInfo(dRdX, XXVal, R);
00293                   
00294               } // end of plasticity
00295               
00296               // update
00297               sigmaVal(0, 0) = XXVal[0];
00298               sigmaVal(0, 1) = XXVal[5];
00299               sigmaVal(0, 2) = XXVal[4];
00300               sigmaVal(1, 0) = XXVal[5];
00301               sigmaVal(1, 1) = XXVal[1];
00302               sigmaVal(1, 2) = XXVal[3];
00303               sigmaVal(2, 0) = XXVal[4];
00304               sigmaVal(2, 1) = XXVal[3];
00305               sigmaVal(2, 2) = XXVal[2];
00306               
00307               alphaVal(0, 0) = XXVal[6];
00308               alphaVal(0, 1) = XXVal[10];
00309               alphaVal(0, 2) = XXVal[9];
00310               alphaVal(1, 0) = XXVal[10];
00311               alphaVal(1, 1) = XXVal[7];
00312               alphaVal(1, 2) = XXVal[8];
00313               alphaVal(2, 0) = XXVal[9];
00314               alphaVal(2, 1) = XXVal[8];
00315               alphaVal(2, 2) = -XXVal[6] - XXVal[7];
00316               
00317               kappaVal = XXVal[11];
00318               
00319               //dgammaVal = XXVal[12];
00320               
00321               //compute plastic strain increment deps_plastic = compliance ( sigma_tr - sigma_(n+1));
00322               Intrepid::Tensor<ScalarT> dsigma = sigmaTr - sigmaVal;
00323               deps_plastic = Intrepid::dotdot(compliance, dsigma);
00324               
00325               // compute its two invariants: devolps (volumetric) and deqps (deviatoric)
00326               devolps = Intrepid::trace(deps_plastic);
00327               Intrepid::Tensor<ScalarT> dev_plastic = deps_plastic
00328               - (1.0 / 3.0) * devolps * Intrepid::identity<ScalarT>(3);
00329               //deqps = std::sqrt(2./3.) * Intrepid::norm(dev_plastic);
00330               // use altenative definition, just differ by constants
00331               deqps = std::sqrt(2) * Intrepid::norm(dev_plastic);
00332   
00333               // stress and back stress
00334               for (std::size_t i = 0; i < num_dims_; ++i) {
00335                   for (std::size_t j = 0; j < num_dims_; ++j) {
00336                       stress(cell, qp, i, j) = sigmaVal(i, j);
00337                       backStress(cell, qp, i, j) = alphaVal(i, j);
00338                   }
00339               }
00340               
00341               capParameter(cell, qp) = kappaVal;
00342               eqps(cell, qp) = eqpsold(cell, qp) + deqps;
00343               volPlasticStrain(cell, qp) = volPlasticStrainold(cell, qp) + devolps;
00344               
00345           } //loop over qps
00346           
00347       } //loop over cell
00348 
00349   } // end of evaluateFields
00350 
00351 //**********************************************************************
00352 // all local functions
00353 template<typename EvalT, typename Traits>
00354 typename CapImplicitModel<EvalT, Traits>::ScalarT
00355 //typename EvalT::ScalarT
00356 CapImplicitModel<EvalT, Traits>::compute_f(Intrepid::Tensor<ScalarT> & sigma, Intrepid::Tensor<ScalarT> & alpha, ScalarT & kappa)
00357     {
00358         
00359         Intrepid::Tensor<ScalarT> xi = sigma - alpha;
00360         
00361         ScalarT I1 = Intrepid::trace(xi), p = I1 / 3.;
00362         
00363         Intrepid::Tensor<ScalarT> s = xi - p * Intrepid::identity<ScalarT>(3);
00364         
00365         ScalarT J2 = 0.5 * Intrepid::dotdot(s, s);
00366         
00367         ScalarT J3 = Intrepid::det(s);
00368         
00369         ScalarT Gamma = 1.0;
00370         if (psi != 0 && J2 != 0)
00371             Gamma =
00372             0.5
00373             * (1. - 3. * std::sqrt(3.0) * J3 / 2. / std::pow(J2, 1.5)
00374                + (1. + 3.0 * std::sqrt(3.0) * J3 / 2. / std::pow(J2, 1.5))
00375                / psi);
00376         
00377         ScalarT Ff_I1 = A - C * std::exp(B * I1) - theta * I1;
00378         
00379         ScalarT Ff_kappa = A - C * std::exp(B * kappa) - theta * kappa;
00380         
00381         ScalarT X = kappa - R * Ff_kappa;
00382         
00383         ScalarT Fc = 1.0;
00384         
00385         if ((kappa - I1) > 0 && ((X - kappa) != 0))
00386             Fc = 1.0 - (I1 - kappa) * (I1 - kappa) / (X - kappa) / (X - kappa);
00387         
00388         return Gamma * Gamma * J2 - Fc * (Ff_I1 - N) * (Ff_I1 - N);
00389     }
00390     
00391 template<typename EvalT, typename Traits>
00392 typename CapImplicitModel<EvalT, Traits>::DFadType
00393 //typename EvalT::DFadType
00394 CapImplicitModel<EvalT, Traits>::compute_f(Intrepid::Tensor<DFadType> & sigma, Intrepid::Tensor<DFadType> & alpha, DFadType & kappa)
00395     {
00396         
00397         Intrepid::Tensor<DFadType> xi = sigma - alpha;
00398         
00399         DFadType I1 = Intrepid::trace(xi), p = I1 / 3.;
00400         
00401         Intrepid::Tensor<DFadType> s = xi - p * Intrepid::identity<DFadType>(3);
00402         
00403         DFadType J2 = 0.5 * Intrepid::dotdot(s, s);
00404         
00405         DFadType J3 = Intrepid::det(s);
00406         
00407         DFadType Gamma = 1.0;
00408         if (psi != 0 && J2 != 0)
00409             Gamma =
00410             0.5
00411             * (1. - 3.0 * std::sqrt(3.0) * J3 / 2. / std::pow(J2, 1.5)
00412                + (1. + 3.0 * std::sqrt(3.0) * J3 / 2. / std::pow(J2, 1.5))
00413                / psi);
00414         
00415         DFadType Ff_I1 = A - C * std::exp(B * I1) - theta * I1;
00416         
00417         DFadType Ff_kappa = A - C * std::exp(B * kappa) - theta * kappa;
00418         
00419         DFadType X = kappa - R * Ff_kappa;
00420         
00421         DFadType Fc = 1.0;
00422         
00423         if ((kappa - I1) > 0 && ((X - kappa) != 0))
00424             Fc = 1.0 - (I1 - kappa) * (I1 - kappa) / (X - kappa) / (X - kappa);
00425         
00426         return Gamma * Gamma * J2 - Fc * (Ff_I1 - N) * (Ff_I1 - N);
00427     }
00428     
00429 template<typename EvalT, typename Traits>
00430 typename CapImplicitModel<EvalT, Traits>::D2FadType
00431 //typename EValT::D2FadType
00432 CapImplicitModel<EvalT, Traits>::compute_g(Intrepid::Tensor<D2FadType> & sigma, Intrepid::Tensor<D2FadType> & alpha, D2FadType & kappa)
00433     {
00434         
00435         Intrepid::Tensor<D2FadType> xi = sigma - alpha;
00436         
00437         D2FadType I1 = Intrepid::trace(xi), p = I1 / 3.;
00438         
00439         Intrepid::Tensor<D2FadType> s = xi - p * Intrepid::identity<D2FadType>(3);
00440         
00441         D2FadType J2 = 0.5 * Intrepid::dotdot(s, s);
00442         
00443         D2FadType J3 = Intrepid::det(s);
00444         
00445         D2FadType Gamma = 1.0;
00446         if (psi != 0 && J2 != 0)
00447             Gamma =
00448             0.5
00449             * (1. - 3.0 * std::sqrt(3.0) * J3 / 2. / std::pow(J2, 1.5)
00450                + (1. + 3.0 * std::sqrt(3.0) * J3 / 2. / std::pow(J2, 1.5))
00451                / psi);
00452         
00453         D2FadType Ff_I1 = A - C * std::exp(L * I1) - phi * I1;
00454         
00455         D2FadType Ff_kappa = A - C * std::exp(L * kappa) - phi * kappa;
00456         
00457         D2FadType X = kappa - Q * Ff_kappa;
00458         
00459         D2FadType Fc = 1.0;
00460         
00461         if ((kappa - I1) > 0 && ((X - kappa) != 0))
00462             Fc = 1.0 - (I1 - kappa) * (I1 - kappa) / (X - kappa) / (X - kappa);
00463         
00464         return Gamma * Gamma * J2 - Fc * (Ff_I1 - N) * (Ff_I1 - N);
00465     }
00466     
00467 template<typename EvalT, typename Traits>
00468 std::vector<typename CapImplicitModel<EvalT, Traits>::ScalarT>
00469 //std::vector<typename EvalT::ScalarT>
00470 CapImplicitModel<EvalT,Traits>::initialize(Intrepid::Tensor<ScalarT> & sigmaVal, Intrepid::Tensor<ScalarT> & alphaVal, ScalarT & kappaVal, ScalarT & dgammaVal)
00471     {
00472         std::vector<ScalarT> XX(13);
00473         
00474         XX[0] = sigmaVal(0, 0);
00475         XX[1] = sigmaVal(1, 1);
00476         XX[2] = sigmaVal(2, 2);
00477         XX[3] = sigmaVal(1, 2);
00478         XX[4] = sigmaVal(0, 2);
00479         XX[5] = sigmaVal(0, 1);
00480         XX[6] = alphaVal(0, 0);
00481         XX[7] = alphaVal(1, 1);
00482         XX[8] = alphaVal(1, 2);
00483         XX[9] = alphaVal(0, 2);
00484         XX[10] = alphaVal(0, 1);
00485         XX[11] = kappaVal;
00486         XX[12] = dgammaVal;
00487         
00488         return XX;
00489     }
00490     
00491 template<typename EvalT, typename Traits>
00492 Intrepid::Tensor<typename CapImplicitModel<EvalT, Traits>::DFadType>
00493 //Intrepid::Tensor<typename EvalT::DFadType>
00494 CapImplicitModel<EvalT, Traits>::compute_dgdsigma(std::vector<DFadType> const & XX)
00495     {
00496         std::vector<D2FadType> D2XX(13);
00497         
00498         for (int i = 0; i < 13; ++i) {
00499             D2XX[i] = D2FadType(13, i, XX[i]);
00500         }
00501         
00502         Intrepid::Tensor<D2FadType> sigma(3), alpha(3);
00503         
00504         sigma(0, 0) = D2XX[0];
00505         sigma(0, 1) = D2XX[5];
00506         sigma(0, 2) = D2XX[4];
00507         sigma(1, 0) = D2XX[5];
00508         sigma(1, 1) = D2XX[1];
00509         sigma(1, 2) = D2XX[3];
00510         sigma(2, 0) = D2XX[4];
00511         sigma(2, 1) = D2XX[3];
00512         sigma(2, 2) = D2XX[2];
00513         
00514         alpha(0, 0) = D2XX[6];
00515         alpha(0, 1) = D2XX[10];
00516         alpha(0, 2) = D2XX[9];
00517         alpha(1, 0) = D2XX[10];
00518         alpha(1, 1) = D2XX[7];
00519         alpha(1, 2) = D2XX[8];
00520         alpha(2, 0) = D2XX[9];
00521         alpha(2, 1) = D2XX[8];
00522         alpha(2, 2) = -D2XX[6] - D2XX[7];
00523         
00524         D2FadType kappa = D2XX[11];
00525         
00526         D2FadType g = compute_g(sigma, alpha, kappa);
00527         
00528         Intrepid::Tensor<DFadType> dgdsigma(3);
00529         
00530         dgdsigma(0, 0) = g.dx(0);
00531         dgdsigma(0, 1) = g.dx(5);
00532         dgdsigma(0, 2) = g.dx(4);
00533         dgdsigma(1, 0) = g.dx(5);
00534         dgdsigma(1, 1) = g.dx(1);
00535         dgdsigma(1, 2) = g.dx(3);
00536         dgdsigma(2, 0) = g.dx(4);
00537         dgdsigma(2, 1) = g.dx(3);
00538         dgdsigma(2, 2) = g.dx(2);
00539         
00540         return dgdsigma;
00541     }
00542     
00543 template<typename EvalT, typename Traits>
00544 typename CapImplicitModel<EvalT, Traits>::DFadType
00545 //typename EvalT::DFadType
00546 CapImplicitModel<EvalT, Traits>::compute_Galpha(DFadType J2_alpha)
00547     {
00548         if (N != 0)
00549             return 1.0 - pow(J2_alpha, 0.5) / N;
00550         else
00551             return 0.0;
00552     }
00553     
00554 template<typename EvalT, typename Traits>
00555 Intrepid::Tensor<typename CapImplicitModel<EvalT, Traits>::DFadType>
00556 //Intrepid::Tensor<typename EvalT::DFadType>
00557 CapImplicitModel<EvalT, Traits>::compute_halpha(Intrepid::Tensor<DFadType> const & dgdsigma, DFadType const J2_alpha)
00558     {
00559         
00560         DFadType Galpha = compute_Galpha(J2_alpha);
00561         
00562         DFadType I1 = Intrepid::trace(dgdsigma), p = I1 / 3.0;
00563         
00564         Intrepid::Tensor<DFadType> s = dgdsigma
00565         - p * Intrepid::identity<DFadType>(3);
00566         
00567         //Intrepid::Tensor<DFadType, 3> halpha = calpha * Galpha * s; // * operator not defined;
00568         Intrepid::Tensor<DFadType> halpha(3);
00569         for (int i = 0; i < 3; i++) {
00570             for (int j = 0; j < 3; j++) {
00571                 halpha(i, j) = calpha * Galpha * s(i, j);
00572             }
00573         }
00574         
00575         return halpha;
00576     }
00577     
00578 template<typename EvalT, typename Traits>
00579 typename CapImplicitModel<EvalT, Traits>::DFadType
00580 //typename EvalT::DFadType
00581 CapImplicitModel<EvalT, Traits>::compute_dedkappa(DFadType const kappa)
00582     {
00583         
00584         //******** use analytical expression
00585         ScalarT Ff_kappa0 = A - C * std::exp(L * kappa0) - phi * kappa0;
00586         
00587         ScalarT X0 = kappa0 - Q * Ff_kappa0;
00588         
00589         DFadType Ff_kappa = A - C * std::exp(L * kappa) - phi * kappa;
00590         
00591         DFadType X = kappa - Q * Ff_kappa;
00592         
00593         DFadType dedX = (D1 - 2. * D2 * (X - X0))
00594         * std::exp((D1 - D2 * (X - X0)) * (X - X0)) * W;
00595         
00596         DFadType dXdkappa = 1. + Q * C * L * exp(L * kappa) + Q * phi;
00597         
00598         return dedX * dXdkappa;
00599     }
00600     
00601 template<typename EvalT, typename Traits>
00602 typename CapImplicitModel<EvalT, Traits>::DFadType
00603 //typename EvalT::DFadType
00604 CapImplicitModel<EvalT, Traits>::compute_hkappa(DFadType const I1_dgdsigma, DFadType const dedkappa)
00605     {
00606         if (dedkappa != 0)
00607             return I1_dgdsigma / dedkappa;
00608         else
00609             return 0;
00610     }
00611     
00612 template<typename EvalT, typename Traits>
00613 void
00614 CapImplicitModel<EvalT, Traits>::compute_ResidJacobian(std::vector<ScalarT> const & XXVal, std::vector<ScalarT> & R,std::vector<ScalarT> & dRdX, const Intrepid::Tensor<ScalarT> & sigmaVal,const Intrepid::Tensor<ScalarT> & alphaVal, const ScalarT & kappaVal,Intrepid::Tensor4<ScalarT> const & Celastic, bool kappa_flag)
00615     {
00616         
00617         std::vector<DFadType> Rfad(13);
00618         std::vector<DFadType> XX(13);
00619         std::vector<ScalarT> XXtmp(13);
00620         
00621         // initialize DFadType local unknown vector Xfad
00622         // Note that since Xfad is a temporary variable that gets changed within local iterations
00623         // when we initialize Xfad, we only pass in the values of X, NOT the system sensitivity information
00624         for (int i = 0; i < 13; ++i) {
00625             XXtmp[i] = Sacado::ScalarValue<ScalarT>::eval(XXVal[i]);
00626             XX[i] = DFadType(13, i, XXtmp[i]);
00627         }
00628         
00629         Intrepid::Tensor<DFadType> sigma(3), alpha(3);
00630         
00631         sigma(0, 0) = XX[0];
00632         sigma(0, 1) = XX[5];
00633         sigma(0, 2) = XX[4];
00634         sigma(1, 0) = XX[5];
00635         sigma(1, 1) = XX[1];
00636         sigma(1, 2) = XX[3];
00637         sigma(2, 0) = XX[4];
00638         sigma(2, 1) = XX[3];
00639         sigma(2, 2) = XX[2];
00640         
00641         alpha(0, 0) = XX[6];
00642         alpha(0, 1) = XX[10];
00643         alpha(0, 2) = XX[9];
00644         alpha(1, 0) = XX[10];
00645         alpha(1, 1) = XX[7];
00646         alpha(1, 2) = XX[8];
00647         alpha(2, 0) = XX[9];
00648         alpha(2, 1) = XX[8];
00649         alpha(2, 2) = -XX[6] - XX[7];
00650         
00651         DFadType kappa = XX[11];
00652         
00653         DFadType dgamma = XX[12];
00654         
00655         DFadType f = compute_f(sigma, alpha, kappa);
00656         
00657         Intrepid::Tensor<DFadType> dgdsigma = compute_dgdsigma(XX);
00658         
00659         DFadType J2_alpha = 0.5 * Intrepid::dotdot(alpha, alpha);
00660         
00661         Intrepid::Tensor<DFadType> halpha = compute_halpha(dgdsigma, J2_alpha);
00662         
00663         DFadType I1_dgdsigma = Intrepid::trace(dgdsigma);
00664         
00665         DFadType dedkappa = compute_dedkappa(kappa);
00666         
00667         DFadType hkappa = compute_hkappa(I1_dgdsigma, dedkappa);
00668         
00669         DFadType t;
00670         
00671         t = 0;
00672         for (int i = 0; i < 3; i++) {
00673             for (int j = 0; j < 3; j++) {
00674                 t = t + Celastic(0, 0, i, j) * dgdsigma(i, j);
00675             }
00676         }
00677         Rfad[0] = dgamma * t + sigma(0, 0) - sigmaVal(0, 0);
00678         
00679         t = 0;
00680         for (int i = 0; i < 3; i++) {
00681             for (int j = 0; j < 3; j++) {
00682                 t = t + Celastic(1, 1, i, j) * dgdsigma(i, j);
00683             }
00684         }
00685         Rfad[1] = dgamma * t + sigma(1, 1) - sigmaVal(1, 1);
00686         
00687         t = 0;
00688         for (int i = 0; i < 3; i++) {
00689             for (int j = 0; j < 3; j++) {
00690                 t = t + Celastic(2, 2, i, j) * dgdsigma(i, j);
00691             }
00692         }
00693         Rfad[2] = dgamma * t + sigma(2, 2) - sigmaVal(2, 2);
00694         
00695         t = 0;
00696         for (int i = 0; i < 3; i++) {
00697             for (int j = 0; j < 3; j++) {
00698                 t = t + Celastic(1, 2, i, j) * dgdsigma(i, j);
00699             }
00700         }
00701         Rfad[3] = dgamma * t + sigma(1, 2) - sigmaVal(1, 2);
00702         
00703         t = 0;
00704         for (int i = 0; i < 3; i++) {
00705             for (int j = 0; j < 3; j++) {
00706                 t = t + Celastic(0, 2, i, j) * dgdsigma(i, j);
00707             }
00708         }
00709         Rfad[4] = dgamma * t + sigma(0, 2) - sigmaVal(0, 2);
00710         
00711         t = 0;
00712         for (int i = 0; i < 3; i++) {
00713             for (int j = 0; j < 3; j++) {
00714                 t = t + Celastic(0, 1, i, j) * dgdsigma(i, j);
00715             }
00716         }
00717         Rfad[5] = dgamma * t + sigma(0, 1) - sigmaVal(0, 1);
00718         
00719         Rfad[6] = dgamma * halpha(0, 0) - alpha(0, 0) + alphaVal(0, 0);
00720         
00721         Rfad[7] = dgamma * halpha(1, 1) - alpha(1, 1) + alphaVal(1, 1);
00722         
00723         Rfad[8] = dgamma * halpha(1, 2) - alpha(1, 2) + alphaVal(1, 2);
00724         
00725         Rfad[9] = dgamma * halpha(0, 2) - alpha(0, 2) + alphaVal(0, 2);
00726         
00727         Rfad[10] = dgamma * halpha(0, 1) - alpha(0, 1) + alphaVal(0, 1);
00728         
00729         if (kappa_flag == false)
00730             Rfad[11] = dgamma * hkappa - kappa + kappaVal;
00731         else
00732             Rfad[11] = 0;
00733         
00734         // debugging
00735         //  if(kappa_flag == false)Rfad[11] = -dgamma * hkappa - kappa + kappaVal;
00736         //  else Rfad[11] = 0;
00737         
00738         Rfad[12] = f;
00739         
00740         // get ScalarT Residual
00741         for (int i = 0; i < 13; i++)
00742             R[i] = Rfad[i].val();
00743         
00744         //std::cout << "in assemble_Resid, R= " << R[0] << " " << R[1] << " " << R[2] << " " << R[3]<< std::endl;
00745         
00746         // get Jacobian
00747         for (int i = 0; i < 13; i++)
00748             for (int j = 0; j < 13; j++)
00749                 dRdX[i + 13 * j] = Rfad[i].dx(j);
00750         
00751         if (kappa_flag == true) {
00752             for (int j = 0; j < 13; j++)
00753                 dRdX[11 + 13 * j] = 0.0;
00754             
00755             dRdX[11 + 13 * 11] = 1.0;
00756         }
00757         
00758     }
00759     
00760 } // end LCM

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