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

LameStress_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 "Intrepid_FunctionSpaceTools.hpp"
00011 #include "QCAD_MaterialDatabase.hpp"
00012 
00013 namespace LCM {
00014 
00015 template<typename EvalT, typename Traits>
00016 LameStressBase<EvalT, Traits>::
00017 LameStressBase(Teuchos::ParameterList& p) :
00018   defGradField(p.get<std::string>("DefGrad Name"),
00019                p.get<Teuchos::RCP<PHX::DataLayout> >("QP Tensor Data Layout")),
00020   stressField(p.get<std::string>("Stress Name"),
00021               p.get<Teuchos::RCP<PHX::DataLayout> >("QP Tensor Data Layout") ),
00022   lameMaterialModel(Teuchos::RCP<LameMaterial>())
00023 {
00024   // Pull out numQPs and numDims from a Layout
00025   tensor_dl = p.get< Teuchos::RCP<PHX::DataLayout> >("QP Tensor Data Layout");
00026   std::vector<PHX::DataLayout::size_type> dims;
00027   tensor_dl->dimensions(dims);
00028   numQPs  = dims[1];
00029   numDims = dims[2];
00030 
00031   TEUCHOS_TEST_FOR_EXCEPTION(this->numDims != 3, Teuchos::Exceptions::InvalidParameter, " LAME materials enabled only for three-dimensional analyses.");
00032 
00033   defGradName = p.get<std::string>("DefGrad Name")+"_old";
00034   this->addDependentField(defGradField);
00035 
00036   stressName = p.get<std::string>("Stress Name")+"_old";
00037   this->addEvaluatedField(stressField);
00038 
00039   this->setName("LameStress"+PHX::TypeString<EvalT>::value);
00040 
00041   // Default to getting material info form base input file (possibley overwritten later)
00042   lameMaterialModelName = p.get<std::string>("Lame Material Model", "Elastic");
00043   Teuchos::ParameterList& lameMaterialParameters = p.sublist("Lame Material Parameters");
00044 
00045   // Code to allow material data to come from materials.xml data file
00046   int haveMatDB = p.get<bool>("Have MatDB", false);
00047 
00048   std::string ebName = p.get<std::string>("Element Block Name", "Missing");
00049 
00050   // Check for material database file
00051   if (haveMatDB) {
00052     // Check if material database will be supplying the data
00053     bool dataFromDatabase = lameMaterialParameters.get<bool>("Material Dependent Data Source",false);
00054 
00055     // If so, overwrite material model and data from database file
00056     if (dataFromDatabase) {
00057        Teuchos::RCP<QCAD::MaterialDatabase> materialDB = p.get< Teuchos::RCP<QCAD::MaterialDatabase> >("MaterialDB");
00058 
00059        lameMaterialModelName = materialDB->getElementBlockParam<std::string>(ebName, "Lame Material Model");
00060        lameMaterialParameters = materialDB->getElementBlockSublist(ebName, "Lame Material Parameters");
00061      }
00062   }
00063 
00064   // Initialize the LAME material model
00065   // This assumes that there is a single material model associated with this
00066   // evaluator and that the material properties are constant (read directly
00067   // from input deck parameter list)
00068   lameMaterialModel = LameUtils::constructLameMaterialModel(lameMaterialModelName, lameMaterialParameters);
00069 
00070   // Get a list of the LAME material model state variable names
00071   lameMaterialModelStateVariableNames = LameUtils::getStateVariableNames(lameMaterialModelName, lameMaterialParameters);
00072 
00073   // Declare the state variables as evaluated fields (type is always double)
00074   Teuchos::RCP<PHX::DataLayout> dataLayout = p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout");
00075   for(unsigned int i=0 ; i<lameMaterialModelStateVariableNames.size() ; ++i){
00076     PHX::MDField<ScalarT,Cell,QuadPoint,Dim,Dim> lameMaterialModelStateVariableField(lameMaterialModelStateVariableNames[i], dataLayout);
00077     this->addEvaluatedField(lameMaterialModelStateVariableField);
00078     lameMaterialModelStateVariableFields.push_back(lameMaterialModelStateVariableField);
00079   }
00080 }
00081 
00082 template<typename EvalT, typename Traits>
00083 void LameStressBase<EvalT, Traits>::
00084 postRegistrationSetup(typename Traits::SetupData d,
00085                       PHX::FieldManager<Traits>& fm)
00086 {
00087   this->utils.setFieldData(defGradField,fm);
00088   this->utils.setFieldData(stressField,fm);
00089   for(unsigned int i=0 ; i<lameMaterialModelStateVariableFields.size() ; ++i)
00090     this->utils.setFieldData(lameMaterialModelStateVariableFields[i],fm);
00091 }
00092 
00093 template<typename EvalT, typename Traits>
00094 void LameStressBase<EvalT, Traits>::
00095 evaluateFields(typename Traits::EvalData workset)
00096 {
00097   TEUCHOS_TEST_FOR_EXCEPTION("LameStressBase::evaluateFields not implemented for this template type",
00098     Teuchos::Exceptions::InvalidParameter, "Need specialization.");
00099 }
00100 
00101 
00102 
00103 template<typename Traits>
00104 void LameStress<PHAL::AlbanyTraits::Residual, Traits>::
00105 evaluateFields(typename Traits::EvalData workset)
00106 {
00107 
00108   Teuchos::RCP<LameMatParams> matp = Teuchos::rcp(new LameMatParams());
00109   this->setMatP(matp, workset);
00110 
00111   this->calcStressRealType(this->stressField, this->defGradField, workset, matp);
00112 
00113   this->freeMatP(matp);
00114 
00115 }
00116 
00117 template<typename Traits>
00118 void LameStress<PHAL::AlbanyTraits::Jacobian, Traits>::
00119 evaluateFields(typename Traits::EvalData workset)
00120 {
00121   // This block forces stressField Fad to allocate deriv array --is ther a better way?
00122   PHAL::AlbanyTraits::Jacobian::ScalarT scalarToForceAllocation=this->defGradField(0,0,0,0);
00123   for (int cell=0; cell < (int)workset.numCells; ++cell)
00124     for (int qp=0; qp < (int)this->numQPs; ++qp)
00125       for (int i=0; i < (int)this->numDims; ++i)
00126         for (int j=0; j < (int)this->numDims; ++j)
00127           this->stressField(cell,qp,i,j) = scalarToForceAllocation;
00128 
00129   // Allocate Fields of RealType (move to postRegSetup)?
00130   PHX::MDField<RealType,Cell,QuadPoint,Dim,Dim> stressFieldRealType("stress_RealType", this->tensor_dl);
00131   PHX::MDField<RealType,Cell,QuadPoint,Dim,Dim> defGradFieldRealType("defGrad_RealType", this->tensor_dl);
00132   Teuchos::ArrayRCP<RealType> s_mem(this->tensor_dl->size());
00133   Teuchos::ArrayRCP<RealType> d_mem(this->tensor_dl->size());
00134   stressFieldRealType.setFieldData(s_mem);
00135   defGradFieldRealType.setFieldData(d_mem);
00136 
00137   // Allocate double arrays in matp
00138   Teuchos::RCP<LameMatParams> matp = Teuchos::rcp(new LameMatParams());
00139   this->setMatP(matp, workset);
00140 
00141   // Begin Finite Difference 
00142   // Do Base unperturbed case
00143   for (int cell=0; cell < (int)workset.numCells; ++cell)
00144     for (int qp=0; qp < (int)this->numQPs; ++qp)
00145       for (int i=0; i < (int)this->numDims; ++i)
00146         for (int j=0; j < (int)this->numDims; ++j)
00147           defGradFieldRealType(cell,qp,i,j) = this->defGradField(cell,qp,i,j).val();
00148 
00149   this->calcStressRealType(stressFieldRealType, defGradFieldRealType, workset, matp);
00150 
00151   for (int cell=0; cell < (int)workset.numCells; ++cell)
00152     for (int qp=0; qp < (int)this->numQPs; ++qp)
00153       for (int i=0; i < (int)this->numDims; ++i)
00154         for (int j=0; j < (int)this->numDims; ++j)
00155           this->stressField(cell,qp,i,j).val() = stressFieldRealType(cell,qp,i,j);
00156 
00157   // Do Perturbations
00158   double pert=1.0e-6;
00159   int numIVs = this->defGradField(0,0,0,0).size();
00160   for (int iv=0; iv < numIVs; ++iv) {
00161     for (int cell=0; cell < (int)workset.numCells; ++cell)
00162       for (int qp=0; qp < (int)this->numQPs; ++qp)
00163         for (int i=0; i < (int)this->numDims; ++i)
00164           for (int j=0; j < (int)this->numDims; ++j)
00165             defGradFieldRealType(cell,qp,i,j) = 
00166               this->defGradField(cell,qp,i,j).val() + pert*this->defGradField(cell,qp,i,j).fastAccessDx(iv);
00167 
00168     this->calcStressRealType(stressFieldRealType, defGradFieldRealType, workset, matp);
00169 
00170     for (int cell=0; cell < (int)workset.numCells; ++cell)
00171       for (int qp=0; qp < (int)this->numQPs; ++qp)
00172         for (int i=0; i < (int)this->numDims; ++i)
00173           for (int j=0; j < (int)this->numDims; ++j)
00174             this->stressField(cell,qp,i,j).fastAccessDx(iv) =
00175               (stressFieldRealType(cell,qp,i,j) - this->stressField(cell,qp,i,j).val()) / pert;
00176   }
00177 
00178   // Free double arrays allocated in matp
00179   this->freeMatP(matp);
00180 }
00181 
00182 // Tangent implementation is Identical to Jacobian
00183 template<typename Traits>
00184 void LameStress<PHAL::AlbanyTraits::Tangent, Traits>::
00185 evaluateFields(typename Traits::EvalData workset)
00186 {
00187   // This block forces stressField Fad to allocate deriv array
00188   PHAL::AlbanyTraits::Tangent::ScalarT scalarToForceAllocation=this->defGradField(0,0,0,0);
00189   for (int cell=0; cell < (int)workset.numCells; ++cell)
00190     for (int qp=0; qp < (int)this->numQPs; ++qp)
00191       for (int i=0; i < (int)this->numDims; ++i)
00192         for (int j=0; j < (int)this->numDims; ++j)
00193           this->stressField(cell,qp,i,j) = scalarToForceAllocation;
00194 
00195   // Allocate Fields of RealType (move to postRegSetup)?
00196   PHX::MDField<RealType,Cell,QuadPoint,Dim,Dim> stressFieldRealType("stress_RealType", this->tensor_dl);
00197   PHX::MDField<RealType,Cell,QuadPoint,Dim,Dim> defGradFieldRealType("defGrad_RealType", this->tensor_dl);
00198   Teuchos::ArrayRCP<RealType> s_mem(this->tensor_dl->size());
00199   Teuchos::ArrayRCP<RealType> d_mem(this->tensor_dl->size());
00200   stressFieldRealType.setFieldData(s_mem);
00201   defGradFieldRealType.setFieldData(d_mem);
00202 
00203   // Allocate double arrays in matp
00204   Teuchos::RCP<LameMatParams> matp = Teuchos::rcp(new LameMatParams());
00205   this->setMatP(matp, workset);
00206 
00207   // Begin Finite Difference 
00208   // Do Base unperturbed case
00209   for (int cell=0; cell < (int)workset.numCells; ++cell)
00210     for (int qp=0; qp < (int)this->numQPs; ++qp)
00211       for (int i=0; i < (int)this->numDims; ++i)
00212         for (int j=0; j < (int)this->numDims; ++j)
00213           defGradFieldRealType(cell,qp,i,j) = this->defGradField(cell,qp,i,j).val();
00214 
00215   this->calcStressRealType(stressFieldRealType, defGradFieldRealType, workset, matp);
00216 
00217   for (int cell=0; cell < (int)workset.numCells; ++cell)
00218     for (int qp=0; qp < (int)this->numQPs; ++qp)
00219       for (int i=0; i < (int)this->numDims; ++i)
00220         for (int j=0; j < (int)this->numDims; ++j)
00221           this->stressField(cell,qp,i,j).val() = stressFieldRealType(cell,qp,i,j);
00222 
00223   // Do Perturbations
00224   double pert=1.0e-8;
00225   int numIVs = this->defGradField(0,0,0,0).size();
00226   for (int iv=0; iv < numIVs; ++iv) {
00227     for (int cell=0; cell < (int)workset.numCells; ++cell)
00228       for (int qp=0; qp < (int)this->numQPs; ++qp)
00229         for (int i=0; i < (int)this->numDims; ++i)
00230           for (int j=0; j < (int)this->numDims; ++j)
00231             defGradFieldRealType(cell,qp,i,j) = 
00232               this->defGradField(cell,qp,i,j).val() + pert*this->defGradField(cell,qp,i,j).fastAccessDx(iv);
00233 
00234     this->calcStressRealType(stressFieldRealType, defGradFieldRealType, workset, matp);
00235 
00236     for (int cell=0; cell < (int)workset.numCells; ++cell)
00237       for (int qp=0; qp < (int)this->numQPs; ++qp)
00238         for (int i=0; i < (int)this->numDims; ++i)
00239           for (int j=0; j < (int)this->numDims; ++j)
00240             this->stressField(cell,qp,i,j).fastAccessDx(iv) =
00241               (stressFieldRealType(cell,qp,i,j) - this->stressField(cell,qp,i,j).val()) / pert;
00242   }
00243 
00244   // Free double arrays allocated in matp
00245   this->freeMatP(matp);
00246 }
00247 
00248 template<typename EvalT, typename Traits>
00249 void LameStressBase<EvalT, Traits>::
00250   setMatP(Teuchos::RCP<LameMatParams>& matp,
00251           typename Traits::EvalData workset)
00252 {
00253   // \todo Get actual time step for calls to LAME materials.
00254   RealType deltaT = 1.0;
00255 
00256   int numStateVariables = (int)(this->lameMaterialModelStateVariableNames.size());
00257 
00258   // Allocate workset space
00259   // Lame is called one time (called for all material points in the workset at once)
00260   int numMaterialEvaluations = workset.numCells * this->numQPs;
00261 
00262   double* strainRate = new double[6*numMaterialEvaluations];   // symmetric tensor5
00263   double* spin = new double[3*numMaterialEvaluations];         // skew-symmetric tensor
00264   double* leftStretch = new double[6*numMaterialEvaluations];  // symmetric tensor
00265   double* rotation = new double[9*numMaterialEvaluations];     // full tensor
00266   double* stressOld = new double[6*numMaterialEvaluations];    // symmetric tensor
00267   double* stressNew = new double[6*numMaterialEvaluations];    // symmetric tensor
00268   double* stateOld = new double[numStateVariables*numMaterialEvaluations];  // a single double for each state variable
00269   double* stateNew = new double[numStateVariables*numMaterialEvaluations];  // a single double for each state variable
00270 
00271   // \todo Set up scratch space for material models using getNumScratchVars() and setScratchPtr().
00272 
00273   // Create the matParams structure, which is passed to Lame
00274   matp->nelements = numMaterialEvaluations;
00275   matp->dt = deltaT;
00276   matp->time = 0.0;
00277   matp->strain_rate = strainRate;
00278   matp->spin = spin;
00279   matp->left_stretch = leftStretch;
00280   matp->rotation = rotation;
00281   matp->state_old = stateOld;
00282   matp->state_new = stateNew;
00283   matp->stress_old = stressOld;
00284   matp->stress_new = stressNew;
00285 //   matp->dt_mat = std::numeric_limits<double>::max();
00286   
00287   // matParams that still need to be added:
00288   // matp->temp_old  (temperature)
00289   // matp->temp_new
00290   // matp->sound_speed_old
00291   // matp->sound_speed_new
00292   // matp->volume
00293   // scratch pointer
00294   // function pointers (lots to be done here)
00295 }
00296 
00297 template<typename EvalT, typename Traits>
00298 void LameStressBase<EvalT, Traits>::
00299   freeMatP(Teuchos::RCP<LameMatParams>& matp)
00300 {
00301   delete [] matp->strain_rate;
00302   delete [] matp->spin;
00303   delete [] matp->left_stretch;
00304   delete [] matp->rotation;
00305   delete [] matp->state_old;
00306   delete [] matp->state_new;
00307   delete [] matp->stress_old;
00308   delete [] matp->stress_new;
00309 }
00310 
00311 template<typename EvalT, typename Traits>
00312 void LameStressBase<EvalT, Traits>::
00313   calcStressRealType(PHX::MDField<RealType,Cell,QuadPoint,Dim,Dim>& stressFieldRef,
00314              PHX::MDField<RealType,Cell,QuadPoint,Dim,Dim>& defGradFieldRef,
00315              typename Traits::EvalData workset,
00316              Teuchos::RCP<LameMatParams>& matp) 
00317 {
00318   // Get the old state data
00319   Albany::MDArray oldDefGrad = (*workset.stateArrayPtr)[defGradName];
00320   Albany::MDArray oldStress = (*workset.stateArrayPtr)[stressName];
00321 
00322   int numStateVariables = (int)(this->lameMaterialModelStateVariableNames.size());
00323 
00324   // Pointers used for filling the matParams structure
00325   double* strainRatePtr = matp->strain_rate;
00326   double* spinPtr = matp->spin;
00327   double* leftStretchPtr = matp->left_stretch;
00328   double* rotationPtr = matp->rotation;
00329   double* stateOldPtr = matp->state_old;
00330   double* stressOldPtr = matp->stress_old;
00331 
00332   double deltaT = matp->dt;
00333 
00334   for (int cell=0; cell < (int)workset.numCells; ++cell) {
00335     for (int qp=0; qp < (int)numQPs; ++qp) {
00336 
00337       // Fill the following entries in matParams for call to LAME
00338       //
00339       // nelements     - number of elements 
00340       // dt            - time step, this one is tough because Albany does not currently have a concept of time step for implicit integration
00341       // time          - current time, again Albany does not currently have a concept of time for implicit integration
00342       // strain_rate   - what Sierra calls the rate of deformation, it is the symmetric part of the velocity gradient
00343       // spin          - anti-symmetric part of the velocity gradient
00344       // left_stretch  - found as V in the polar decomposition of the deformation gradient F = VR
00345       // rotation      - found as R in the polar decomposition of the deformation gradient F = VR
00346       // state_old     - material state data for previous time step (material dependent, none for lame(nt)::Elastic)
00347       // state_new     - material state data for current time step (material dependent, none for lame(nt)::Elastic)
00348       // stress_old    - stress at previous time step
00349       // stress_new    - stress at current time step, filled by material model
00350       //
00351       // The total deformation gradient is available as field data
00352       // 
00353       // The velocity gradient is not available but can be computed at the logarithm of the incremental deformation gradient divided by deltaT
00354       // The incremental deformation gradient is computed as F_new F_old^-1
00355 
00356       // JTO:  here is how I think this will go (of course the first two lines won't work as is...)
00357       // Intrepid::Tensor<RealType> F = newDefGrad;
00358       // Intrepid::Tensor<RealType> Fn = oldDefGrad;
00359       // Intrepid::Tensor<RealType> f = F*Intrepid::inverse(Fn);
00360       // Intrepid::Tensor<RealType> V;
00361       // Intrepid::Tensor<RealType> R;
00362       // boost::tie(V,R) = Intrepid::polar_left(F);
00363       // Intrepid::Tensor<RealType> Vinc;
00364       // Intrepid::Tensor<RealType> Rinc;
00365       // Intrepid::Tensor<RealType> logVinc;
00366       // boost::tie(Vinc,Rinc,logVinc) = Intrepid::polar_left_logV(f)
00367       // Intrepid::Tensor<RealType> logRinc = Intrepid::log_rotation(Rinc);
00368       // Intrepid::Tensor<RealType> logf = Intrepid::bch(logVinc,logRinc);
00369       // Intrepid::Tensor<RealType> L = (1.0/deltaT)*logf;
00370       // Intrepid::Tensor<RealType> D = Intrepid::sym(L);
00371       // Intrepid::Tensor<RealType> W = Intrepid::skew(L);
00372       // and then fill data into the vectors below
00373 
00374       // new deformation gradient (the current deformation gradient as computed in the current configuration)
00375       Intrepid::Tensor<RealType> Fnew(
00376        defGradFieldRef(cell,qp,0,0), defGradFieldRef(cell,qp,0,1), defGradFieldRef(cell,qp,0,2),
00377        defGradFieldRef(cell,qp,1,0), defGradFieldRef(cell,qp,1,1), defGradFieldRef(cell,qp,1,2),
00378        defGradFieldRef(cell,qp,2,0), defGradFieldRef(cell,qp,2,1), defGradFieldRef(cell,qp,2,2) );
00379 
00380       // old deformation gradient (deformation gradient at previous load step)
00381       Intrepid::Tensor<RealType> Fold( oldDefGrad(cell,qp,0,0), oldDefGrad(cell,qp,0,1), oldDefGrad(cell,qp,0,2),
00382                                  oldDefGrad(cell,qp,1,0), oldDefGrad(cell,qp,1,1), oldDefGrad(cell,qp,1,2),
00383                                  oldDefGrad(cell,qp,2,0), oldDefGrad(cell,qp,2,1), oldDefGrad(cell,qp,2,2) );
00384 
00385       // incremental deformation gradient
00386       Intrepid::Tensor<RealType> Finc = Fnew * Intrepid::inverse(Fold);
00387 
00388       // left stretch V, and rotation R, from left polar decomposition of new deformation gradient
00389       Intrepid::Tensor<RealType> V(3), R(3);
00390       boost::tie(V,R) = Intrepid::polar_left_eig(Fnew);
00391 
00392       // incremental left stretch Vinc, incremental rotation Rinc, and log of incremental left stretch, logVinc
00393       Intrepid::Tensor<RealType> Vinc(3), Rinc(3), logVinc(3);
00394       boost::tie(Vinc,Rinc,logVinc) = Intrepid::polar_left_logV_lame(Finc);
00395 
00396       // log of incremental rotation
00397       Intrepid::Tensor<RealType> logRinc = Intrepid::log_rotation(Rinc);
00398 
00399       // log of incremental deformation gradient
00400       Intrepid::Tensor<RealType> logFinc = Intrepid::bch(logVinc, logRinc);
00401 
00402       // velocity gradient
00403       Intrepid::Tensor<RealType> L = RealType(1.0/deltaT)*logFinc;
00404 
00405       // strain rate (a.k.a rate of deformation)
00406       Intrepid::Tensor<RealType> D = Intrepid::sym(L);
00407 
00408       // spin
00409       Intrepid::Tensor<RealType> W = Intrepid::skew(L);
00410 
00411       // load everything into the Lame data structure
00412 
00413       strainRatePtr[0] = ( D(0,0) );
00414       strainRatePtr[1] = ( D(1,1) );
00415       strainRatePtr[2] = ( D(2,2) );
00416       strainRatePtr[3] = ( D(0,1) );
00417       strainRatePtr[4] = ( D(1,2) );
00418       strainRatePtr[5] = ( D(0,2) );
00419 
00420       spinPtr[0] = ( W(0,1) );
00421       spinPtr[1] = ( W(1,2) );
00422       spinPtr[2] = ( W(0,2) );
00423 
00424       leftStretchPtr[0] = ( V(0,0) );
00425       leftStretchPtr[1] = ( V(1,1) );
00426       leftStretchPtr[2] = ( V(2,2) );
00427       leftStretchPtr[3] = ( V(0,1) );
00428       leftStretchPtr[4] = ( V(1,2) );
00429       leftStretchPtr[5] = ( V(0,2) );
00430 
00431       rotationPtr[0] = ( R(0,0) );
00432       rotationPtr[1] = ( R(1,1) );
00433       rotationPtr[2] = ( R(2,2) );
00434       rotationPtr[3] = ( R(0,1) );
00435       rotationPtr[4] = ( R(1,2) );
00436       rotationPtr[5] = ( R(0,2) );
00437       rotationPtr[6] = ( R(1,0) );
00438       rotationPtr[7] = ( R(2,1) );
00439       rotationPtr[8] = ( R(2,0) );
00440 
00441       stressOldPtr[0] = oldStress(cell,qp,0,0);
00442       stressOldPtr[1] = oldStress(cell,qp,1,1);
00443       stressOldPtr[2] = oldStress(cell,qp,2,2);
00444       stressOldPtr[3] = oldStress(cell,qp,0,1);
00445       stressOldPtr[4] = oldStress(cell,qp,1,2);
00446       stressOldPtr[5] = oldStress(cell,qp,0,2);
00447 
00448       // increment the pointers
00449       strainRatePtr += 6;
00450       spinPtr += 3;
00451       leftStretchPtr += 6;
00452       rotationPtr += 9;
00453       stressOldPtr += 6;
00454 
00455       // copy data from the state manager to the LAME data structure
00456       for(int iVar=0 ; iVar<numStateVariables ; iVar++, stateOldPtr++){
00457         //std::string& variableName = this->lameMaterialModelStateVariableNames[iVar];
00458         //const Intrepid::FieldContainer<RealType>& stateVar = *oldState[variableName];
00459         const std::string& variableName = this->lameMaterialModelStateVariableNames[iVar]+"_old";
00460         Albany::MDArray stateVar = (*workset.stateArrayPtr)[variableName];
00461         *stateOldPtr = stateVar(cell,qp);
00462       }
00463     }
00464   }
00465 
00466   // Make a call to the LAME material model to initialize the load step
00467   this->lameMaterialModel->loadStepInit(matp.get());
00468 
00469   // Get the stress from the LAME material
00470   this->lameMaterialModel->getStress(matp.get());
00471 
00472   double* stressNewPtr = matp->stress_new;
00473 
00474   // Post-process data from Lame call
00475   for (std::size_t cell=0; cell < workset.numCells; ++cell) {
00476     for (std::size_t qp=0; qp < numQPs; ++qp) {
00477 
00478       // Copy the new stress into the stress field
00479       stressFieldRef(cell,qp,0,0) = stressNewPtr[0];
00480       stressFieldRef(cell,qp,1,1) = stressNewPtr[1];
00481       stressFieldRef(cell,qp,2,2) = stressNewPtr[2];
00482       stressFieldRef(cell,qp,0,1) = stressNewPtr[3];
00483       stressFieldRef(cell,qp,1,2) = stressNewPtr[4];
00484       stressFieldRef(cell,qp,0,2) = stressNewPtr[5];
00485       stressFieldRef(cell,qp,1,0) = stressNewPtr[3]; 
00486       stressFieldRef(cell,qp,2,1) = stressNewPtr[4]; 
00487       stressFieldRef(cell,qp,2,0) = stressNewPtr[5];
00488 
00489       stressNewPtr += 6;
00490     }
00491   }
00492 
00493   // !!!!! When should this be done???
00494   double* stateNewPtr = matp->state_new;
00495   for (std::size_t cell=0; cell < workset.numCells; ++cell) {
00496     for (std::size_t qp=0; qp < numQPs; ++qp) {
00497       // copy state_new data from the LAME data structure to the corresponding state variable field
00498       for(int iVar=0 ; iVar<numStateVariables ; iVar++, stateNewPtr++)
00499         this->lameMaterialModelStateVariableFields[iVar](cell,qp) = *stateNewPtr;
00500     }
00501   }
00502 
00503 }
00504 
00505 
00506 }
00507 

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