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 SurfaceVectorGradient<EvalT, Traits>::
00017 SurfaceVectorGradient(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 currentBasis (p.get<std::string>("Current Basis Name"),dl->qp_tensor),
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>("Vector Jump Name"),dl->qp_vector),
00025 weights (p.get<std::string>("Weights Name"),dl->qp_scalar),
00026 defGrad (p.get<std::string>("Surface Vector Gradient Name"),dl->qp_tensor),
00027 J (p.get<std::string>("Surface Vector Gradient Determinant Name"),dl->qp_scalar),
00028 weightedAverage(p.get<bool>("Weighted Volume Average J", false)),
00029 alpha(p.get<RealType>("Average J Stabilization Parameter", 0.0))
00030 {
00031
00032
00033
00034
00035
00036 this->addDependentField(currentBasis);
00037 this->addDependentField(refDualBasis);
00038 this->addDependentField(refNormal);
00039 this->addDependentField(jump);
00040 this->addDependentField(weights);
00041
00042 this->addEvaluatedField(defGrad);
00043 this->addEvaluatedField(J);
00044
00045 this->setName("Surface Vector Gradient"+PHX::TypeString<EvalT>::value);
00046
00047 std::vector<PHX::DataLayout::size_type> dims;
00048 dl->node_vector->dimensions(dims);
00049 worksetSize = dims[0];
00050 numNodes = dims[1];
00051 numDims = dims[2];
00052
00053 numQPs = cubature->getNumPoints();
00054
00055 numPlaneNodes = numNodes / 2;
00056 numPlaneDims = numDims - 1;
00057 }
00058
00059
00060 template<typename EvalT, typename Traits>
00061 void SurfaceVectorGradient<EvalT, Traits>::
00062 postRegistrationSetup(typename Traits::SetupData d,
00063 PHX::FieldManager<Traits>& fm)
00064 {
00065 this->utils.setFieldData(currentBasis,fm);
00066 this->utils.setFieldData(refDualBasis,fm);
00067 this->utils.setFieldData(refNormal,fm);
00068 this->utils.setFieldData(jump,fm);
00069 this->utils.setFieldData(weights,fm);
00070 this->utils.setFieldData(defGrad,fm);
00071 this->utils.setFieldData(J,fm);
00072 }
00073
00074
00075 template<typename EvalT, typename Traits>
00076 void SurfaceVectorGradient<EvalT, Traits>::
00077 evaluateFields(typename Traits::EvalData workset)
00078 {
00079 for (std::size_t cell=0; cell < workset.numCells; ++cell) {
00080 for (std::size_t pt=0; pt < numQPs; ++pt) {
00081 Intrepid::Vector<ScalarT> g_0(3, ¤tBasis(cell, pt, 0, 0));
00082 Intrepid::Vector<ScalarT> g_1(3, ¤tBasis(cell, pt, 1, 0));
00083 Intrepid::Vector<ScalarT> g_2(3, ¤tBasis(cell, pt, 2, 0));
00084 Intrepid::Vector<MeshScalarT> G_2(3, &refNormal(cell, pt, 0));
00085 Intrepid::Vector<ScalarT> d(3, &jump(cell, pt, 0));
00086 Intrepid::Vector<MeshScalarT> G0(3, &refDualBasis(cell, pt, 0, 0));
00087 Intrepid::Vector<MeshScalarT> G1(3, &refDualBasis(cell, pt, 1, 0));
00088 Intrepid::Vector<MeshScalarT> G2(3, &refDualBasis(cell, pt, 2, 0));
00089
00090 Intrepid::Tensor<ScalarT>
00091 Fpar(Intrepid::bun(g_0, G0) +
00092 Intrepid::bun(g_1, G1) +
00093 Intrepid::bun(g_2, G2));
00094
00095 Intrepid::Tensor<ScalarT> Fper((1 / thickness) * Intrepid::bun(d, G_2));
00096
00097 Intrepid::Tensor<ScalarT> F = Fpar + Fper;
00098
00099 defGrad(cell, pt, 0, 0) = F(0, 0);
00100 defGrad(cell, pt, 0, 1) = F(0, 1);
00101 defGrad(cell, pt, 0, 2) = F(0, 2);
00102 defGrad(cell, pt, 1, 0) = F(1, 0);
00103 defGrad(cell, pt, 1, 1) = F(1, 1);
00104 defGrad(cell, pt, 1, 2) = F(1, 2);
00105 defGrad(cell, pt, 2, 0) = F(2, 0);
00106 defGrad(cell, pt, 2, 1) = F(2, 1);
00107 defGrad(cell, pt, 2, 2) = F(2, 2);
00108
00109 J(cell,pt) = Intrepid::det(F);
00110 }
00111 }
00112
00113 if (weightedAverage)
00114 {
00115 ScalarT Jbar, wJbar, vol;
00116 for (std::size_t cell=0; cell < workset.numCells; ++cell)
00117 {
00118 Jbar = 0.0;
00119 vol = 0.0;
00120 for (std::size_t qp=0; qp < numQPs; ++qp)
00121 {
00122 Jbar += weights(cell,qp) * std::log( J(cell,qp) );
00123 vol += weights(cell,qp);
00124 }
00125 Jbar /= vol;
00126
00127
00128 for (std::size_t qp=0; qp < numQPs; ++qp)
00129 {
00130 for (std::size_t i=0; i < numDims; ++i)
00131 {
00132 for (std::size_t j=0; j < numDims; ++j)
00133 {
00134 wJbar = std::exp( (1-alpha) * Jbar + alpha * std::log( J(cell,qp) ) );
00135 defGrad(cell,qp,i,j) *= std::pow( wJbar / J(cell,qp) ,1./3. );
00136 }
00137 }
00138 J(cell,qp) = wJbar;
00139 }
00140 }
00141 }
00142
00143 }
00144
00145 }