1 #ifndef VERTEXCFD_EQUATIONSET_FULLINDUCTIONMHD_IMPL_HPP
2 #define VERTEXCFD_EQUATIONSET_FULLINDUCTIONMHD_IMPL_HPP
4 #include <Panzer_BasisIRLayout.hpp>
5 #include <Panzer_IntegrationRule.hpp>
7 #include <Panzer_Integrator_BasisTimesScalar.hpp>
8 #include <Panzer_Integrator_GradBasisDotVector.hpp>
10 #include <Phalanx_FieldManager.hpp>
12 #include <Teuchos_ParameterList.hpp>
13 #include <Teuchos_RCP.hpp>
14 #include <Teuchos_StandardParameterEntryValidators.hpp>
21 template<
class EvalType>
22 FullInductionMHD<EvalType>::FullInductionMHD(
23 const Teuchos::RCP<Teuchos::ParameterList>& params,
24 const int& default_integration_order,
25 const panzer::CellData& cell_data,
26 const Teuchos::RCP<panzer::GlobalData>& global_data,
27 const bool build_transient_support)
28 : panzer::EquationSet_DefaultImpl<EvalType>(params,
29 default_integration_order,
32 build_transient_support)
35 if (!this->buildTransientSupport())
37 throw std::logic_error(
38 "Transient support is required for solving all equation sets.");
42 _num_space_dim = cell_data.baseCellDimension();
43 if (!(_num_space_dim == 2 || _num_space_dim == 3))
45 throw std::runtime_error(
"Number of space dimensions not supported");
49 const bool fluid_mhd = params->get<std::string>(
"Type")
50 ==
"FullInductionMHD";
53 Teuchos::ParameterList valid_parameters;
54 this->setDefaultValidParameters(valid_parameters);
56 "Model ID",
"",
"Closure model id associated with this equation set");
57 valid_parameters.set(
"Basis Order", 1,
"Order of the basis");
58 valid_parameters.set(
"Integration Order", 2,
"Order of the integration");
60 "Build Resistive Flux",
false,
"Resistive flux boolean");
61 valid_parameters.set(
"Build Induction Constant Source",
63 "Induction equation constant source boolean");
64 valid_parameters.set(
"Build Magnetic Correction Potential Equation",
66 "Solve full induction equation with divergence "
70 valid_parameters.set(
"Build Divergence Cleaning Source",
72 "Divergence cleaning source boolean");
73 valid_parameters.set(
"Build Godunov-Powell Source",
75 "Godunov-Powell source boolean");
77 valid_parameters.set(
"Build Magnetic Correction Damping Source",
79 "Magnetic Correction damping source boolean");
80 params->validateParametersAndSetDefaults(valid_parameters);
83 const int basis_order = params->get<
int>(
"Basis Order", 1);
84 const int integration_order
85 = params->get<
int>(
"Integration Order", basis_order + 1);
86 const std::string model_id = params->get<std::string>(
"Model ID");
87 const bool build_ind_equ_const_source
88 = params->get<
bool>(
"Build Induction Constant Source");
89 const bool build_magn_corr
90 = params->get<
bool>(
"Build Magnetic Correction Potential Equation");
91 _build_resistive_flux = params->get<
bool>(
"Build Resistive Flux");
92 const bool build_div_cleaning_src
93 = fluid_mhd ? params->get<
bool>(
"Build Divergence Cleaning Source")
95 const bool build_godunov_powell_source
96 = fluid_mhd ? params->get<
bool>(
"Build Godunov-Powell Source") :
false;
97 const bool build_magn_corr_damping_src
98 = params->get<
bool>(
"Build Magnetic Correction Damping Source");
102 _build_convective_flux = fluid_mhd || build_magn_corr;
105 for (
int d = 0; d < _num_space_dim; ++d)
107 const std::string ds = std::to_string(d);
108 _equ_dof_fim_pair.insert(
109 {
"induction_" + ds,
"induced_magnetic_field_" + ds});
114 _equ_dof_fim_pair.insert(
115 {
"magnetic_correction_potential",
"scalar_magnetic_potential"});
120 = [&,
this](
const std::string& equ_name,
const std::string& dof_name) {
121 const std::string residual_name =
"RESIDUAL_" + equ_name;
122 const std::string scatter_name =
"SCATTER_" + equ_name;
123 const std::string basis_type =
"HGrad";
124 this->addDOF(dof_name,
130 this->addDOFGrad(dof_name);
131 this->addDOFTimeDerivative(dof_name);
135 for (
auto it : _equ_dof_fim_pair)
137 const auto equ_name = it.first;
138 const auto dof_name = it.second;
139 set_dofs(equ_name, dof_name);
141 if (std::string::npos != equ_name.find(
"induction"))
143 std::unordered_map<std::string, bool> source_term;
145 {
"GODUNOV_POWELL_SOURCE", build_godunov_powell_source});
146 source_term.insert({
"CONSTANT_SOURCE", build_ind_equ_const_source});
147 _equ_source_term.insert({equ_name, source_term});
149 if (std::string::npos != equ_name.find(
"magnetic_correction"))
151 std::unordered_map<std::string, bool> source_term;
152 source_term.insert({
"DIV_CLEANING_SOURCE", build_div_cleaning_src});
153 source_term.insert({
"DAMPING_SOURCE", build_magn_corr_damping_src});
154 _equ_source_term.insert({equ_name, source_term});
159 this->addClosureModel(model_id);
164 template<
class EvalType>
165 void FullInductionMHD<EvalType>::buildAndRegisterEquationSetEvaluators(
166 PHX::FieldManager<panzer::Traits>& fm,
167 const panzer::FieldLibrary&,
168 const Teuchos::ParameterList&)
const
172 const auto it = _equ_dof_fim_pair.find(
"induction_0");
173 const auto ir = this->getIntRuleForDOF(it->second);
174 const auto basis = this->getBasisIRLayoutForDOF(it->second);
177 auto add_basis_time_scalar_residual = [&,
this](
178 const std::string& equ_name,
179 const std::string& residual_name,
180 const double& multiplier,
181 std::vector<std::string>& op_names) {
182 const std::string closure_model_residual = residual_name +
"_"
184 const std::string full_residual =
"RESIDUAL_" + closure_model_residual;
185 auto op = Teuchos::rcp(
186 new panzer::Integrator_BasisTimesScalar<EvalType, panzer::Traits>(
187 panzer::EvaluatorStyle::EVALUATES,
189 closure_model_residual,
193 this->
template registerEvaluator<EvalType>(fm, op);
194 op_names.push_back(full_residual);
198 auto add_grad_basis_time_residual = [&,
this](
199 const std::string& equ_name,
200 const std::string& residual_name,
201 const double& multiplier,
202 std::vector<std::string>& op_names) {
203 const std::string closure_model_residual = residual_name +
"_"
205 const std::string full_residual =
"RESIDUAL_" + closure_model_residual;
206 auto op = Teuchos::rcp(
207 new panzer::Integrator_GradBasisDotVector<EvalType, panzer::Traits>(
208 panzer::EvaluatorStyle::EVALUATES,
210 closure_model_residual,
214 this->
template registerEvaluator<EvalType>(fm, op);
215 op_names.push_back(full_residual);
219 for (
auto it : _equ_dof_fim_pair)
222 const auto eq_name = it.first;
223 const auto dof_name = it.second;
224 std::vector<std::string> residual_operator_names;
227 add_basis_time_scalar_residual(
228 eq_name,
"DQDT", 1.0, residual_operator_names);
231 if (_build_convective_flux)
233 add_grad_basis_time_residual(
234 eq_name,
"CONVECTIVE_FLUX", -1.0, residual_operator_names);
238 if (_build_resistive_flux)
240 add_grad_basis_time_residual(
241 eq_name,
"RESISTIVE_FLUX", 1.0, residual_operator_names);
245 for (
const auto& [src_name, add_src] : _equ_source_term.at(eq_name))
249 add_basis_time_scalar_residual(
250 eq_name, src_name, -1.0, residual_operator_names);
255 this->buildAndRegisterResidualSummationEvaluator(
256 fm, dof_name, residual_operator_names,
"RESIDUAL_" + eq_name);
265 #endif // end VERTEXCFD_EQUATIONSET_FULLINDUCTIONMHD_IMPL_HPP