1 #ifndef VERTEXCFD_BOUNDARYCONDITION_BOUNDARYFLUXBASE_IMPL_HPP
2 #define VERTEXCFD_BOUNDARYCONDITION_BOUNDARYFLUXBASE_IMPL_HPP
4 #include "VertexCFD_BoundaryState_ViscousGradient.hpp"
5 #include "VertexCFD_BoundaryState_ViscousPenaltyParameter.hpp"
6 #include "VertexCFD_Integrator_BoundaryGradBasisDotVector.hpp"
8 #include <Panzer_DOF.hpp>
9 #include <Panzer_DOFGradient.hpp>
10 #include <Panzer_DotProduct.hpp>
11 #include <Panzer_Integrator_BasisTimesScalar.hpp>
12 #include <Panzer_Normals.hpp>
13 #include <Panzer_Sum.hpp>
15 #include <Phalanx_DataLayout.hpp>
16 #include <Phalanx_DataLayout_MDALayout.hpp>
17 #include <Phalanx_MDField.hpp>
25 namespace BoundaryCondition
28 template<
class EvalType,
int NumSpaceDim>
29 BoundaryFluxBase<EvalType, NumSpaceDim>::BoundaryFluxBase(
30 const panzer::BC& bc,
const Teuchos::RCP<panzer::GlobalData>& global_data)
31 : panzer::BCStrategy<EvalType>(bc)
32 , panzer::GlobalDataAcceptorDefaultImpl(global_data)
35 bnd_prefix.insert({
"BOUNDARY_",
"BOUNDARY_"});
36 bnd_prefix.insert({
"PENALTY_BOUNDARY_",
"PENALTY_"});
37 bnd_prefix.insert({
"SYMMETRY_BOUNDARY_",
"SYMMETRY_"});
42 template<
class EvalType,
int NumSpaceDim>
44 const panzer::PhysicsBlock& side_pb,
45 std::unordered_map<std::string, std::string>& )
48 const auto& irules = side_pb.getIntegrationRules();
49 int integration_order = 0;
50 for (
const auto& pair : irules)
52 integration_order = std::max(integration_order, pair.second->order());
57 new panzer::IntegrationRule(integration_order, side_pb.cellData()));
60 const auto& dof_basis_pair = side_pb.getProvidedDOFs();
61 for (
const auto& dof_basis : dof_basis_pair)
63 _dof_basis_pair.insert({dof_basis.first, dof_basis.second});
64 const Teuchos::RCP<panzer::IntegrationRule> ir = Teuchos::rcp(
65 new panzer::IntegrationRule(integration_order, side_pb.cellData()));
73 template<
class EvalType,
int NumSpaceDim>
75 const Teuchos::ParameterList& bc_params,
76 const panzer::PhysicsBlock& side_pb,
77 std::string& model_id,
78 Teuchos::ParameterList& side_pb_list)
const
80 if (bc_params.isType<std::string>(
"Model ID"))
84 model_id = bc_params.get<std::string>(
"Model ID");
85 for (
auto itr = side_pb.getParameterList()->begin();
86 itr != side_pb.getParameterList()->end();
90 = Teuchos::getValue<Teuchos::ParameterList>(itr->second);
91 if (sublist.get<std::string>(
"Model ID") == model_id)
93 side_pb_list = sublist;
97 else if (side_pb.getParameterList()->numParams() != 1)
100 =
"\n\nERROR: Multiple equation sets are being solved on a single "
101 "block but `Model ID` is not being specified in the "
102 "corresponding boundary condition lists.\n\n";
103 throw std::runtime_error(msg);
108 = side_pb.getParameterList()->sublist(
"child0").get<std::string>(
110 side_pb_list = side_pb.getParameterList()->sublist(
"child0");
116 template<
class EvalType,
int NumSpaceDim>
118 const panzer::PhysicsBlock& ,
const std::string& dof_name)
const
120 const Teuchos::RCP<panzer::PureBasis> basis = _dof_basis_pair.at(dof_name);
122 return panzer::basisIRLayout(basis, *_ir);
127 template<
class EvalType,
int NumSpaceDim>
129 PHX::FieldManager<panzer::Traits>& fm,
130 const panzer::PhysicsBlock& side_pb,
131 const std::string& dof_name)
const
134 const auto basis_layout = this->getBasisIRLayout(side_pb, dof_name);
135 Teuchos::ParameterList dof_params;
136 dof_params.set<std::string>(
"Name", dof_name);
137 dof_params.set<Teuchos::RCP<panzer::BasisIRLayout>>(
"Basis", basis_layout);
138 dof_params.set<Teuchos::RCP<panzer::IntegrationRule>>(
"IR", _ir);
140 = Teuchos::rcp(
new panzer::DOF<EvalType, panzer::Traits>(dof_params));
141 this->
template registerEvaluator<EvalType>(fm, dof_op);
144 dof_params.set<std::string>(
"Gradient Name",
"GRAD_" + dof_name);
145 const auto gd_op = Teuchos::rcp(
146 new panzer::DOFGradient<EvalType, panzer::Traits>(dof_params));
147 this->
template registerEvaluator<EvalType>(fm, gd_op);
152 template<
class EvalType,
int NumSpaceDim>
153 void BoundaryFluxBase<EvalType, NumSpaceDim>::registerSideNormals(
154 PHX::FieldManager<panzer::Traits>& fm,
155 const panzer::PhysicsBlock& side_pb)
const
157 std::stringstream normal_params_name;
158 normal_params_name <<
"Side Normal:" << side_pb.cellData().side();
159 Teuchos::ParameterList normal_params(normal_params_name.str());
160 normal_params.set<std::string>(
"Name",
"Side Normal");
161 normal_params.set<
int>(
"Side ID", side_pb.cellData().side());
162 normal_params.set<Teuchos::RCP<panzer::IntegrationRule>>(
"IR", _ir);
163 normal_params.set<
bool>(
"Normalize",
true);
164 const auto normal_op = Teuchos::rcp(
165 new panzer::Normals<EvalType, panzer::Traits>(normal_params));
166 this->
template registerEvaluator<EvalType>(fm, normal_op);
170 template<
class EvalType,
int NumSpaceDim>
171 void BoundaryFluxBase<EvalType, NumSpaceDim>::registerConvectionTypeFluxOperator(
172 std::pair<const std::string, std::string> dof_eq_pair,
173 std::unordered_map<std::string, std::vector<std::string>>& eq_res_map,
174 const std::string& closure_name,
175 PHX::FieldManager<panzer::Traits>& fm,
176 const panzer::PhysicsBlock& side_pb,
177 const double& multiplier)
const
180 const std::string eq_name = dof_eq_pair.first;
181 const std::string dof_name = dof_eq_pair.second;
182 const std::string normal_dot_name =
"Normal Dot Flux " + eq_name;
185 const std::string flux_name =
"BOUNDARY_" + closure_name +
"_FLUX_"
187 const auto normal_dot_flux_op
188 = panzer::buildEvaluator_DotProduct<EvalType, panzer::Traits>(
189 normal_dot_name, *_ir,
"Side Normal", flux_name);
190 this->
template registerEvaluator<EvalType>(fm, normal_dot_flux_op);
193 const auto basis_layout = this->getBasisIRLayout(side_pb, dof_name);
194 const std::string residual_name = closure_name +
"_BOUNDARY_RESIDUAL_"
196 const auto convective_flux_op = Teuchos::rcp(
197 new panzer::Integrator_BasisTimesScalar<EvalType, panzer::Traits>(
198 panzer::EvaluatorStyle::EVALUATES,
204 this->
template registerEvaluator<EvalType>(fm, convective_flux_op);
207 eq_res_map[eq_name].push_back(residual_name);
212 template<
class EvalType,
int NumSpaceDim>
213 void BoundaryFluxBase<EvalType, NumSpaceDim>::registerPenaltyAndViscousGradientOperator(
214 std::pair<const std::string, std::string> dof_eq_pair,
215 PHX::FieldManager<panzer::Traits>& fm,
216 const panzer::PhysicsBlock& side_pb,
217 const Teuchos::ParameterList& bc_params)
const
220 const std::string eq_name = dof_eq_pair.first;
221 const std::string dof_name = dof_eq_pair.second;
222 const auto basis_layout = this->getBasisIRLayout(side_pb, dof_name);
225 double penalty = 10.0;
228 if (dof_name ==
"temperature")
231 if (bc_params.isSublist(
"Penalty Parameters"))
233 const auto penalty_list = bc_params.sublist(
"Penalty Parameters");
234 if (penalty_list.isType<
double>(dof_name))
236 penalty = penalty_list.get<
double>(dof_name);
241 const auto viscous_penalty_op
242 = Teuchos::rcp(
new ViscousPenaltyParameter<EvalType, panzer::Traits>(
243 *_ir, *(basis_layout->getBasis()), dof_name, penalty));
244 this->
template registerEvaluator<EvalType>(fm, viscous_penalty_op);
247 const auto viscous_gradient_op = Teuchos::rcp(
248 new ViscousGradient<EvalType, panzer::Traits>(*_ir, dof_name));
249 this->
template registerEvaluator<EvalType>(fm, viscous_gradient_op);
254 template<
class EvalType,
int NumSpaceDim>
255 void BoundaryFluxBase<EvalType, NumSpaceDim>::registerViscousTypeFluxOperator(
256 std::pair<const std::string, std::string> dof_eq_pair,
257 std::unordered_map<std::string, std::vector<std::string>>& eq_res_map,
258 const std::string closure_name,
259 PHX::FieldManager<panzer::Traits>& fm,
260 const panzer::PhysicsBlock& side_pb,
261 const double& multiplier)
const
263 const std::string eq_name = dof_eq_pair.first;
264 const std::string dof_name = dof_eq_pair.second;
265 const auto basis_layout = this->getBasisIRLayout(side_pb, dof_name);
270 const std::string normal_dot_viscous_name =
"Normal Dot " + closure_name
271 +
" Flux " + eq_name;
272 const std::string flux_name =
"BOUNDARY_" + closure_name +
"_FLUX_"
274 auto normal_dot_viscous_flux_op
275 = panzer::buildEvaluator_DotProduct<EvalType, panzer::Traits>(
276 normal_dot_viscous_name, *_ir,
"Side Normal", flux_name);
277 this->
template registerEvaluator<EvalType>(fm, normal_dot_viscous_flux_op);
279 const std::string bnd_resid = closure_name +
"_BOUNDARY_RESIDUAL_"
281 auto bnd_op = Teuchos::rcp(
282 new panzer::Integrator_BasisTimesScalar<EvalType, panzer::Traits>(
283 panzer::EvaluatorStyle::EVALUATES,
285 normal_dot_viscous_name,
289 this->
template registerEvaluator<EvalType>(fm, bnd_op);
290 eq_res_map[eq_name].push_back(bnd_resid);
293 const std::string penalty_bnd_resid =
"PENALTY_BOUNDARY_RESIDUAL_"
295 auto bnd_penalty_op = Teuchos::rcp(
296 new Integrator::BoundaryGradBasisDotVector<EvalType, panzer::Traits>(
297 panzer::EvaluatorStyle::EVALUATES,
299 "PENALTY_BOUNDARY_" + closure_name +
"_FLUX_" + eq_name,
303 this->
template registerEvaluator<EvalType>(fm, bnd_penalty_op);
304 eq_res_map[eq_name].push_back(penalty_bnd_resid);
309 const std::string normal_dot_scaled_penalty_viscous_name
310 =
"Normal Dot Scaled Penalty " + closure_name +
" Flux " + eq_name;
311 const std::string scaled_penalty_flux_name
312 =
"SYMMETRY_BOUNDARY_" + closure_name +
"_FLUX_" + eq_name;
313 auto normal_dot_scaled_penalty_viscous_flux_op
314 = panzer::buildEvaluator_DotProduct<EvalType, panzer::Traits>(
315 normal_dot_scaled_penalty_viscous_name,
318 scaled_penalty_flux_name);
319 this->
template registerEvaluator<EvalType>(
320 fm, normal_dot_scaled_penalty_viscous_flux_op);
322 const std::string scaled_penalty_bnd_resid =
"SYMMETRY_BOUNDARY_RESIDUAL_"
324 auto scaled_bnd_penalty_op = Teuchos::rcp(
325 new panzer::Integrator_BasisTimesScalar<EvalType, panzer::Traits>(
326 panzer::EvaluatorStyle::EVALUATES,
327 scaled_penalty_bnd_resid,
328 normal_dot_scaled_penalty_viscous_name,
332 this->
template registerEvaluator<EvalType>(fm, scaled_bnd_penalty_op);
333 eq_res_map[eq_name].push_back(scaled_penalty_bnd_resid);
338 template<
class EvalType,
int NumSpaceDim>
339 void BoundaryFluxBase<EvalType, NumSpaceDim>::registerResidual(
340 std::pair<const std::string, std::string> dof_eq_pair,
341 std::unordered_map<std::string, std::vector<std::string>>& eq_res_map,
342 PHX::FieldManager<panzer::Traits>& fm,
343 const panzer::PhysicsBlock& side_pb)
const
346 const std::string eq_name = dof_eq_pair.first;
347 const std::string dof_name = dof_eq_pair.second;
348 const auto basis_layout = this->getBasisIRLayout(side_pb, dof_name);
351 auto residuals = Teuchos::rcp(
new std::vector<std::string>);
352 for (
auto& res : eq_res_map[eq_name])
353 residuals->push_back(res);
356 Teuchos::ParameterList sum_params;
357 sum_params.set(
"Sum Name",
"BOUNDARY_RESIDUAL_" + eq_name);
358 sum_params.set(
"Values Names", residuals);
359 sum_params.set(
"Data Layout", basis_layout->getBasis()->functional);
360 auto sum_op = Teuchos::rcp(
361 new panzer::SumStatic<EvalType, panzer::Traits, panzer::Cell, panzer::BASIS>(
363 this->
template registerEvaluator<EvalType>(fm, sum_op);
368 template<
class EvalType,
int NumSpaceDim>
370 std::pair<const std::string, std::string> dof_eq_pair,
371 PHX::FieldManager<panzer::Traits>& fm,
372 const panzer::PhysicsBlock& ,
373 const panzer::LinearObjFactory<panzer::Traits>& lof)
const
375 const std::string& eq_name = dof_eq_pair.first;
376 const std::string& dof_name = dof_eq_pair.second;
377 const Teuchos::RCP<const panzer::PureBasis> basis
378 = _dof_basis_pair.at(dof_name);
380 const std::string residual_name =
"BOUNDARY_RESIDUAL_" + eq_name;
381 Teuchos::ParameterList p(
"Scatter: " + residual_name +
" to " + eq_name);
383 const std::string scatter_field_name
384 =
"Dummy Scatter: " + this->m_bc.identifier() + residual_name;
385 p.set(
"Scatter Name", scatter_field_name);
386 p.set(
"Basis", basis);
388 auto residual_names = Teuchos::rcp(
new std::vector<std::string>);
389 residual_names->push_back(residual_name);
390 p.set(
"Dependent Names", residual_names);
392 auto names_map = Teuchos::rcp(
new std::map<std::string, std::string>);
394 std::pair<std::string, std::string>(residual_name, dof_name));
395 p.set(
"Dependent Map", names_map);
397 auto scatter_op = lof.buildScatter<EvalType>(p);
399 this->
template registerEvaluator<EvalType>(fm, scatter_op);
402 auto dummy_layout = Teuchos::rcp(
new PHX::MDALayout<panzer::Dummy>(0));
403 const PHX::Tag<typename EvalType::ScalarT> tag(scatter_field_name,
405 fm.template requireField<EvalType>(tag);
412 #endif // end VERTEXCFD_BOUNDARYCONDITION_BOUNDARYFLUXBASE_IMPL_HPP