00001
00002
00003
00004
00005
00006
00007 #include <Intrepid_MiniTensor.h>
00008
00009 #include "Teuchos_TestForException.hpp"
00010 #include "Phalanx_DataLayout.hpp"
00011
00012 namespace LCM {
00013
00014
00015 template<typename EvalT, typename Traits>
00016 SurfaceScalarGradient<EvalT, Traits>::
00017 SurfaceScalarGradient(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 jump (p.get<std::string>("Scalar Jump Name"),dl->qp_scalar),
00025 nodalScalar (p.get<std::string>("Nodal Scalar Name"),dl->node_scalar),
00026 scalarGrad (p.get<std::string>("Surface Scalar Gradient Name"),dl->qp_vector)
00027 {
00028 this->addDependentField(refDualBasis);
00029 this->addDependentField(refNormal);
00030 this->addDependentField(jump);
00031 this->addDependentField(nodalScalar);
00032
00033 this->addEvaluatedField(scalarGrad);
00034
00035 this->setName("Surface Scalar Gradient"+PHX::TypeString<EvalT>::value);
00036
00037 std::vector<PHX::DataLayout::size_type> dims;
00038 dl->node_vector->dimensions(dims);
00039 worksetSize = dims[0];
00040 numNodes = dims[1];
00041 numDims = dims[2];
00042
00043 numQPs = cubature->getNumPoints();
00044
00045 numPlaneNodes = numNodes / 2;
00046 numPlaneDims = numDims - 1;
00047
00048 #ifdef ALBANY_VERBOSE
00049 std::cout << "in Surface Gradient Jump" << std::endl;
00050 std::cout << " numPlaneNodes: " << numPlaneNodes << std::endl;
00051 std::cout << " numPlaneDims: " << numPlaneDims << std::endl;
00052 std::cout << " numQPs: " << numQPs << std::endl;
00053 std::cout << " cubature->getNumPoints(): " << cubature->getNumPoints() << std::endl;
00054 std::cout << " cubature->getDimension(): " << cubature->getDimension() << std::endl;
00055 #endif
00056
00057
00058 refValues.resize(numPlaneNodes, numQPs);
00059 refGrads.resize(numPlaneNodes, numQPs, numPlaneDims);
00060 refPoints.resize(numQPs, numPlaneDims);
00061 refWeights.resize(numQPs);
00062
00063
00064 cubature->getCubature(refPoints, refWeights);
00065 intrepidBasis->getValues(refValues, refPoints, Intrepid::OPERATOR_VALUE);
00066 intrepidBasis->getValues(refGrads, refPoints, Intrepid::OPERATOR_GRAD);
00067 }
00068
00069
00070 template<typename EvalT, typename Traits>
00071 void SurfaceScalarGradient<EvalT, Traits>::
00072 postRegistrationSetup(typename Traits::SetupData d,
00073 PHX::FieldManager<Traits>& fm)
00074 {
00075 this->utils.setFieldData(refDualBasis,fm);
00076 this->utils.setFieldData(refNormal,fm);
00077 this->utils.setFieldData(jump,fm);
00078 this->utils.setFieldData(nodalScalar,fm);
00079 this->utils.setFieldData(scalarGrad,fm);
00080
00081 }
00082
00083
00084 template<typename EvalT, typename Traits>
00085 void SurfaceScalarGradient<EvalT, Traits>::
00086 evaluateFields(typename Traits::EvalData workset)
00087 {
00088 ScalarT midPlaneAvg;
00089 for (std::size_t cell=0; cell < workset.numCells; ++cell) {
00090 for (std::size_t pt=0; pt < numQPs; ++pt) {
00091
00092 Intrepid::Vector<MeshScalarT> G_0(3, &refDualBasis(cell, pt, 0, 0));
00093 Intrepid::Vector<MeshScalarT> G_1(3, &refDualBasis(cell, pt, 1, 0));
00094 Intrepid::Vector<MeshScalarT> G_2(3, &refDualBasis(cell, pt, 2, 0));
00095 Intrepid::Vector<MeshScalarT> N(3, &refNormal(cell, pt, 0));
00096
00097 Intrepid::Vector<ScalarT> scalarGradPerpendicular(0, 0, 0);
00098 Intrepid::Vector<ScalarT> scalarGradParallel(0, 0, 0);
00099
00100
00101 Intrepid::Tensor<MeshScalarT> gBasis(3, &refDualBasis(cell, pt, 0, 0));
00102 Intrepid::Tensor<MeshScalarT> invRefDualBasis(3);
00103
00104
00105 gBasis = Intrepid::transpose(gBasis);
00106 invRefDualBasis = Intrepid::inverse(gBasis);
00107
00108 Intrepid::Vector<MeshScalarT> invG_0(3, &invRefDualBasis(0, 0));
00109 Intrepid::Vector<MeshScalarT> invG_1(3, &invRefDualBasis(1, 0));
00110 Intrepid::Vector<MeshScalarT> invG_2(3, &invRefDualBasis(2, 0));
00111
00112
00113 for (int node(0); node < numPlaneNodes; ++node) {
00114 int topNode = node + numPlaneNodes;
00115 midPlaneAvg = 0.5 * (nodalScalar(cell, node) + nodalScalar(cell, topNode));
00116 for (int i(0); i < numDims; ++i) {
00117 scalarGradParallel(i) +=
00118 refGrads(node, pt, 0) * midPlaneAvg * invG_0(i) +
00119 refGrads(node, pt, 1) * midPlaneAvg * invG_1(i);
00120 }
00121 }
00122
00123
00124 for (int i(0); i < numDims; ++i) {
00125 scalarGradPerpendicular(i) = jump(cell,pt) / thickness *invG_2(i);
00126 }
00127
00128
00129 for (int i(0); i < numDims; ++i )
00130 scalarGrad(cell, pt, i) = scalarGradParallel(i) + scalarGradPerpendicular(i);
00131 }
00132 }
00133 }
00134
00135 }