00001
00002
00003
00004
00005
00006
00007
00008 #include "Teuchos_TestForException.hpp"
00009 #include "Phalanx_DataLayout.hpp"
00010
00011 #include <Intrepid_MiniTensor.h>
00012
00013 #include "Intrepid_FunctionSpaceTools.hpp"
00014 #include "Intrepid_RealSpaceTools.hpp"
00015
00016 namespace LCM {
00017
00018
00019 template<typename EvalT, typename Traits>
00020 SurfaceTLPoroMassResidual<EvalT, Traits>::
00021 SurfaceTLPoroMassResidual(const Teuchos::ParameterList& p,
00022 const Teuchos::RCP<Albany::Layouts>& dl) :
00023 thickness (p.get<double>("thickness")),
00024 cubature (p.get<Teuchos::RCP<Intrepid::Cubature<RealType> > >("Cubature")),
00025 intrepidBasis (p.get<Teuchos::RCP<Intrepid::Basis<RealType, Intrepid::FieldContainer<RealType> > > >("Intrepid Basis")),
00026 scalarGrad (p.get<std::string>("Scalar Gradient Name"),dl->qp_vector),
00027 surface_Grad_BF (p.get<std::string>("Surface Scalar Gradient Operator Name"),dl->node_qp_gradient),
00028 refDualBasis (p.get<std::string>("Reference Dual Basis Name"),dl->qp_tensor),
00029 refNormal (p.get<std::string>("Reference Normal Name"),dl->qp_vector),
00030 refArea (p.get<std::string>("Reference Area Name"),dl->qp_scalar),
00031 porePressure (p.get<std::string>("Pore Pressure Name"),dl->qp_scalar),
00032 nodalPorePressure (p.get<std::string>("Nodal Pore Pressure Name"),dl->node_scalar),
00033 biotCoefficient (p.get<std::string>("Biot Coefficient Name"),dl->qp_scalar),
00034 biotModulus (p.get<std::string>("Biot Modulus Name"),dl->qp_scalar),
00035 kcPermeability (p.get<std::string>("Kozeny-Carman Permeability Name"),dl->qp_scalar),
00036 deltaTime (p.get<std::string>("Delta Time Name"),dl->workset_scalar),
00037 poroMassResidual (p.get<std::string>("Residual Name"),dl->node_scalar),
00038 haveMech(false)
00039 {
00040 this->addDependentField(scalarGrad);
00041 this->addDependentField(surface_Grad_BF);
00042 this->addDependentField(refDualBasis);
00043 this->addDependentField(refNormal);
00044 this->addDependentField(refArea);
00045 this->addDependentField(porePressure);
00046 this->addDependentField(nodalPorePressure);
00047 this->addDependentField(biotCoefficient);
00048 this->addDependentField(biotModulus);
00049 this->addDependentField(kcPermeability);
00050 this->addDependentField(deltaTime);
00051
00052 this->addEvaluatedField(poroMassResidual);
00053
00054 this->setName("Surface TL Poro Mass Residual"+PHX::TypeString<EvalT>::value);
00055
00056 if (p.isType<std::string>("DefGrad Name")) {
00057 haveMech = true;
00058
00059 PHX::MDField<ScalarT,Cell,QuadPoint,Dim, Dim>
00060 tf(p.get<std::string>("DefGrad Name"), dl->qp_tensor);
00061 defGrad = tf;
00062 this->addDependentField(defGrad);
00063
00064 PHX::MDField<ScalarT,Cell,QuadPoint>
00065 tj(p.get<std::string>("DetDefGrad Name"), dl->qp_scalar);
00066 J = tj;
00067 this->addDependentField(J);
00068 }
00069
00070 std::vector<PHX::DataLayout::size_type> dims;
00071 dl->node_vector->dimensions(dims);
00072 worksetSize = dims[0];
00073 numNodes = dims[1];
00074 numDims = dims[2];
00075
00076 numQPs = cubature->getNumPoints();
00077
00078 numPlaneNodes = numNodes / 2;
00079 numPlaneDims = numDims - 1;
00080
00081 #ifdef ALBANY_VERBOSE
00082 std::cout << "in Surface TL Poro Mass Residual" << std::endl;
00083 std::cout << " numPlaneNodes: " << numPlaneNodes << std::endl;
00084 std::cout << " numPlaneDims: " << numPlaneDims << std::endl;
00085 std::cout << " numQPs: " << numQPs << std::endl;
00086 std::cout << " cubature->getNumPoints(): " << cubature->getNumPoints() << std::endl;
00087 std::cout << " cubature->getDimension(): " << cubature->getDimension() << std::endl;
00088 #endif
00089
00090
00091 refValues.resize(numPlaneNodes, numQPs);
00092 refGrads.resize(numPlaneNodes, numQPs, numPlaneDims);
00093 refPoints.resize(numQPs, numPlaneDims);
00094 refWeights.resize(numQPs);
00095
00096 if (haveMech) {
00097
00098 C.resize(worksetSize, numQPs, numDims, numDims);
00099 Cinv.resize(worksetSize, numQPs, numDims, numDims);
00100 F_inv.resize(worksetSize, numQPs, numDims, numDims);
00101 F_invT.resize(worksetSize, numQPs, numDims, numDims);
00102 JF_invT.resize(worksetSize, numQPs, numDims, numDims);
00103 KJF_invT.resize(worksetSize, numQPs, numDims, numDims);
00104 Kref.resize(worksetSize, numQPs, numDims, numDims);
00105 }
00106
00107
00108 flux.resize(worksetSize, numQPs, numDims);
00109
00110
00111 cubature->getCubature(refPoints, refWeights);
00112 intrepidBasis->getValues(refValues, refPoints, Intrepid::OPERATOR_VALUE);
00113 intrepidBasis->getValues(refGrads, refPoints, Intrepid::OPERATOR_GRAD);
00114
00115 porePressureName = p.get<std::string>("Pore Pressure Name")+"_old";
00116
00117 if (haveMech) JName ="surf_J_old";
00118 }
00119
00120
00121 template<typename EvalT, typename Traits>
00122 void SurfaceTLPoroMassResidual<EvalT, Traits>::
00123 postRegistrationSetup(typename Traits::SetupData d,
00124 PHX::FieldManager<Traits>& fm)
00125 {
00126 this->utils.setFieldData(scalarGrad,fm);
00127 this->utils.setFieldData(surface_Grad_BF,fm);
00128 this->utils.setFieldData(refDualBasis,fm);
00129 this->utils.setFieldData(refNormal,fm);
00130 this->utils.setFieldData(refArea,fm);
00131 this->utils.setFieldData(porePressure, fm);
00132 this->utils.setFieldData(nodalPorePressure, fm);
00133 this->utils.setFieldData(biotCoefficient, fm);
00134 this->utils.setFieldData(biotModulus, fm);
00135 this->utils.setFieldData(kcPermeability, fm);
00136 this->utils.setFieldData(deltaTime, fm);
00137 this->utils.setFieldData(poroMassResidual,fm);
00138 if (haveMech) {
00139
00140 this->utils.setFieldData(defGrad,fm);
00141 this->utils.setFieldData(J,fm);
00142 }
00143 }
00144
00145
00146 template<typename EvalT, typename Traits>
00147 void SurfaceTLPoroMassResidual<EvalT, Traits>::
00148 evaluateFields(typename Traits::EvalData workset)
00149 {
00150 typedef Intrepid::FunctionSpaceTools FST;
00151 typedef Intrepid::RealSpaceTools<ScalarT> RST;
00152
00153 Albany::MDArray porePressureold = (*workset.stateArrayPtr)[porePressureName];
00154 Albany::MDArray Jold;
00155 if (haveMech) {
00156 Jold = (*workset.stateArrayPtr)[JName];
00157 }
00158
00159 ScalarT dt = deltaTime(0);
00160
00161
00162
00163 if (haveMech) {
00164
00165 RST::inverse(F_inv, defGrad);
00166 RST::transpose(F_invT, F_inv);
00167 FST::scalarMultiplyDataData<ScalarT>(JF_invT, J, F_invT);
00168 FST::scalarMultiplyDataData<ScalarT>(KJF_invT, kcPermeability, JF_invT);
00169 FST::tensorMultiplyDataData<ScalarT>(Kref, F_inv, KJF_invT);
00170 FST::tensorMultiplyDataData<ScalarT> (flux, Kref, scalarGrad);
00171 } else {
00172 FST::scalarMultiplyDataData<ScalarT> (flux, kcPermeability, scalarGrad);
00173 }
00174
00175 for (std::size_t cell(0); cell < workset.numCells; ++cell) {
00176 for (std::size_t node(0); node < numPlaneNodes; ++node) {
00177
00178 int topNode = node + numPlaneNodes;
00179 poroMassResidual(cell, topNode) = 0.0;
00180 poroMassResidual(cell, node) = 0.0;
00181 }
00182 }
00183
00184 for (std::size_t cell(0); cell < workset.numCells; ++cell) {
00185 for (std::size_t node(0); node < numPlaneNodes; ++node) {
00186 int topNode = node + numPlaneNodes;
00187
00188 for (std::size_t pt=0; pt < numQPs; ++pt) {
00189
00190
00191
00192
00193 poroMassResidual(cell, node) -= refValues(node,pt)*
00194 (std::log(J(cell,pt)/Jold(cell, pt))*
00195 biotCoefficient(cell,pt) +
00196 (porePressure(cell, pt) - porePressureold(cell, pt))/
00197 biotModulus(cell,pt))*refArea(cell,pt);
00198
00199 poroMassResidual(cell, topNode) -= refValues(node,pt)*
00200 (std::log(J(cell,pt)/Jold(cell, pt))*
00201 biotCoefficient(cell,pt) +
00202 (porePressure(cell, pt) - porePressureold(cell, pt))/
00203 biotModulus(cell,pt))*refArea(cell,pt);
00204
00205 }
00206 }
00207 }
00208
00209
00210 for (std::size_t cell(0); cell < workset.numCells; ++cell) {
00211 for (std::size_t node(0); node < numPlaneNodes; ++node) {
00212
00213 int topNode = node + numPlaneNodes;
00214
00215 for (std::size_t pt=0; pt < numQPs; ++pt) {
00216 for (std::size_t dim=0; dim <numDims; ++dim){
00217
00218 poroMassResidual(cell,node) -= flux(cell, pt, dim)*dt*
00219 surface_Grad_BF(cell, node, pt, dim)*
00220 refArea(cell,pt);
00221
00222 poroMassResidual(cell, topNode) -= flux(cell, pt, dim)*dt*
00223 surface_Grad_BF(cell, topNode, pt, dim)*
00224 refArea(cell,pt);
00225 }
00226 }
00227 }
00228 }
00229 }
00230
00231 }