00001
00002
00003
00004
00005
00006
00007 #include <Intrepid_MiniTensor.h>
00008 #include <Phalanx_DataLayout.hpp>
00009 #include <Teuchos_TestForException.hpp>
00010
00011
00012 namespace LCM {
00013
00014
00015 template<typename EvalT, typename Traits>
00016 SurfaceScalarGradientOperator<EvalT, Traits>::
00017 SurfaceScalarGradientOperator(const Teuchos::ParameterList& p,
00018 const Teuchos::RCP<Albany::Layouts>& dl) :
00019 thickness (p.get<double>("thickness")),
00020 cubature (p.get<Teuchos::RCP<Intrepid::Cubature<RealType> > >("Cubature")),
00021 intrepidBasis (p.get<Teuchos::RCP<Intrepid::Basis<RealType, Intrepid::FieldContainer<RealType> > > >("Intrepid Basis")),
00022 refDualBasis (p.get<std::string>("Reference Dual Basis Name"),dl->qp_tensor),
00023 refNormal (p.get<std::string>("Reference Normal Name"),dl->qp_vector),
00024 val_node (p.get<std::string>("Nodal Scalar Name"),dl->node_scalar),
00025 surface_Grad_BF (p.get<std::string>("Surface Scalar Gradient Operator Name"),dl->node_qp_gradient),
00026 grad_val_qp (p.get<std::string> ("Surface Scalar Gradient Name"), dl->qp_gradient)
00027 {
00028 this->addDependentField(refDualBasis);
00029 this->addDependentField(refNormal);
00030 this->addDependentField(val_node);
00031
00032
00033 this->addEvaluatedField(surface_Grad_BF);
00034 this->addEvaluatedField(grad_val_qp);
00035
00036
00037 this->setName("Surface Scalar Gradient Operator"+PHX::TypeString<EvalT>::value);
00038
00039 std::vector<PHX::DataLayout::size_type> dims;
00040 dl->node_qp_gradient->dimensions(dims);
00041 worksetSize = dims[0];
00042 numNodes = dims[1];
00043 numDims = dims[3];
00044
00045 numQPs = cubature->getNumPoints();
00046
00047 numPlaneNodes = numNodes / 2;
00048 numPlaneDims = numDims - 1;
00049
00050 #ifdef ALBANY_VERBOSE
00051 std::cout << "in Surface Scalar Gradient Operator" << std::endl;
00052 std::cout << " numPlaneNodes: " << numPlaneNodes << std::endl;
00053 std::cout << " numPlaneDims: " << numPlaneDims << std::endl;
00054 std::cout << " numQPs: " << numQPs << std::endl;
00055 std::cout << " cubature->getNumPoints(): " << cubature->getNumPoints() << std::endl;
00056 std::cout << " cubature->getDimension(): " << cubature->getDimension() << std::endl;
00057 #endif
00058
00059
00060
00061 refValues.resize(numPlaneNodes, numQPs);
00062 refGrads.resize(numPlaneNodes, numQPs, numPlaneDims);
00063 refPoints.resize(numQPs, numPlaneDims);
00064 refWeights.resize(numQPs);
00065
00066
00067 cubature->getCubature(refPoints, refWeights);
00068 intrepidBasis->getValues(refValues, refPoints, Intrepid::OPERATOR_VALUE);
00069 intrepidBasis->getValues(refGrads, refPoints, Intrepid::OPERATOR_GRAD);
00070 }
00071
00072
00073 template<typename EvalT, typename Traits>
00074 void SurfaceScalarGradientOperator<EvalT, Traits>::
00075 postRegistrationSetup(typename Traits::SetupData d,
00076 PHX::FieldManager<Traits>& fm)
00077 {
00078 this->utils.setFieldData(refDualBasis,fm);
00079 this->utils.setFieldData(refNormal,fm);
00080 this->utils.setFieldData(val_node,fm);
00081 this->utils.setFieldData(surface_Grad_BF,fm);
00082 this->utils.setFieldData(grad_val_qp,fm);
00083 }
00084
00085
00086 template<typename EvalT, typename Traits>
00087 void SurfaceScalarGradientOperator<EvalT, Traits>::
00088 evaluateFields(typename Traits::EvalData workset)
00089 {
00090 Intrepid::Vector<MeshScalarT> Parent_Grad_plus(3);
00091 Intrepid::Vector<MeshScalarT> Parent_Grad_minor(3);
00092
00093 for (std::size_t cell=0; cell < workset.numCells; ++cell) {
00094 for (std::size_t pt=0; pt < numQPs; ++pt) {
00095
00096 Intrepid::Tensor<MeshScalarT> gBasis(3, &refDualBasis(cell, pt, 0, 0));
00097
00098 Intrepid::Vector<MeshScalarT> N(3, &refNormal(cell, pt, 0));
00099
00100 gBasis = Intrepid::transpose(gBasis);
00101
00102
00103 for (int node(0); node < numPlaneNodes; ++node) {
00104 int topNode = node + numPlaneNodes;
00105
00106
00107 for (int i(0); i < numPlaneDims; ++i ){
00108 Parent_Grad_plus(i) = 0.5*refGrads(node, pt, i);
00109 Parent_Grad_minor(i) = 0.5*refGrads(node, pt, i);
00110 }
00111
00112
00113 MeshScalarT invh = 1./ thickness;
00114 Parent_Grad_plus(numPlaneDims) = invh * refValues(node,pt);
00115 Parent_Grad_minor(numPlaneDims) = -invh * refValues(node,pt);
00116
00117
00118 Intrepid::Vector<MeshScalarT> Transformed_Grad_plus(Intrepid::dot(gBasis, Parent_Grad_plus));
00119 Intrepid::Vector<MeshScalarT> Transformed_Grad_minor(Intrepid::dot(gBasis,Parent_Grad_minor));
00120
00121
00122 for (int j(0); j < numDims; ++j ){
00123 surface_Grad_BF(cell, topNode, pt, j) = Transformed_Grad_plus(j);
00124 surface_Grad_BF(cell, node, pt, j) = Transformed_Grad_minor(j);
00125 }
00126 }
00127 }
00128 }
00129
00130 for (std::size_t cell=0; cell < workset.numCells; ++cell) {
00131 for (std::size_t pt=0; pt < numQPs; ++pt) {
00132 for (int k(0); k< numDims; ++k){
00133 grad_val_qp(cell, pt, k) = 0;
00134 for (int node(0); node < numNodes; ++node) {
00135 grad_val_qp(cell, pt, k) += surface_Grad_BF(cell, node, pt, k)*
00136 val_node(cell,node);
00137 }
00138 }
00139 }
00140 }
00141
00142 }
00143
00144 }