00001
00002
00003
00004
00005
00006
00007 #include "FELIX_Stokes.hpp"
00008
00009 #include "Intrepid_FieldContainer.hpp"
00010 #include "Intrepid_DefaultCubatureFactory.hpp"
00011 #include "Shards_CellTopology.hpp"
00012 #include "PHAL_FactoryTraits.hpp"
00013 #include "Albany_Utils.hpp"
00014 #include "Albany_ProblemUtils.hpp"
00015
00016 void
00017 FELIX::Stokes::
00018 getVariableType(Teuchos::ParameterList& paramList,
00019 const std::string& defaultType,
00020 FELIX::Stokes::NS_VAR_TYPE& variableType,
00021 bool& haveVariable,
00022 bool& haveEquation)
00023 {
00024 std::string type = paramList.get("Variable Type", defaultType);
00025 if (type == "None")
00026 variableType = NS_VAR_TYPE_NONE;
00027 else if (type == "Constant")
00028 variableType = NS_VAR_TYPE_CONSTANT;
00029 else if (type == "DOF")
00030 variableType = NS_VAR_TYPE_DOF;
00031 else
00032 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
00033 "Unknown variable type " << type << std::endl);
00034 haveVariable = (variableType != NS_VAR_TYPE_NONE);
00035 haveEquation = (variableType == NS_VAR_TYPE_DOF);
00036 }
00037
00038 std::string
00039 FELIX::Stokes::
00040 variableTypeToString(FELIX::Stokes::NS_VAR_TYPE variableType)
00041 {
00042 if (variableType == NS_VAR_TYPE_NONE)
00043 return "None";
00044 else if (variableType == NS_VAR_TYPE_CONSTANT)
00045 return "Constant";
00046 return "DOF";
00047 }
00048
00049 FELIX::Stokes::
00050 Stokes( const Teuchos::RCP<Teuchos::ParameterList>& params_,
00051 const Teuchos::RCP<ParamLib>& paramLib_,
00052 const int numDim_) :
00053 Albany::AbstractProblem(params_, paramLib_),
00054 haveFlow(false),
00055 haveFlowEq(false),
00056 haveSource(false),
00057 havePSPG(false),
00058 numDim(numDim_)
00059 {
00060
00061 getVariableType(params->sublist("Flow"), "DOF", flowType,
00062 haveFlow, haveFlowEq);
00063
00064 if (haveFlowEq) {
00065 havePSPG = params->get("Have Pressure Stabilization", true);
00066 }
00067
00068 haveSource = true;
00069
00070
00071
00072
00073 int num_eq = 0;
00074 if (haveFlowEq) num_eq += numDim+1;
00075 this->setNumEquations(num_eq);
00076
00077
00078 this->requirements.push_back("Surface Height");
00079 this->requirements.push_back("Temperature");
00080 this->requirements.push_back("Basal Friction");
00081 this->requirements.push_back("Thickness");
00082 this->requirements.push_back("Flow Factor");
00083
00084
00085 *out << "Stokes problem:" << std::endl
00086 << "\tSpatial dimension: " << numDim << std::endl
00087 << "\tFlow variables: " << variableTypeToString(flowType)
00088 << std::endl
00089 << "\tPressure stabilization: " << havePSPG << std::endl;
00090 }
00091
00092 FELIX::Stokes::
00093 ~Stokes()
00094 {
00095 }
00096
00097 void
00098 FELIX::Stokes::
00099 buildProblem(
00100 Teuchos::ArrayRCP<Teuchos::RCP<Albany::MeshSpecsStruct> > meshSpecs,
00101 Albany::StateManager& stateMgr)
00102 {
00103 using Teuchos::rcp;
00104
00105
00106 TEUCHOS_TEST_FOR_EXCEPTION(meshSpecs.size()!=1,std::logic_error,"Problem supports one Material Block");
00107 fm.resize(1);
00108 fm[0] = rcp(new PHX::FieldManager<PHAL::AlbanyTraits>);
00109 buildEvaluators(*fm[0], *meshSpecs[0], stateMgr, Albany::BUILD_RESID_FM,
00110 Teuchos::null);
00111 constructDirichletEvaluators(*meshSpecs[0]);
00112
00113 constructNeumannEvaluators(meshSpecs[0]);
00114 }
00115
00116 Teuchos::Array< Teuchos::RCP<const PHX::FieldTag> >
00117 FELIX::Stokes::
00118 buildEvaluators(
00119 PHX::FieldManager<PHAL::AlbanyTraits>& fm0,
00120 const Albany::MeshSpecsStruct& meshSpecs,
00121 Albany::StateManager& stateMgr,
00122 Albany::FieldManagerChoice fmchoice,
00123 const Teuchos::RCP<Teuchos::ParameterList>& responseList)
00124 {
00125
00126
00127 Albany::ConstructEvaluatorsOp<Stokes> op(
00128 *this, fm0, meshSpecs, stateMgr, fmchoice, responseList);
00129 boost::mpl::for_each<PHAL::AlbanyTraits::BEvalTypes>(op);
00130 return *op.tags;
00131 }
00132
00133 void
00134 FELIX::Stokes::constructDirichletEvaluators(
00135 const Albany::MeshSpecsStruct& meshSpecs)
00136 {
00137
00138 std::vector<std::string> dirichletNames(neq);
00139 int index = 0;
00140 if (haveFlowEq) {
00141 dirichletNames[index++] = "ux";
00142 if (numDim>=2) dirichletNames[index++] = "uy";
00143 if (numDim==3) dirichletNames[index++] = "uz";
00144 dirichletNames[index++] = "p";
00145 }
00146 Albany::BCUtils<Albany::DirichletTraits> dirUtils;
00147 dfm = dirUtils.constructBCEvaluators(meshSpecs.nsNames, dirichletNames,
00148 this->params, this->paramLib);
00149 }
00150
00151
00152 void
00153 FELIX::Stokes::constructNeumannEvaluators(const Teuchos::RCP<Albany::MeshSpecsStruct>& meshSpecs)
00154 {
00155
00156
00157
00158
00159 Albany::BCUtils<Albany::NeumannTraits> nbcUtils;
00160
00161
00162
00163 if(!nbcUtils.haveBCSpecified(this->params)) {
00164 return;
00165 }
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177 std::vector<std::string> nbcNames;
00178 Teuchos::RCP< Teuchos::Array<std::string> > dof_names =
00179 Teuchos::rcp(new Teuchos::Array<std::string>);
00180 Teuchos::Array<Teuchos::Array<int> > offsets;
00181 int idx = 0;
00182 if (haveFlowEq) {
00183 nbcNames.push_back("ux");
00184 offsets.push_back(Teuchos::Array<int>(1,idx++));
00185 if (numDim>=2) {
00186 nbcNames.push_back("uy");
00187 offsets.push_back(Teuchos::Array<int>(1,idx++));
00188 }
00189 if (numDim==3) {
00190 nbcNames.push_back("uz");
00191 offsets.push_back(Teuchos::Array<int>(1,idx++));
00192 }
00193 nbcNames.push_back("p");
00194 offsets.push_back(Teuchos::Array<int>(1,idx++));
00195 dof_names->push_back("Velocity");
00196 dof_names->push_back("Pressure");
00197 }
00198
00199
00200
00201 std::vector<std::string> condNames(3);
00202
00203
00204
00205 if(numDim == 2)
00206 condNames[0] = "(dudx, dudy)";
00207 else if(numDim == 3)
00208 condNames[0] = "(dudx, dudy, dudz)";
00209 else
00210 TEUCHOS_TEST_FOR_EXCEPTION(true, Teuchos::Exceptions::InvalidParameter,
00211 std::endl << "Error: Sidesets only supported in 2 and 3D." << std::endl);
00212
00213 condNames[1] = "dudn";
00214
00215 condNames[2] = "basal";
00216
00217 nfm.resize(1);
00218
00219
00220 nfm[0] = nbcUtils.constructBCEvaluators(meshSpecs, nbcNames,
00221 Teuchos::arcp(dof_names),
00222 true, 0, condNames, offsets, dl,
00223 this->params, this->paramLib);
00224 }
00225
00226
00227
00228 Teuchos::RCP<const Teuchos::ParameterList>
00229 FELIX::Stokes::getValidProblemParameters() const
00230 {
00231 Teuchos::RCP<Teuchos::ParameterList> validPL =
00232 this->getGenericProblemParams("ValidStokesParams");
00233
00234 validPL->set<bool>("Have Pressure Stabilization", true);
00235 validPL->sublist("Flow", false, "");
00236 validPL->sublist("Density", false, "");
00237 validPL->sublist("Viscosity", false, "");
00238 validPL->sublist("FELIX Viscosity", false, "");
00239 validPL->sublist("Tau M", false, "");
00240 validPL->sublist("Body Force", false, "");
00241
00242 return validPL;
00243 }
00244