00001
00002
00003
00004
00005
00006
00007 #include "Teuchos_TestForException.hpp"
00008 #include "Phalanx_DataLayout.hpp"
00009
00010 #include "Intrepid_FunctionSpaceTools.hpp"
00011
00012 namespace LCM {
00013
00014
00015 template<typename EvalT, typename Traits>
00016 UnSatPoroElasticityResidMass<EvalT, Traits>::
00017 UnSatPoroElasticityResidMass(const Teuchos::ParameterList& p) :
00018 wBF (p.get<std::string> ("Weighted BF Name"),
00019 p.get<Teuchos::RCP<PHX::DataLayout> >("Node QP Scalar Data Layout") ),
00020 porePressure (p.get<std::string> ("QP Pore Pressure Name"),
00021 p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout") ),
00022 Tdot (p.get<std::string> ("QP Time Derivative Variable Name"),
00023 p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout") ),
00024 stabParameter (p.get<std::string> ("Material Property Name"),
00025 p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout") ),
00026 ThermalCond (p.get<std::string> ("Thermal Conductivity Name"),
00027 p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout") ),
00028 vgPermeability (p.get<std::string> ("Van Genuchten Permeability Name"),
00029 p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout") ),
00030 vgSat (p.get<std::string> ("Van Genuchten Saturation Name"),
00031 p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout") ),
00032 porosity (p.get<std::string> ("Porosity Name"),
00033 p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout") ),
00034 biotCoefficient (p.get<std::string> ("Biot Coefficient Name"),
00035 p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout") ),
00036 biotModulus (p.get<std::string> ("Biot Modulus Name"),
00037 p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout") ),
00038 wGradBF (p.get<std::string> ("Weighted Gradient BF Name"),
00039 p.get<Teuchos::RCP<PHX::DataLayout> >("Node QP Vector Data Layout") ),
00040 TGrad (p.get<std::string> ("Gradient QP Variable Name"),
00041 p.get<Teuchos::RCP<PHX::DataLayout> >("QP Vector Data Layout") ),
00042 Source (p.get<std::string> ("Source Name"),
00043 p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout") ),
00044 strain (p.get<std::string> ("Strain Name"),
00045 p.get<Teuchos::RCP<PHX::DataLayout> >("QP Tensor Data Layout") ),
00046 coordVec (p.get<std::string> ("Coordinate Vector Name"),
00047 p.get<Teuchos::RCP<PHX::DataLayout> >("Coordinate Data Layout") ),
00048 cubature (p.get<Teuchos::RCP <Intrepid::Cubature<RealType> > >("Cubature")),
00049 cellType (p.get<Teuchos::RCP <shards::CellTopology> > ("Cell Type")),
00050 weights (p.get<std::string> ("Weights Name"),
00051 p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout") ),
00052 deltaTime (p.get<std::string>("Delta Time Name"),
00053 p.get<Teuchos::RCP<PHX::DataLayout> >("Workset Scalar Data Layout")),
00054 TResidual (p.get<std::string> ("Residual Name"),
00055 p.get<Teuchos::RCP<PHX::DataLayout> >("Node Scalar Data Layout") ),
00056 haveSource (p.get<bool>("Have Source")),
00057 haveConvection(false),
00058 haveAbsorption (p.get<bool>("Have Absorption")),
00059 haverhoCp(false)
00060 {
00061 if (p.isType<bool>("Disable Transient"))
00062 enableTransient = !p.get<bool>("Disable Transient");
00063 else enableTransient = true;
00064
00065 this->addDependentField(stabParameter);
00066 this->addDependentField(deltaTime);
00067 this->addDependentField(weights);
00068 this->addDependentField(coordVec);
00069 this->addDependentField(wBF);
00070 this->addDependentField(porePressure);
00071 this->addDependentField(ThermalCond);
00072 this->addDependentField(vgPermeability);
00073 this->addDependentField(vgSat);
00074 this->addDependentField(porosity);
00075 this->addDependentField(biotCoefficient);
00076 this->addDependentField(biotModulus);
00077 if (enableTransient) this->addDependentField(Tdot);
00078 this->addDependentField(TGrad);
00079 this->addDependentField(wGradBF);
00080 if (haveSource) this->addDependentField(Source);
00081 if (haveAbsorption) {
00082 Absorption = PHX::MDField<ScalarT,Cell,QuadPoint>(
00083 p.get<std::string>("Absorption Name"),
00084 p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout"));
00085 this->addDependentField(Absorption);
00086 }
00087
00088
00089
00090 this->addDependentField(strain);
00091 this->addEvaluatedField(TResidual);
00092
00093 Teuchos::RCP<PHX::DataLayout> vector_dl =
00094 p.get< Teuchos::RCP<PHX::DataLayout> >("Node QP Vector Data Layout");
00095 std::vector<PHX::DataLayout::size_type> dims;
00096 vector_dl->dimensions(dims);
00097
00098
00099 strainName = p.get<std::string>("Strain Name")+"_old";
00100 porosityName = p.get<std::string>("Porosity Name")+"_old";
00101 porePressureName = p.get<std::string>("QP Pore Pressure Name")+"_old";
00102 satName = p.get<std::string>("Van Genuchten Saturation Name")+"_old";
00103
00104
00105
00106 worksetSize = dims[0];
00107 numNodes = dims[1];
00108 numQPs = dims[2];
00109 numDims = dims[3];
00110
00111
00112
00113
00114 flux.resize(dims[0], numQPs, numDims);
00115 fluxdt.resize(dims[0], numQPs, numDims);
00116 pterm.resize(dims[0], numQPs);
00117 tpterm.resize(dims[0], numNodes, numQPs);
00118
00119
00120
00121 if (haveAbsorption) aterm.resize(dims[0], numQPs);
00122
00123 convectionVels = Teuchos::getArrayFromStringParameter<double> (p,
00124 "Convection Velocity", numDims, false);
00125 if (p.isType<std::string>("Convection Velocity")) {
00126 convectionVels = Teuchos::getArrayFromStringParameter<double> (p,
00127 "Convection Velocity", numDims, false);
00128 }
00129 if (convectionVels.size()>0) {
00130 haveConvection = true;
00131 if (p.isType<bool>("Have Rho Cp"))
00132 haverhoCp = p.get<bool>("Have Rho Cp");
00133 if (haverhoCp) {
00134 PHX::MDField<ScalarT,Cell,QuadPoint> tmp(p.get<std::string>("Rho Cp Name"),
00135 p.get<Teuchos::RCP<PHX::DataLayout> >("QP Scalar Data Layout"));
00136 rhoCp = tmp;
00137 this->addDependentField(rhoCp);
00138 }
00139 }
00140
00141 this->setName("UnSatPoroElasticityResidMass"+PHX::TypeString<EvalT>::value);
00142
00143 }
00144
00145
00146 template<typename EvalT, typename Traits>
00147 void UnSatPoroElasticityResidMass<EvalT, Traits>::
00148 postRegistrationSetup(typename Traits::SetupData d,
00149 PHX::FieldManager<Traits>& fm)
00150 {
00151 this->utils.setFieldData(stabParameter,fm);
00152 this->utils.setFieldData(deltaTime,fm);
00153 this->utils.setFieldData(weights,fm);
00154 this->utils.setFieldData(coordVec,fm);
00155 this->utils.setFieldData(wBF,fm);
00156 this->utils.setFieldData(porePressure,fm);
00157 this->utils.setFieldData(ThermalCond,fm);
00158 this->utils.setFieldData(vgPermeability,fm);
00159 this->utils.setFieldData(vgSat,fm);
00160 this->utils.setFieldData(porosity,fm);
00161 this->utils.setFieldData(biotCoefficient,fm);
00162 this->utils.setFieldData(biotModulus,fm);
00163 this->utils.setFieldData(TGrad,fm);
00164 this->utils.setFieldData(wGradBF,fm);
00165 if (haveSource) this->utils.setFieldData(Source,fm);
00166 if (enableTransient) this->utils.setFieldData(Tdot,fm);
00167 if (haveAbsorption) this->utils.setFieldData(Absorption,fm);
00168 if (haveConvection && haverhoCp) this->utils.setFieldData(rhoCp,fm);
00169 this->utils.setFieldData(strain,fm);
00170 this->utils.setFieldData(TResidual,fm);
00171 }
00172
00173
00174 template<typename EvalT, typename Traits>
00175 void UnSatPoroElasticityResidMass<EvalT, Traits>::
00176 evaluateFields(typename Traits::EvalData workset)
00177 {
00178 typedef Intrepid::FunctionSpaceTools FST;
00179
00180
00181 Albany::MDArray strainold = (*workset.stateArrayPtr)[strainName];
00182 Albany::MDArray porosityold = (*workset.stateArrayPtr)[porosityName];
00183 Albany::MDArray porePressureold = (*workset.stateArrayPtr)[porePressureName];
00184 Albany::MDArray vgSatold = (*workset.stateArrayPtr)[satName];
00185
00186
00187 if (porosityold(1,1) < 0 || porosity(1,1) < 0 ) {
00188 std::cout << "negative porosity detected. Error! \n";
00189 }
00190
00191 switch (numDims) {
00192 case 3:
00193
00194
00195 for (std::size_t cell=0; cell < workset.numCells; ++cell) {
00196
00197 for (std::size_t node=0; node < numNodes; ++node) {
00198 TResidual(cell,node)=0.0;
00199 for (std::size_t qp=0; qp < numQPs; ++qp) {
00200
00201
00202 ScalarT trstrain = 0.0;
00203 for (std::size_t i(0); i < numDims; ++i){
00204 trstrain += strainold(cell,qp,i,i);
00205 }
00206
00207 TResidual(cell,node) += -vgSat(cell, qp)*(
00208
00209 strain(cell,qp,0,0) + strain(cell,qp,1,1)+strain(cell,qp,2,2) - trstrain
00210 )
00211 *wBF(cell, node, qp) ;
00212
00213
00214 TResidual(cell,node) += -porosity(cell,qp)*(
00215 vgSat(cell, qp) -vgSatold(cell, qp)
00216 )*wBF(cell, node, qp);
00217
00218 }
00219 }
00220 }
00221 break;
00222 case 2:
00223
00224 for (std::size_t cell=0; cell < workset.numCells; ++cell) {
00225
00226 for (std::size_t node=0; node < numNodes; ++node) {
00227 TResidual(cell,node)=0.0;
00228 for (std::size_t qp=0; qp < numQPs; ++qp) {
00229
00230
00231 ScalarT trstrain = 0.0;
00232 for (std::size_t i(0); i < numDims; ++i){
00233 trstrain += strainold(cell,qp,i,i);
00234 }
00235
00236 TResidual(cell,node) += -vgSat(cell, qp)*(
00237 strain(cell,qp,0,0) + strain(cell,qp,1,1) - trstrain
00238 )*wBF(cell, node, qp) ;
00239
00240
00241 TResidual(cell,node) += -porosity(cell,qp)*(vgSat(cell, qp)
00242 -vgSatold(cell, qp)
00243 )*wBF(cell, node, qp);
00244 }
00245 }
00246 }
00247 break;
00248 case 1:
00249
00250 for (std::size_t cell=0; cell < workset.numCells; ++cell) {
00251
00252 for (std::size_t node=0; node < numNodes; ++node) {
00253 TResidual(cell,node)=0.0;
00254 for (std::size_t qp=0; qp < numQPs; ++qp) {
00255
00256
00257 ScalarT trstrain = 0.0;
00258 for (std::size_t i(0); i < numDims; ++i){
00259 trstrain += strainold(cell,qp,i,i);
00260 }
00261
00262 TResidual(cell,node) += -vgSat(cell, qp)*(
00263 strain(cell,qp,0,0) - trstrain
00264 )*wBF(cell, node, qp) ;
00265
00266
00267 TResidual(cell,node) += -(vgSat(cell, qp)
00268 -vgSatold(cell, qp)
00269 )*porosity(cell, qp)*
00270 wBF(cell, node, qp);
00271 }
00272 }
00273 }
00274 break;
00275
00276 }
00277
00278
00279
00280
00281 ScalarT dt = deltaTime(0);
00282
00283 FST::scalarMultiplyDataData<ScalarT> (flux, vgPermeability, TGrad);
00284
00285 for (std::size_t cell=0; cell < workset.numCells; ++cell){
00286 for (std::size_t qp=0; qp < numQPs; ++qp) {
00287 for (std::size_t dim=0; dim <numDims; ++dim){
00288 fluxdt(cell, qp, dim) = -flux(cell,qp,dim)*dt;
00289 }
00290 }
00291 }
00292
00293
00294 FST::integrate<ScalarT>(TResidual, fluxdt, wGradBF, Intrepid::COMP_CPP, true);
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304 for (std::size_t cell=0; cell < workset.numCells; ++cell){
00305
00306 porePbar = 0.0;
00307
00308 vol = 0.0;
00309 for (std::size_t qp=0; qp < numQPs; ++qp) {
00310 porePbar += weights(cell,qp)*(vgSat(cell,qp)
00311 -vgSatold(cell, qp)
00312 );
00313
00314 vol += weights(cell,qp);
00315 }
00316 porePbar /= vol;
00317
00318 for (std::size_t qp=0; qp < numQPs; ++qp) {
00319 pterm(cell,qp) = porePbar;
00320 }
00321
00322 for (std::size_t node=0; node < numNodes; ++node) {
00323 trialPbar = 0.0;
00324 for (std::size_t qp=0; qp < numQPs; ++qp) {
00325 trialPbar += wBF(cell,node,qp);
00326 }
00327 trialPbar /= vol;
00328
00329
00330
00331
00332 }
00333
00334 }
00335
00336
00337 for (std::size_t cell=0; cell < workset.numCells; ++cell) {
00338
00339 for (std::size_t node=0; node < numNodes; ++node) {
00340 for (std::size_t qp=0; qp < numQPs; ++qp) {
00341
00342 TResidual(cell,node) -= (vgSat(cell, qp)
00343 -vgSatold(cell, qp)
00344 )
00345 *stabParameter(cell, qp)*porosity(cell, qp)*
00346 ( wBF(cell, node, qp)
00347
00348 );
00349 TResidual(cell,node) += pterm(cell,qp)*stabParameter(cell, qp)*porosity(cell, qp)*
00350 ( wBF(cell, node, qp)
00351
00352 );
00353
00354
00355
00356
00357
00358
00359 }
00360 }
00361 }
00362
00363
00364
00365
00366
00367
00368 }
00369
00370
00371 }
00372
00373