00001
00002
00003
00004
00005
00006
00007 #include "Teuchos_TestForException.hpp"
00008 #include "Teuchos_VerboseObject.hpp"
00009 #include "Phalanx_DataLayout.hpp"
00010
00011 #include "Intrepid_FunctionSpaceTools.hpp"
00012
00013
00014
00015
00016
00017
00018 namespace FELIX {
00019
00020
00021 template<typename EvalT, typename Traits>
00022 StokesFOResid<EvalT, Traits>::
00023 StokesFOResid(const Teuchos::ParameterList& p,
00024 const Teuchos::RCP<Albany::Layouts>& dl) :
00025 wBF (p.get<std::string> ("Weighted BF Name"), dl->node_qp_scalar),
00026 wGradBF (p.get<std::string> ("Weighted Gradient BF Name"),dl->node_qp_gradient),
00027 U (p.get<std::string> ("QP Variable Name"), dl->qp_vector),
00028 Ugrad (p.get<std::string> ("Gradient QP Variable Name"), dl->qp_vecgradient),
00029 UDot (p.get<std::string> ("QP Time Derivative Variable Name"), dl->qp_vector),
00030 force (p.get<std::string> ("Body Force Name"), dl->qp_vector),
00031 muFELIX (p.get<std::string> ("FELIX Viscosity QP Variable Name"), dl->qp_scalar),
00032 Residual (p.get<std::string> ("Residual Name"), dl->node_vector)
00033 {
00034
00035 Teuchos::ParameterList* list =
00036 p.get<Teuchos::ParameterList*>("Parameter List");
00037
00038 std::string type = list->get("Type", "FELIX");
00039
00040 Teuchos::RCP<Teuchos::FancyOStream> out(Teuchos::VerboseObjectBase::getDefaultOStream());
00041 if (type == "FELIX") {
00042 #ifdef OUTPUT_TO_SCREEN
00043 *out << "setting FELIX FO model physics" << std::endl;
00044 #endif
00045 eqn_type = FELIX;
00046 }
00047 else if (type == "Poisson") {
00048 #ifdef OUTPUT_TO_SCREEN
00049 *out << "setting Poisson (Laplace) operator" << std::endl;
00050 #endif
00051 eqn_type = POISSON;
00052 }
00053
00054 this->addDependentField(U);
00055 this->addDependentField(Ugrad);
00056 this->addDependentField(force);
00057
00058 this->addDependentField(wBF);
00059 this->addDependentField(wGradBF);
00060 this->addDependentField(muFELIX);
00061
00062 this->addEvaluatedField(Residual);
00063
00064
00065 this->setName("StokesFOResid"+PHX::TypeString<EvalT>::value);
00066
00067 std::vector<PHX::DataLayout::size_type> dims;
00068 wGradBF.fieldTag().dataLayout().dimensions(dims);
00069 numNodes = dims[1];
00070 numQPs = dims[2];
00071 numDims = dims[3];
00072
00073 U.fieldTag().dataLayout().dimensions(dims);
00074 vecDim = dims[2];
00075
00076
00077
00078
00079
00080
00081
00082 if (vecDim != 2 & eqn_type == FELIX) {TEUCHOS_TEST_FOR_EXCEPTION(true, Teuchos::Exceptions::InvalidParameter,
00083 std::endl << "Error in FELIX::StokesFOResid constructor: " <<
00084 "Invalid Parameter vecDim. Problem implemented for 2 dofs per node only (u and v). " << std::endl);}
00085 if (vecDim != 1 & eqn_type == POISSON) {TEUCHOS_TEST_FOR_EXCEPTION(true, Teuchos::Exceptions::InvalidParameter,
00086 std::endl << "Error in FELIX::StokesFOResid constructor: " <<
00087 "Invalid Parameter vecDim. Poisson problem implemented for 1 dof per node only. " << std::endl);}
00088
00089 }
00090
00091
00092 template<typename EvalT, typename Traits>
00093 void StokesFOResid<EvalT, Traits>::
00094 postRegistrationSetup(typename Traits::SetupData d,
00095 PHX::FieldManager<Traits>& fm)
00096 {
00097 this->utils.setFieldData(U,fm);
00098 this->utils.setFieldData(Ugrad,fm);
00099 this->utils.setFieldData(force,fm);
00100
00101 this->utils.setFieldData(wBF,fm);
00102 this->utils.setFieldData(wGradBF,fm);
00103 this->utils.setFieldData(muFELIX,fm);
00104
00105 this->utils.setFieldData(Residual,fm);
00106 }
00107
00108
00109 template<typename EvalT, typename Traits>
00110 void StokesFOResid<EvalT, Traits>::
00111 evaluateFields(typename Traits::EvalData workset)
00112 {
00113 typedef Intrepid::FunctionSpaceTools FST;
00114
00115 for (std::size_t i=0; i < Residual.size(); ++i) Residual(i)=0.0;
00116
00117 if (numDims == 3) {
00118 if (eqn_type == FELIX) {
00119 for (std::size_t cell=0; cell < workset.numCells; ++cell) {
00120 for (std::size_t qp=0; qp < numQPs; ++qp) {
00121 ScalarT& mu = muFELIX(cell,qp);
00122 ScalarT strs00 = 2.0*mu*(2.0*Ugrad(cell,qp,0,0) + Ugrad(cell,qp,1,1));
00123 ScalarT strs11 = 2.0*mu*(2.0*Ugrad(cell,qp,1,1) + Ugrad(cell,qp,0,0));
00124 ScalarT strs01 = mu*(Ugrad(cell,qp,1,0)+ Ugrad(cell,qp,0,1));
00125 ScalarT strs02 = mu*Ugrad(cell,qp,0,2);
00126 ScalarT strs12 = mu*Ugrad(cell,qp,1,2);
00127 for (std::size_t node=0; node < numNodes; ++node) {
00128 Residual(cell,node,0) += strs00*wGradBF(cell,node,qp,0) +
00129 strs01*wGradBF(cell,node,qp,1) +
00130 strs02*wGradBF(cell,node,qp,2);
00131 Residual(cell,node,1) += strs01*wGradBF(cell,node,qp,0) +
00132 strs11*wGradBF(cell,node,qp,1) +
00133 strs12*wGradBF(cell,node,qp,2);
00134 }
00135 }
00136 for (std::size_t qp=0; qp < numQPs; ++qp) {
00137 ScalarT& frc0 = force(cell,qp,0);
00138 ScalarT& frc1 = force(cell,qp,1);
00139 for (std::size_t node=0; node < numNodes; ++node) {
00140 Residual(cell,node,0) += frc0*wBF(cell,node,qp);
00141 Residual(cell,node,1) += frc1*wBF(cell,node,qp);
00142 }
00143 }
00144 } }
00145 else if (eqn_type == POISSON) {
00146 for (std::size_t cell=0; cell < workset.numCells; ++cell) {
00147 for (std::size_t node=0; node < numNodes; ++node) {
00148 for (std::size_t qp=0; qp < numQPs; ++qp) {
00149 Residual(cell,node,0) += Ugrad(cell,qp,0,0)*wGradBF(cell,node,qp,0) +
00150 Ugrad(cell,qp,0,1)*wGradBF(cell,node,qp,1) +
00151 Ugrad(cell,qp,0,2)*wGradBF(cell,node,qp,2) +
00152 force(cell,qp,0)*wBF(cell,node,qp);
00153 }
00154
00155 } } }
00156 }
00157 else {
00158 if (eqn_type == FELIX) {
00159 for (std::size_t cell=0; cell < workset.numCells; ++cell) {
00160 for (std::size_t node=0; node < numNodes; ++node) {
00161 for (std::size_t qp=0; qp < numQPs; ++qp) {
00162 Residual(cell,node,0) += 2.0*muFELIX(cell,qp)*((2.0*Ugrad(cell,qp,0,0) + Ugrad(cell,qp,1,1))*wGradBF(cell,node,qp,0) +
00163 0.5*(Ugrad(cell,qp,0,1) + Ugrad(cell,qp,1,0))*wGradBF(cell,node,qp,1)) +
00164 force(cell,qp,0)*wBF(cell,node,qp);
00165 Residual(cell,node,1) += 2.0*muFELIX(cell,qp)*(0.5*(Ugrad(cell,qp,0,1) + Ugrad(cell,qp,1,0))*wGradBF(cell,node,qp,0) +
00166 (Ugrad(cell,qp,0,0) + 2.0*Ugrad(cell,qp,1,1))*wGradBF(cell,node,qp,1)) + force(cell,qp,1)*wBF(cell,node,qp);
00167 }
00168
00169 } } }
00170 else if (eqn_type == POISSON) {
00171 for (std::size_t cell=0; cell < workset.numCells; ++cell) {
00172 for (std::size_t node=0; node < numNodes; ++node) {
00173 for (std::size_t qp=0; qp < numQPs; ++qp) {
00174 Residual(cell,node,0) += Ugrad(cell,qp,0,0)*wGradBF(cell,node,qp,0) +
00175 Ugrad(cell,qp,0,1)*wGradBF(cell,node,qp,1) +
00176 force(cell,qp,0)*wBF(cell,node,qp);
00177 }
00178
00179 } } }
00180 }
00181 }
00182
00183
00184 }
00185