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
00014
00015
00016 #include <typeinfo>
00017
00018 namespace LCM {
00019
00020
00021 template<typename EvalT, typename Traits>
00022 SurfaceHDiffusionDefResidual<EvalT, Traits>::
00023 SurfaceHDiffusionDefResidual(const Teuchos::ParameterList& p,
00024 const Teuchos::RCP<Albany::Layouts>& dl) :
00025 thickness (p.get<double>("thickness")),
00026 cubature (p.get<Teuchos::RCP<Intrepid::Cubature<RealType> > >("Cubature")),
00027 intrepidBasis (p.get<Teuchos::RCP<Intrepid::Basis<RealType, Intrepid::FieldContainer<RealType> > > >("Intrepid Basis")),
00028 scalarGrad (p.get<std::string>("Surface Transport Gradient Name"),dl->qp_vector),
00029 surface_Grad_BF (p.get<std::string>("Surface Scalar Gradient Operator Name"),dl->node_qp_gradient),
00030 refDualBasis (p.get<std::string>("Reference Dual Basis Name"),dl->qp_tensor),
00031 refNormal (p.get<std::string>("Reference Normal Name"),dl->qp_vector),
00032 refArea (p.get<std::string>("Reference Area Name"),dl->qp_scalar),
00033 transport_ (p.get<std::string>("Transport Name"),dl->qp_scalar),
00034 nodal_transport_ (p.get<std::string>("Nodal Transport Name"),dl->node_scalar),
00035 dL_ (p.get<std::string>("Diffusion Coefficient Name"),dl->qp_scalar),
00036 eff_diff_ (p.get<std::string>("Effective Diffusivity Name"),dl->qp_scalar),
00037 convection_coefficient_ (p.get<std::string>("Tau Contribution Name"),dl->qp_scalar),
00038 strain_rate_factor_ (p.get<std::string>("Strain Rate Factor Name"),dl->qp_scalar),
00039 hydro_stress_gradient_ (p.get<std::string>("Surface HydroStress Gradient Name"),dl->qp_vector),
00040 eqps_ (p.get<std::string>("eqps Name"),dl->qp_scalar),
00041 deltaTime (p.get<std::string>("Delta Time Name"),dl->workset_scalar),
00042 element_length_ (p.get<std::string>("Element Length Name"),dl->qp_scalar),
00043 transport_residual_ (p.get<std::string>("Residual Name"),dl->node_scalar),
00044 haveMech(false),
00045 stab_param_(p.get<RealType>("Stabilization Parameter"))
00046 {
00047 this->addDependentField(scalarGrad);
00048 this->addDependentField(surface_Grad_BF);
00049 this->addDependentField(refDualBasis);
00050 this->addDependentField(refNormal);
00051 this->addDependentField(refArea);
00052 this->addDependentField(transport_);
00053 this->addDependentField(nodal_transport_);
00054 this->addDependentField(dL_);
00055 this->addDependentField(eff_diff_);
00056 this->addDependentField(convection_coefficient_);
00057 this->addDependentField(strain_rate_factor_);
00058 this->addDependentField(eqps_);
00059 this->addDependentField(hydro_stress_gradient_);
00060 this->addDependentField(element_length_);
00061 this->addDependentField(deltaTime);
00062
00063 this->addEvaluatedField(transport_residual_);
00064
00065
00066 this->setName("Transport Residual"+PHX::TypeString<EvalT>::value);
00067
00068 if (p.isType<std::string>("DefGrad Name")) {
00069 haveMech = true;
00070
00071 PHX::MDField<ScalarT,Cell,QuadPoint,Dim, Dim>
00072 tf(p.get<std::string>("DefGrad Name"), dl->qp_tensor);
00073 defGrad = tf;
00074 this->addDependentField(defGrad);
00075
00076 PHX::MDField<ScalarT,Cell,QuadPoint>
00077 tj(p.get<std::string>("DetDefGrad Name"), dl->qp_scalar);
00078 J = tj;
00079 this->addDependentField(J);
00080 }
00081
00082 std::vector<PHX::DataLayout::size_type> dims;
00083 dl->node_vector->dimensions(dims);
00084 worksetSize = dims[0];
00085 numNodes = dims[1];
00086 numDims = dims[2];
00087
00088 numQPs = cubature->getNumPoints();
00089
00090 numPlaneNodes = numNodes / 2;
00091 numPlaneDims = numDims - 1;
00092
00093 #ifdef ALBANY_VERBOSE
00094 std::cout << "in Surface Scalar Residual" << std::endl;
00095 std::cout << " numPlaneNodes: " << numPlaneNodes << std::endl;
00096 std::cout << " numPlaneDims: " << numPlaneDims << std::endl;
00097 std::cout << " numQPs: " << numQPs << std::endl;
00098 std::cout << " cubature->getNumPoints(): " << cubature->getNumPoints() << std::endl;
00099 std::cout << " cubature->getDimension(): " << cubature->getDimension() << std::endl;
00100 #endif
00101
00102
00103 refValues.resize(numPlaneNodes, numQPs);
00104 refGrads.resize(numPlaneNodes, numQPs, numPlaneDims);
00105 refPoints.resize(numQPs, numPlaneDims);
00106 refWeights.resize(numQPs);
00107
00108
00109 artificalDL.resize(worksetSize, numQPs);
00110 stabilizedDL.resize(worksetSize, numQPs);
00111 flux.resize(worksetSize, numQPs, numDims);
00112
00113 pterm.resize(worksetSize, numQPs);
00114
00115
00116 cubature->getCubature(refPoints, refWeights);
00117 intrepidBasis->getValues(refValues, refPoints, Intrepid::OPERATOR_VALUE);
00118 intrepidBasis->getValues(refGrads, refPoints, Intrepid::OPERATOR_GRAD);
00119
00120 transportName = p.get<std::string>("Transport Name")+"_old";
00121 if (haveMech) eqpsName =p.get<std::string>("eqps Name")+"_old";
00122 }
00123
00124
00125 template<typename EvalT, typename Traits>
00126 void SurfaceHDiffusionDefResidual<EvalT, Traits>::
00127 postRegistrationSetup(typename Traits::SetupData d,
00128 PHX::FieldManager<Traits>& fm)
00129 {
00130 this->utils.setFieldData(scalarGrad,fm);
00131 this->utils.setFieldData(surface_Grad_BF,fm);
00132 this->utils.setFieldData(refDualBasis,fm);
00133 this->utils.setFieldData(refNormal,fm);
00134 this->utils.setFieldData(refArea,fm);
00135 this->utils.setFieldData(transport_, fm);
00136 this->utils.setFieldData(nodal_transport_, fm);
00137 this->utils.setFieldData(dL_, fm);
00138 this->utils.setFieldData(eff_diff_, fm);
00139 this->utils.setFieldData(convection_coefficient_, fm);
00140 this->utils.setFieldData(strain_rate_factor_, fm);
00141 this->utils.setFieldData(element_length_, fm);
00142 this->utils.setFieldData(deltaTime, fm);
00143 this->utils.setFieldData(transport_residual_,fm);
00144
00145 if (haveMech) {
00146
00147 this->utils.setFieldData(defGrad,fm);
00148 this->utils.setFieldData(J,fm);
00149 this->utils.setFieldData(eqps_, fm);
00150 this->utils.setFieldData(hydro_stress_gradient_, fm);
00151 }
00152 }
00153
00154
00155 template<typename EvalT, typename Traits>
00156 void SurfaceHDiffusionDefResidual<EvalT, Traits>::
00157 evaluateFields(typename Traits::EvalData workset)
00158 {
00159
00160
00161
00162 Albany::MDArray transportold = (*workset.stateArrayPtr)[transportName];
00163 Albany::MDArray scalarGrad_old = (*workset.stateArrayPtr)[CLGradName];
00164 Albany::MDArray eqps_old;
00165 if (haveMech) {
00166 eqps_old = (*workset.stateArrayPtr)[eqpsName];
00167 }
00168
00169 ScalarT dt = deltaTime(0);
00170 ScalarT temp(0.0);
00171 ScalarT transientTerm(0.0);
00172 ScalarT stabilizationTerm(0.0);
00173
00174
00175
00176
00177 for (std::size_t cell=0; cell < workset.numCells; ++cell) {
00178
00179 for (std::size_t pt=0; pt < numQPs; ++pt) {
00180
00181 if (dt == 0){
00182 artificalDL(cell,pt) = 0;
00183 } else {
00184 temp = thickness*thickness /6.0*eff_diff_(cell,pt)/dL_(cell,pt)/dt;
00185 artificalDL(cell,pt) = stab_param_*temp*
00186 (0.5 + 0.5*std::tanh( (temp-1.0)/dL_(cell,pt) ))*
00187 dL_(cell,pt);
00188 }
00189 stabilizedDL(cell,pt) = artificalDL(cell,pt)/( dL_(cell,pt) + artificalDL(cell,pt) );
00190 }
00191 }
00192
00193 for (std::size_t cell=0; cell < workset.numCells; ++cell) {
00194 for (std::size_t pt=0; pt < numQPs; ++pt) {
00195
00196 Intrepid::Tensor<ScalarT> F(numDims, &defGrad(cell, pt, 0, 0));
00197 Intrepid::Tensor<ScalarT> C_tensor_ = Intrepid::t_dot(F,F);
00198 Intrepid::Tensor<ScalarT> C_inv_tensor_ = Intrepid::inverse(C_tensor_);
00199 Intrepid::Vector<ScalarT> C_grad_(numDims, &scalarGrad(cell, pt, 0));
00200 Intrepid::Vector<ScalarT> C_grad_in_ref_ = Intrepid::dot(C_inv_tensor_, C_grad_ );
00201
00202 for (std::size_t j=0; j<numDims; j++){
00203 flux(cell,pt,j) = (1-stabilizedDL(cell,pt))*C_grad_in_ref_(j);
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 int topNode = node + numPlaneNodes;
00213 transport_residual_(cell, node) = 0;
00214 transport_residual_(cell, topNode) = 0;
00215 }
00216 }
00217
00218 for (std::size_t cell(0); cell < workset.numCells; ++cell) {
00219 for (std::size_t node(0); node < numPlaneNodes; ++node) {
00220 int topNode = node + numPlaneNodes;
00221 for (std::size_t pt=0; pt < numQPs; ++pt) {
00222 for (std::size_t dim=0; dim <numDims; ++dim){
00223
00224 transport_residual_(cell, node) += flux(cell, pt, dim)*dt*
00225 surface_Grad_BF(cell, node, pt, dim)*
00226 refArea(cell,pt);
00227
00228 transport_residual_(cell, topNode) += flux(cell, pt, dim)*dt*
00229 surface_Grad_BF(cell, topNode, pt, dim)*
00230 refArea(cell,pt);
00231 }
00232 }
00233 }
00234 }
00235
00236 for (std::size_t cell(0); cell < workset.numCells; ++cell) {
00237 for (std::size_t node(0); node < numPlaneNodes; ++node) {
00238
00239 int topNode = node + numPlaneNodes;
00240
00241 for (std::size_t pt=0; pt < numQPs; ++pt) {
00242
00243
00244
00245 temp = 1.0/dL_(cell,pt) + artificalDL(cell,pt);
00246
00247
00248 transientTerm = refValues(node,pt)*
00249 ( eff_diff_(cell,pt)*
00250 (transport_(cell, pt)-transportold(cell, pt) ))*
00251 refArea(cell,pt)*temp;
00252
00253 transport_residual_(cell, node) += transientTerm;
00254
00255 transport_residual_(cell, topNode) += transientTerm;
00256
00257 if (haveMech) {
00258
00259 transientTerm = refValues(node,pt)*
00260 strain_rate_factor_(cell,pt)*
00261 (eqps_(cell,pt)- eqps_old(cell,pt))*
00262 refArea(cell,pt)*temp;
00263
00264 transport_residual_(cell, node) += transientTerm;
00265
00266 transport_residual_(cell, topNode) += transientTerm;
00267
00268
00269 for (std::size_t dim=0; dim < numDims; ++dim) {
00270
00271 transport_residual_(cell, node) -= surface_Grad_BF(cell, node, pt, dim)*
00272 convection_coefficient_(cell,pt)*transport_(cell,pt)*
00273 hydro_stress_gradient_(cell,pt, dim)*dt*
00274 refArea(cell,pt)*temp;
00275
00276 transport_residual_(cell, topNode) -= surface_Grad_BF(cell, topNode, pt, dim)*
00277 convection_coefficient_(cell,pt)*transport_(cell,pt)*
00278 hydro_stress_gradient_(cell,pt, dim)*dt*
00279 refArea(cell,pt)*temp;
00280 }
00281 }
00282 }
00283 }
00284 }
00285
00286
00287
00288 ScalarT CLPbar(0);
00289 ScalarT vol(0);
00290
00291 for (std::size_t cell=0; cell < workset.numCells; ++cell){
00292 CLPbar = 0.0;
00293 vol = 0.0;
00294 for (std::size_t qp=0; qp < numQPs; ++qp) {
00295 CLPbar += refArea(cell,qp)*
00296 (transport_(cell,qp) - transportold(cell, qp));
00297 vol += refArea(cell,qp);
00298 }
00299 CLPbar /= vol;
00300 for (std::size_t qp=0; qp < numQPs; ++qp) {
00301 pterm(cell,qp) = CLPbar;
00302 }
00303 }
00304
00305 for (std::size_t cell=0; cell < workset.numCells; ++cell) {
00306 for (std::size_t node=0; node < numPlaneNodes; ++node) {
00307
00308 int topNode = node + numPlaneNodes;
00309
00310 for (std::size_t qp=0; qp < numQPs; ++qp) {
00311
00312 temp = 1.0/dL_(cell,qp) + artificalDL(cell,qp);
00313
00314 stabilizationTerm= stab_param_*eff_diff_(cell, qp)*
00315 (-transport_(cell, qp)+transportold(cell, qp)+
00316 pterm(cell,qp))*refValues(node,qp)*
00317 refArea(cell,qp)*temp;
00318
00319 transport_residual_(cell,node) -= stabilizationTerm;
00320 transport_residual_(cell,topNode) -= stabilizationTerm;
00321 }
00322 }
00323 }
00324
00325
00326 }
00327
00328 }