VertexCFD  0.0-dev
VertexCFD_EquationSet_Conduction_impl.hpp
1 #ifndef VERTEXCFD_EQUATIONSET_CONDUCTION_IMPL_HPP
2 #define VERTEXCFD_EQUATIONSET_CONDUCTION_IMPL_HPP
3 
4 #include <Panzer_BasisIRLayout.hpp>
5 #include <Panzer_EvaluatorStyle.hpp>
6 #include <Panzer_IntegrationRule.hpp>
7 #include <Panzer_Integrator_BasisTimesScalar.hpp>
8 #include <Panzer_Integrator_GradBasisDotVector.hpp>
9 
10 #include <stdexcept>
11 #include <vector>
12 
13 namespace VertexCFD
14 {
15 namespace EquationSet
16 {
17 //---------------------------------------------------------------------------//
18 template<class EvalType>
19 Conduction<EvalType>::Conduction(
20  const Teuchos::RCP<Teuchos::ParameterList>& params,
21  const int& default_integration_order,
22  const panzer::CellData& cell_data,
23  const Teuchos::RCP<panzer::GlobalData>& global_data,
24  const bool build_transient_support)
25  : panzer::EquationSet_DefaultImpl<EvalType>(params,
26  default_integration_order,
27  cell_data,
28  global_data,
29  build_transient_support)
30  , _dof_name("temperature")
31  , _equ_name("energy")
32 {
33  // This equation set need not always be transient. Could solve Poisson
34  if (!this->buildTransientSupport())
35  {
36  throw std::logic_error(
37  "Conduction equation requires transient support");
38  }
39 
40  // Set default parameter values and validate the inputs.
41  Teuchos::ParameterList valid_parameters;
42  this->setDefaultValidParameters(valid_parameters);
43  valid_parameters.set(
44  "Model ID", "", "Closure model id associated with this equation set");
45  valid_parameters.set("Basis Order", 1, "Order of the basis");
46  valid_parameters.set("Integration Order", 2, "Order of the integration");
47  valid_parameters.set(
48  "Build Source Residual", false, "Build source residual");
49  params->validateParametersAndSetDefaults(valid_parameters);
50 
51  // Extract parameters.
52  const int basis_order = params->get<int>("Basis Order", 1);
53  const int integration_order
54  = params->get<int>("Integration Order", basis_order + 1);
55  const auto model_id = params->get<std::string>("Model ID");
56  _build_source_term = params->get<bool>("Build Source Residual");
57 
58  // Set up degrees of freedom for conduction equation
59  const std::string residual_name = "RESIDUAL_" + _equ_name;
60  const std::string scatter_name = "SCATTER_" + _equ_name;
61  const std::string basis_type = "HGrad";
62  this->addDOF(_dof_name,
63  basis_type,
64  basis_order,
65  integration_order,
66  residual_name,
67  scatter_name);
68  this->addDOFGrad(_dof_name);
69  if (this->buildTransientSupport())
70  {
71  this->addDOFTimeDerivative(_dof_name);
72  }
73 
74  // Add closure models and set-up DOFs
75  this->addClosureModel(model_id);
76  this->setupDOFs();
77 }
78 
79 //---------------------------------------------------------------------------//
80 template<class EvalType>
81 void Conduction<EvalType>::buildAndRegisterEquationSetEvaluators(
82  PHX::FieldManager<panzer::Traits>& fm,
83  const panzer::FieldLibrary&,
84  const Teuchos::ParameterList&) const
85 {
86  // Get integration rule and basis function for field
87  const auto ir = this->getIntRuleForDOF(_dof_name);
88  const auto basis = this->getBasisIRLayoutForDOF(_dof_name);
89 
90  // Add basis time residuals
91  auto add_basis_time_scalar_residual = [&, this](
92  const std::string& equ_name,
93  const std::string& residual_name,
94  const double& multiplier,
95  std::vector<std::string>& op_names) {
96  const std::string closure_model_residual = residual_name + "_"
97  + equ_name;
98  const std::string full_residual = "RESIDUAL_" + closure_model_residual;
99  auto op = Teuchos::rcp(
100  new panzer::Integrator_BasisTimesScalar<EvalType, panzer::Traits>(
101  panzer::EvaluatorStyle::EVALUATES,
102  full_residual,
103  closure_model_residual,
104  *basis,
105  *ir,
106  multiplier));
107  this->template registerEvaluator<EvalType>(fm, op);
108  op_names.push_back(full_residual);
109  };
110 
111  // Add grad-basis time residuals
112  auto add_grad_basis_time_residual = [&, this](
113  const std::string& equ_name,
114  const std::string& residual_name,
115  const double& multiplier,
116  std::vector<std::string>& op_names) {
117  const std::string closure_model_residual = residual_name + "_"
118  + equ_name;
119  const std::string full_residual = "RESIDUAL_" + closure_model_residual;
120  auto op = Teuchos::rcp(
121  new panzer::Integrator_GradBasisDotVector<EvalType, panzer::Traits>(
122  panzer::EvaluatorStyle::EVALUATES,
123  full_residual,
124  closure_model_residual,
125  *basis,
126  *ir,
127  multiplier));
128  this->template registerEvaluator<EvalType>(fm, op);
129  op_names.push_back(full_residual);
130  };
131 
132  // Collect each term for residual to form conduction equation
133  std::vector<std::string> residual_operator_names;
134 
135  // Time derivative residual
136  add_basis_time_scalar_residual(
137  _equ_name, "DQDT", 1.0, residual_operator_names);
138 
139  // Second-order flux: heat flux
140  add_grad_basis_time_residual(
141  _equ_name, "CONDUCTION_FLUX", 1.0, residual_operator_names);
142 
143  // Source term
144  if (_build_source_term)
145  {
146  add_basis_time_scalar_residual(
147  _equ_name, "SOURCE", -1.0, residual_operator_names);
148  }
149 
150  // Build total residual for conduction equation
151  this->buildAndRegisterResidualSummationEvaluator(
152  fm, _dof_name, residual_operator_names, "RESIDUAL_energy");
153 }
154 
155 //---------------------------------------------------------------------------/
156 template<class EvalType>
157 std::string Conduction<EvalType>::fieldName(const int dof) const
158 {
159  if (dof > 0)
160  {
161  throw std::logic_error("Conduction equation contributes a single DOF");
162  }
163 
164  return _dof_name;
165 }
166 
167 //---------------------------------------------------------------------------//
168 
169 } // end namespace EquationSet
170 } // end namespace VertexCFD
171 
172 #endif // end VERTEXCFD_EQUATIONSET_CONDUCTION_IMPL_HPP
VertexCFD
Definition: tstMethodManufacturedSolutionBC.cpp:23