https://mooseframework.inl.gov
Loading...
Searching...
No Matches
DiffusionCG.C
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
3//*
4//* All rights reserved, see COPYRIGHT for full restrictions
5//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6//*
7//* Licensed under LGPL 2.1, please see LICENSE for details
8//* https://www.gnu.org/licenses/lgpl-2.1.html
9
10#include "DiffusionCG.h"
11#include "MooseVariableBase.h"
12
13// Register the actions for the objects actually used
15registerMooseAction("MooseApp", DiffusionCG, "add_kernel");
16registerMooseAction("MooseApp", DiffusionCG, "add_bc");
17registerMooseAction("MooseApp", DiffusionCG, "add_variables_physics");
18
21{
24 "Discretizes a diffusion equation with the continuous Galerkin finite element method");
25 params.addParam<bool>(
26 "use_automatic_differentiation",
27 true,
28 "Whether to use automatic differentiation for all the terms in the equation");
29 params.transferParam<MooseEnum>(MooseVariableBase::validParams(), "order", "variable_order");
30 params.addParam<MaterialPropertyName>("source_matprop", "Source term in the diffusion problem");
31
32 return params;
33}
34
36 : PhysicsBase(parameters),
37 PhysicsComponentInterface(parameters),
38 DiffusionPhysicsBase(parameters),
39 _use_ad(getParam<bool>("use_automatic_differentiation"))
40{
41 checkAtMostOneParamSetByUser({"source_functor", "source_matprop"});
42}
43
44void
46{
47 // Diffusion term(s)
48 unsigned int num_diffusion_terms = 1;
49 if (isParamValid("diffusivity_matprop"))
50 num_diffusion_terms = getParam<std::vector<MaterialPropertyName>>("diffusivity_matprop").size();
51 else if (isParamValid("diffusivity_functor"))
52 num_diffusion_terms = getParam<std::vector<MooseFunctorName>>("diffusivity_functor").size();
53
54 for (const auto i_diff_block_group : make_range(num_diffusion_terms))
55 {
56 // Select the kernel type based on the user parameters
57 std::string kernel_type;
58 if (isParamValid("diffusivity_matprop"))
59 kernel_type = _use_ad ? "ADMatDiffusion" : "MatDiffusion";
60 else if (isParamValid("diffusivity_functor"))
61 {
62 const auto & d =
63 getParam<std::vector<MooseFunctorName>>("diffusivity_functor")[i_diff_block_group];
65 kernel_type = "FunctionDiffusion";
66 else
67 paramError("diffusivity_functor",
68 "No diffusion kernel implemented for the diffusivity type of ",
69 d);
70 }
71 else
72 kernel_type = _use_ad ? "ADDiffusion" : "Diffusion";
73 InputParameters params = getFactory().getValidParams(kernel_type);
74 params.set<NonlinearVariableName>("variable") = _var_name;
75 if (isParamValid("diffusivity_blocks"))
76 assignBlocks(params,
77 getParam<std::vector<std::vector<SubdomainName>>>(
78 "diffusivity_blocks")[i_diff_block_group]);
79 else
80 assignBlocks(params, _blocks);
81
82 // Transfer the diffusivity parameter from the Physics to the kernel
83 // From parameters
84 if (isParamValid("diffusivity_matprop"))
85 params.set<MaterialPropertyName>("diffusivity") =
86 getParam<std::vector<MaterialPropertyName>>("diffusivity_matprop")[i_diff_block_group];
87 else if (isParamValid("diffusivity_functor"))
88 params.set<FunctionName>("function") =
89 getParam<std::vector<MooseFunctorName>>("diffusivity_functor")[i_diff_block_group];
90
91 const auto kernel_name =
92 prefix() + _var_name + "_diffusion" +
93 ((num_diffusion_terms > 1) ? "_" + std::to_string(i_diff_block_group) : "");
94 getProblem().addKernel(kernel_type, kernel_name, params);
95 }
96
97 // Source term
98 if (isParamValid("source_functor") || isParamValid("source_matprop"))
99 {
100 // Select the kernel type based on the user parameters
101 std::string kernel_type;
102 std::string source =
103 isParamValid("source_functor") ? getParam<MooseFunctorName>("source_functor") : "";
104 if (isParamValid("source_matprop"))
105 source = getParam<MaterialPropertyName>("source_matprop");
106
107 if (MooseUtils::parsesToReal(source) || getProblem().hasFunction(source) ||
108 getProblem().hasPostprocessorValueByName(source))
109 kernel_type = _use_ad ? "ADBodyForce" : "BodyForce";
110 else if (getProblem().hasVariable(source))
111 kernel_type = _use_ad ? "ADCoupledForce" : "CoupledForce";
112 else if (getProblem().hasFunctor(source, 0))
113 kernel_type = "FunctorKernel";
114 else if (getProblem().getMaterialPropertyRegistry().hasProperty(source))
115 kernel_type = _use_ad ? "ADMatBodyForce" : "MatBodyForce";
116 else
117 paramError(isParamValid("source_functor") ? "source_functor" : "source_matprop",
118 "No kernel defined for a source term in CG for the type of '",
119 source,
120 "'");
121
122 InputParameters params = getFactory().getValidParams(kernel_type);
123 params.set<NonlinearVariableName>("variable") = _var_name;
124 assignBlocks(params, _blocks);
125
126 // Transfer the source and coefficient parameter from the Physics to the kernel
127 const auto coef = getParam<Real>("source_coef");
128 if (MooseUtils::parsesToReal(source))
129 params.set<Real>("value") = MooseUtils::convert<Real>(source) * coef;
130 else if (getProblem().hasFunction(source))
131 {
132 params.set<Real>("value") = coef;
133 params.set<FunctionName>("function") = source;
134 }
135 else if (getProblem().hasPostprocessorValueByName(source))
136 {
137 params.set<Real>("value") = coef;
138 params.set<PostprocessorName>("postprocessor") = source;
139 }
140 else if (getProblem().hasFunctor(source, 0))
141 {
142 params.set<MooseFunctorName>("functor") = source;
143 params.set<bool>("functor_on_rhs") = true;
144 if (isParamSetByUser("source_coef"))
145 paramError("source_coef",
146 "Setting a coefficient is not implemented with a source functor. Use an "
147 "intermediate (parsed) functor material to define a new functors which "
148 "multiplies the functor by the coefficient");
149 }
151 {
152 params.set<MaterialPropertyName>("material_property") = source;
153 if (isParamSetByUser("source_coef"))
155 "source_coef",
156 "Setting a coefficient is not implemented with a material property source. Use an "
157 "intermediate (parsed) material to define a new functors which "
158 "multiplies the property by the coefficient");
159 }
160 else
161 {
162 params.set<Real>("coef") = coef;
163 params.set<std::vector<VariableName>>("v") = {source};
164 }
165
166 getProblem().addKernel(kernel_type, prefix() + _var_name + "_source", params);
167 }
168
169 // Time derivative term
171 {
172 const std::string kernel_type = _use_ad ? "ADTimeDerivative" : "TimeDerivative";
173 InputParameters params = getFactory().getValidParams(kernel_type);
174 params.set<NonlinearVariableName>("variable") = _var_name;
175 assignBlocks(params, _blocks);
176 getProblem().addKernel(kernel_type, prefix() + _var_name + "_time", params);
177 }
178}
179
180void
182{
183 if (isParamSetByUser("neumann_boundaries"))
184 {
185 const auto & boundary_fluxes = getParam<std::vector<MooseFunctorName>>("boundary_fluxes");
186 for (const auto i : index_range(_neumann_boundaries))
187 {
188 const auto & bc_flux = boundary_fluxes[i];
189 // Select the boundary type based on the user parameters and what we know to be most efficient
190 // We could actually just use the very last option for everything but the performance is
191 // better if one uses the specialized objects
192 std::string bc_type = "";
193 if (MooseUtils::parsesToReal(bc_flux))
194 bc_type = _use_ad ? "ADNeumannBC" : "NeumannBC";
195 else if (getProblem().hasVariable(bc_flux))
196 bc_type = "CoupledVarNeumannBC"; // not AD, but still perfect Jacobian
197 else if (getProblem().hasFunction(bc_flux))
198 bc_type = _use_ad ? "ADFunctionNeumannBC" : "FunctionNeumannBC";
199 else if (getProblem().hasPostprocessorValueByName(bc_flux))
200 bc_type = "PostprocessorNeumannBC";
201 else // this is AD, but we can mix AD and non-AD
202 bc_type = "FunctorNeumannBC";
203
204 // Get the parameters for the object type chosen and set the common parameters
205 InputParameters params = getFactory().getValidParams(bc_type);
206 params.set<NonlinearVariableName>("variable") = _var_name;
207 params.set<std::vector<BoundaryName>>("boundary") = {_neumann_boundaries[i]};
208
209 // Set the flux parameter for the specific type of NeumannBC used
210 if (MooseUtils::parsesToReal(bc_flux))
211 params.set<Real>("value") = MooseUtils::convert<Real>(bc_flux);
212 else if (getProblem().hasVariable(bc_flux))
213 params.set<std::vector<VariableName>>("v") = {bc_flux};
214 else if (getProblem().hasFunction(bc_flux))
215 params.set<FunctionName>("function") = bc_flux;
216 else if (getProblem().hasPostprocessorValueByName(bc_flux))
217 params.set<PostprocessorName>("postprocessor") = bc_flux;
218 else
219 params.set<MooseFunctorName>("functor") = bc_flux;
220
222 bc_type, prefix() + _var_name + "_neumann_bc_" + _neumann_boundaries[i], params);
223 }
224 }
225 if (isParamSetByUser("dirichlet_boundaries"))
226 {
227 const auto & boundary_values = getParam<std::vector<MooseFunctorName>>("boundary_values");
228 for (const auto i : index_range(_dirichlet_boundaries))
229 {
230 const auto & bc_value = boundary_values[i];
231 // Select the boundary type based on the user parameters and what we know to be most efficient
232 std::string bc_type = "";
233 if (MooseUtils::parsesToReal(bc_value))
234 bc_type = _use_ad ? "ADDirichletBC" : "DirichletBC";
235 else if (getProblem().hasVariable(bc_value))
236 bc_type = _use_ad ? "ADMatchedValueBC" : "MatchedValueBC";
237 else if (getProblem().hasFunction(bc_value))
238 bc_type = _use_ad ? "ADFunctionDirichletBC" : "FunctionDirichletBC";
239 else if (getProblem().hasPostprocessorValueByName(bc_value))
240 bc_type = "PostprocessorDirichletBC";
241 else // this is AD, but we can mix AD and non-AD
242 bc_type = "FunctorDirichletBC";
243
244 InputParameters params = getFactory().getValidParams(bc_type);
245 params.set<NonlinearVariableName>("variable") = _var_name;
246 params.set<std::vector<BoundaryName>>("boundary") = {_dirichlet_boundaries[i]};
247
248 // Set the flux parameter for the specific type of DirichletBC used
249 if (MooseUtils::parsesToReal(bc_value))
250 params.set<Real>("value") = MooseUtils::convert<Real>(bc_value);
251 else if (getProblem().hasVariable(bc_value))
252 params.set<std::vector<VariableName>>("v") = {bc_value};
253 else if (getProblem().hasFunction(bc_value))
254 params.set<FunctionName>("function") = bc_value;
255 else if (getProblem().hasPostprocessorValueByName(bc_value))
256 params.set<PostprocessorName>("postprocessor") = bc_value;
257 else
258 params.set<MooseFunctorName>("functor") = bc_value;
259
261 bc_type, prefix() + _var_name + "_dirichlet_bc_" + _dirichlet_boundaries[i], params);
262 }
263 }
264}
265
266void
268{
269 // If the variable was added outside the Physics
271 {
272 reportPotentiallyMissedParameters({"variable_order", "system_names"}, "MooseVariable");
273 return;
274 }
275
276 const std::string variable_type = "MooseVariable";
277 InputParameters params = getFactory().getValidParams(variable_type);
278 params.set<MooseEnum>("order") = getParam<MooseEnum>("variable_order");
279 assignBlocks(params, _blocks);
280 params.set<SolverSystemName>("solver_sys") = getSolverSystem(_var_name);
281
282 getProblem().addVariable(variable_type, _var_name, params);
283}
284
285void
287{
288 const auto bc_type_fixed = "FunctorDirichletBC";
289 InputParameters params_fixed = getFactory().getValidParams(bc_type_fixed);
290 const auto bc_type_flux = "FunctorNeumannBC";
291 InputParameters params_flux = getFactory().getValidParams(bc_type_flux);
292
293 for (const auto & comp_pair : _components_boundary_conditions)
294 {
295 for (const auto & bc_pair : comp_pair.second)
296 {
297 params_fixed.set<NonlinearVariableName>("variable") = _var_name;
298 params_flux.set<NonlinearVariableName>("variable") = _var_name;
299
300 const auto bc_type = bc_pair.second.second;
301 const auto functor_name = bc_pair.second.first;
302 params_fixed.set<MooseFunctorName>("functor") = functor_name;
303 params_flux.set<MooseFunctorName>("functor") = functor_name;
304
305 const auto surface_name = bc_pair.first.second;
306 params_fixed.set<std::vector<BoundaryName>>("boundary") = {surface_name};
307 params_flux.set<std::vector<BoundaryName>>("boundary") = {surface_name};
308
310 getProblem().addBoundaryCondition(bc_type_fixed,
311 prefix() + _var_name + "_comp_" + comp_pair.first +
312 "_fixed_value_" + surface_name,
313 params_fixed);
315 getProblem().addBoundaryCondition(bc_type_flux,
316 prefix() + _var_name + "_comp_" + comp_pair.first +
317 "_flux_" + surface_name,
318 params_flux);
319 else
320 mooseError("Boundary condition type not implemented");
321 }
322 }
323}
registerDiffusionPhysicsBaseTasks("MooseApp", DiffusionCG)
registerMooseAction("MooseApp", DiffusionCG, "add_kernel")
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
Creates all the objects needed to solve a diffusion equation with a continuous Galerkin finite elemen...
Definition DiffusionCG.h:19
virtual void addFEBCs() override
virtual void addBoundaryConditionsFromComponents() override
static InputParameters validParams()
Definition DiffusionCG.C:20
DiffusionCG(const InputParameters &parameters)
Definition DiffusionCG.C:35
virtual void addSolverVariables() override
The default implementation of these routines will do nothing as we do not expect all Physics to be de...
const bool _use_ad
Whether to use automatic differentiation or not.
Definition DiffusionCG.h:33
virtual void addFEKernels() override
Definition DiffusionCG.C:45
Base class to host all common parameters and attributes of Physics actions to solve the diffusion equ...
const std::vector< BoundaryName > & _neumann_boundaries
Boundaries on which a Neumann boundary condition is applied.
const VariableName & _var_name
Name of the diffused variable.
static InputParameters validParams()
const std::vector< BoundaryName > & _dirichlet_boundaries
Boundaries on which a Dirichlet boundary condition is applied.
const MaterialPropertyRegistry & getMaterialPropertyRegistry() const
virtual void addVariable(const std::string &var_type, const std::string &var_name, InputParameters &params)
Canonical method for adding a non-linear variable.
bool hasPostprocessorValueByName(const PostprocessorName &name) const
Whether or not a Postprocessor value exists by a given name.
virtual void addBoundaryCondition(const std::string &bc_name, const std::string &name, InputParameters &parameters)
virtual void addKernel(const std::string &kernel_name, const std::string &name, InputParameters &parameters)
virtual bool hasFunction(const std::string &name, const THREAD_ID tid=0)
InputParameters getValidParams(const std::string &name) const
Get valid parameters for the object.
Definition Factory.C:68
void checkAtMostOneParamSetByUser(const std::vector< std::string > &params) const
Check that only one of the parameters are set.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an optional parameter and a documentation string to the InputParameters object.
void transferParam(const InputParameters &source_param, const std::string &name, const std::string &new_name="", const std::string &new_description="")
A routine to transfer a parameter from one class' validParams to another.
void addClassDescription(const std::string &doc_string)
This method adds a description of the class that will be displayed in the input file syntax dump.
T & set(const std::string &name, bool quiet_mode=false)
Returns a writable reference to the named parameters.
bool hasProperty(const std::string &name) const
void paramError(const std::string &param, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
Definition MooseBase.h:457
bool isParamSetByUser(const std::string &name) const
Test if the supplied parameter is set by a user, as opposed to not set or set to default.
Definition MooseBase.h:205
const T & getParam(const std::string &name) const
Retrieve a parameter for the object.
Definition MooseBase.h:406
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
Definition MooseBase.h:199
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition MooseEnum.h:55
static InputParameters validParams()
Base class to help creating an entire physics.
Definition PhysicsBase.h:31
virtual FEProblemBase & getProblem()
Get the problem for this physics Useful to add objects to the simulation.
Factory & getFactory()
Get the factory for this physics The factory lets you get the parameters for objects.
bool shouldCreateTimeDerivative(const VariableName &var_name, const std::vector< SubdomainName > &blocks, const bool error_if_already_defined) const
Returns whether this Physics should create the variable.
void assignBlocks(InputParameters &params, const std::vector< SubdomainName > &blocks) const
Set the blocks parameter to the input parameters of an object this Physics will create.
void reportPotentiallyMissedParameters(const std::vector< std::string > &param_names, const std::string &object_type, const std::string &object_name="") const
When this is called, we are knowingly not using the value of these parameters.
std::string prefix() const
Use prefix() to disambiguate names.
const SolverSystemName & getSolverSystem(unsigned int variable_index) const
Get the solver system for this variable index.
bool shouldCreateVariable(const VariableName &var_name, const std::vector< SubdomainName > &blocks, const bool error_if_aux)
Returns whether this Physics should create the variable.
std::vector< SubdomainName > _blocks
Keep track of the subdomains the Physics is defined on.
Interface class to help components interact with Physics.
std::map< std::string, std::map< std::pair< VariableName, BoundaryName >, std::pair< MooseFunctorName, ComponentBoundaryConditionInterface::BoundaryConditionType > > > _components_boundary_conditions
Map of components to variables and boundary conditions.
bool hasFunctor(const std::string &name, const THREAD_ID tid) const
checks whether we have a functor corresponding to name on the thread id tid
bool parsesToReal(const std::string &input, Real *parsed_real)
Definition MooseUtils.C:152