00001
00002
00003
00004
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 using namespace std;
00014
00015 namespace LCM {
00016
00017 template<typename EvalT, typename Traits>
00018 LamentStress<EvalT, Traits>::
00019 LamentStress(Teuchos::ParameterList& p) :
00020 defGradField(p.get<std::string>("DefGrad Name"),
00021 p.get<Teuchos::RCP<PHX::DataLayout> >("QP Tensor Data Layout")),
00022 stressField(p.get<std::string>("Stress Name"),
00023 p.get<Teuchos::RCP<PHX::DataLayout> >("QP Tensor Data Layout") ),
00024 lamentMaterialModel(Teuchos::RCP<lament::Material<ScalarT> >())
00025 {
00026
00027 tensor_dl = p.get< Teuchos::RCP<PHX::DataLayout> >("QP Tensor Data Layout");
00028 std::vector<PHX::DataLayout::size_type> dims;
00029 tensor_dl->dimensions(dims);
00030 numQPs = dims[1];
00031 numDims = dims[2];
00032
00033 TEUCHOS_TEST_FOR_EXCEPTION(this->numDims != 3, Teuchos::Exceptions::InvalidParameter, " LAMENT materials enabled only for three-dimensional analyses.");
00034
00035 defGradName = p.get<std::string>("DefGrad Name")+"_old";
00036 this->addDependentField(defGradField);
00037
00038 stressName = p.get<std::string>("Stress Name")+"_old";
00039 this->addEvaluatedField(stressField);
00040
00041 this->setName("LamentStress"+PHX::TypeString<EvalT>::value);
00042
00043
00044 lamentMaterialModelName = p.get<string>("Lame Material Model", "Elastic");
00045 std::cout << "Material Model Name : " << lamentMaterialModelName << std::endl;
00046 Teuchos::ParameterList& lamentMaterialParameters = p.sublist("Lame Material Parameters");
00047
00048
00049 int haveMatDB = p.get<bool>("Have MatDB", false);
00050
00051 std::string ebName = p.get<std::string>("Element Block Name", "Missing");
00052
00053
00054 if (haveMatDB) {
00055
00056 bool dataFromDatabase = lamentMaterialParameters.get<bool>("Material Dependent Data Source",false);
00057
00058
00059 if (dataFromDatabase) {
00060 Teuchos::RCP<QCAD::MaterialDatabase> materialDB = p.get< Teuchos::RCP<QCAD::MaterialDatabase> >("MaterialDB");
00061
00062 lamentMaterialModelName = materialDB->getElementBlockParam<std::string>(ebName, "Lame Material Model");
00063 lamentMaterialParameters = materialDB->getElementBlockSublist(ebName, "Lame Material Parameters");
00064 }
00065 }
00066
00067
00068
00069
00070
00071 lamentMaterialModel = LameUtils::constructLamentMaterialModel<ScalarT>(lamentMaterialModelName, lamentMaterialParameters);
00072
00073
00074 lamentMaterialModelStateVariableNames = LameUtils::getStateVariableNames(lamentMaterialModelName, lamentMaterialParameters);
00075
00076
00077 Teuchos::RCP<PHX::DataLayout> dataLayout = p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout");
00078 for(unsigned int i=0 ; i<lamentMaterialModelStateVariableNames.size() ; ++i){
00079 PHX::MDField<ScalarT,Cell,QuadPoint,Dim,Dim> lamentMaterialModelStateVariableField(lamentMaterialModelStateVariableNames[i], dataLayout);
00080 this->addEvaluatedField(lamentMaterialModelStateVariableField);
00081 lamentMaterialModelStateVariableFields.push_back(lamentMaterialModelStateVariableField);
00082 }
00083 }
00084
00085 template<typename EvalT, typename Traits>
00086 void LamentStress<EvalT, Traits>::
00087 postRegistrationSetup(typename Traits::SetupData d,
00088 PHX::FieldManager<Traits>& fm)
00089 {
00090 this->utils.setFieldData(defGradField,fm);
00091 this->utils.setFieldData(stressField,fm);
00092 for(unsigned int i=0 ; i<lamentMaterialModelStateVariableFields.size() ; ++i)
00093 this->utils.setFieldData(lamentMaterialModelStateVariableFields[i],fm);
00094 }
00095
00096 template<typename EvalT, typename Traits>
00097 void LamentStress<EvalT, Traits>::
00098 evaluateFields(typename Traits::EvalData workset)
00099 {
00100 Teuchos::RCP<lament::matParams<ScalarT> > matp = Teuchos::rcp(new lament::matParams<ScalarT>());
00101
00102
00103 Albany::MDArray oldDefGrad = (*workset.stateArrayPtr)[defGradName];
00104 Albany::MDArray oldStress = (*workset.stateArrayPtr)[stressName];
00105
00106 int numStateVariables = (int)(this->lamentMaterialModelStateVariableNames.size());
00107
00108
00109 double deltaT = 1.0;
00110
00111 vector<ScalarT> strainRate(6);
00112 vector<ScalarT> spin(3);
00113 vector<ScalarT> defGrad(9);
00114 vector<ScalarT> leftStretch(6);
00115 vector<ScalarT> rotation(9);
00116 vector<double> stressOld(6);
00117 vector<ScalarT> stressNew(6);
00118 vector<double> stateOld(numStateVariables);
00119 vector<double> stateNew(numStateVariables);
00120
00121
00122
00123
00124 matp->nelements = 1;
00125 matp->dt = deltaT;
00126 matp->time = 0.0;
00127 matp->strain_rate = &strainRate[0];
00128 matp->spin = &spin[0];
00129 matp->deformation_gradient = &defGrad[0];
00130 matp->left_stretch = &leftStretch[0];
00131 matp->rotation = &rotation[0];
00132 matp->state_old = &stateOld[0];
00133 matp->state_new = &stateNew[0];
00134 matp->stress_old = &stressOld[0];
00135 matp->stress_new = &stressNew[0];
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 for (int cell=0; cell < (int)workset.numCells; ++cell) {
00148 for (int qp=0; qp < (int)numQPs; ++qp) {
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190 Intrepid::Tensor<ScalarT> Fnew( 3, &defGradField(cell,qp,0,0) );
00191
00192
00193 Intrepid::Tensor<ScalarT> Fold( oldDefGrad(cell,qp,0,0), oldDefGrad(cell,qp,0,1), oldDefGrad(cell,qp,0,2),
00194 oldDefGrad(cell,qp,1,0), oldDefGrad(cell,qp,1,1), oldDefGrad(cell,qp,1,2),
00195 oldDefGrad(cell,qp,2,0), oldDefGrad(cell,qp,2,1), oldDefGrad(cell,qp,2,2) );
00196
00197
00198 Intrepid::Tensor<ScalarT> Finc = Fnew * Intrepid::inverse(Fold);
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216 Intrepid::Tensor<ScalarT> V(3), R(3), U(3);
00217 boost::tie(V,R) = Intrepid::polar_left(Fnew);
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256 Intrepid::Tensor<ScalarT> Uinc(3), Vinc(3), Rinc(3), logVinc(3);
00257
00258 boost::tie(Vinc,Rinc) = Intrepid::polar_left(Finc);
00259
00260 logVinc = Intrepid::log(Vinc);
00261
00262
00263 Intrepid::Tensor<ScalarT> logRinc = Intrepid::log_rotation(Rinc);
00264
00265
00266 Intrepid::Tensor<ScalarT> logFinc = Intrepid::bch(logVinc, logRinc);
00267
00268
00269 Intrepid::Tensor<ScalarT> L = (1.0/deltaT)*logFinc;
00270
00271
00272 Intrepid::Tensor<ScalarT> D = Intrepid::sym(L);
00273
00274
00275 Intrepid::Tensor<ScalarT> W = Intrepid::skew(L);
00276
00277
00278
00279 strainRate[0] = ( D(0,0) );
00280 strainRate[1] = ( D(1,1) );
00281 strainRate[2] = ( D(2,2) );
00282 strainRate[3] = ( D(0,1) );
00283 strainRate[4] = ( D(1,2) );
00284 strainRate[5] = ( D(2,0) );
00285
00286 spin[0] = ( W(0,1) );
00287 spin[1] = ( W(1,2) );
00288 spin[2] = ( W(2,0) );
00289
00290 leftStretch[0] = ( V(0,0) );
00291 leftStretch[1] = ( V(1,1) );
00292 leftStretch[2] = ( V(2,2) );
00293 leftStretch[3] = ( V(0,1) );
00294 leftStretch[4] = ( V(1,2) );
00295 leftStretch[5] = ( V(2,0) );
00296
00297 rotation[0] = ( R(0,0) );
00298 rotation[1] = ( R(1,1) );
00299 rotation[2] = ( R(2,2) );
00300 rotation[3] = ( R(0,1) );
00301 rotation[4] = ( R(1,2) );
00302 rotation[5] = ( R(2,0) );
00303 rotation[6] = ( R(1,0) );
00304 rotation[7] = ( R(2,1) );
00305 rotation[8] = ( R(0,2) );
00306
00307 defGrad[0] = ( Fnew(0,0) );
00308 defGrad[1] = ( Fnew(1,1) );
00309 defGrad[2] = ( Fnew(2,2) );
00310 defGrad[3] = ( Fnew(0,1) );
00311 defGrad[4] = ( Fnew(1,2) );
00312 defGrad[5] = ( Fnew(2,0) );
00313 defGrad[6] = ( Fnew(1,0) );
00314 defGrad[7] = ( Fnew(2,1) );
00315 defGrad[8] = ( Fnew(0,2) );
00316
00317 stressOld[0] = oldStress(cell,qp,0,0);
00318 stressOld[1] = oldStress(cell,qp,1,1);
00319 stressOld[2] = oldStress(cell,qp,2,2);
00320 stressOld[3] = oldStress(cell,qp,0,1);
00321 stressOld[4] = oldStress(cell,qp,1,2);
00322 stressOld[5] = oldStress(cell,qp,2,0);
00323
00324
00325 for(int iVar=0 ; iVar<numStateVariables ; iVar++){
00326 const std::string& variableName = this->lamentMaterialModelStateVariableNames[iVar]+"_old";
00327 Albany::MDArray stateVar = (*workset.stateArrayPtr)[variableName];
00328 stateOld[iVar] = stateVar(cell,qp);
00329 }
00330
00331
00332 this->lamentMaterialModel->loadStepInit(matp.get());
00333
00334
00335
00336
00337
00338 this->lamentMaterialModel->getStress(matp.get());
00339
00340
00341
00342
00343 Intrepid::Tensor<ScalarT> lameStress( stressNew[0], stressNew[3], stressNew[5],
00344 stressNew[3], stressNew[1], stressNew[4],
00345 stressNew[5], stressNew[4], stressNew[2] );
00346 Intrepid::Tensor<ScalarT> cauchy = R * lameStress * transpose(R);
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360 for (int i(0); i < 3; ++i)
00361 for (int j(0); j < 3; ++j)
00362 stressField(cell,qp,i,j) = cauchy(i,j);
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375 for(int iVar=0 ; iVar<numStateVariables ; iVar++)
00376 this->lamentMaterialModelStateVariableFields[iVar](cell,qp) = stateNew[iVar];
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392 }
00393 }
00394 }
00395
00396 }
00397