https://mooseframework.inl.gov
Loading...
Searching...
No Matches
MultiSpeciesDiffusionPhysicsBase.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
11#include "MatDiffusion.h"
12#include "MoosePreconditioner.h"
13#include "PetscSupport.h"
14#include "MooseEnumItem.h"
15#include "ActionComponent.h"
16
19{
22 "Base class for creating a diffusion equation for multiple diffused species");
23
24 params.addRequiredParam<std::vector<VariableName>>("species", "Species being diffused");
25
26 // Diffusivity
27 params.addParam<std::vector<MaterialPropertyName>>(
28 "diffusivity_matprops",
29 "Material properties defining the diffusion coefficient for each species");
30 params.addParam<std::vector<MooseFunctorName>>(
31 "diffusivity_functors", "Functors specifying the diffusivity for each species");
32
33 // Source term
34 params.addParam<std::vector<MooseFunctorName>>(
35 "source_functors", "Source terms in the diffusion problem for each species");
36 params.addParam<std::vector<Real>>("source_coefs", {1}, "Coefficient multiplying the source");
37
38 // Boundary conditions
39 params.addParam<std::vector<std::vector<BoundaryName>>>(
40 "neumann_boundaries", {}, "Boundaries on which to apply a diffusive flux for each species");
41 params.addParam<std::vector<std::vector<BoundaryName>>>(
42 "dirichlet_boundaries", {}, "Boundaries on which to apply a fixed value for each species");
43 params.addParam<std::vector<std::vector<MooseFunctorName>>>(
44 "boundary_fluxes",
45 {},
46 "Functors to compute the diffusive flux on each Neumann boundary for each species");
47 params.addParam<std::vector<std::vector<MooseFunctorName>>>(
48 "boundary_values",
49 {},
50 "Functors to compute the diffusive flux on each Dirichlet boundary for each species");
51 params.addParamNamesToGroup("neumann_boundaries dirichlet_boundaries boundary_fluxes "
52 "boundary_values",
53 "Boundary conditions");
54
55 // Initial conditions
56 params.addParam<std::vector<FunctionName>>(
57 "initial_conditions_species", "Functions describing the initial conditions for the species");
58
59 // Postprocessing
60 params.addParam<std::vector<BoundaryName>>(
61 "compute_diffusive_fluxes_on", {}, "Surfaces to compute the diffusive flux on");
62
63 // Preconditioning is implemented so let's use it by default
64 MooseEnum pc_options("default defer", "default");
65 params.addParam<MooseEnum>(
66 "preconditioning", pc_options, "Which preconditioning to use for this Physics");
67
68 params.addParam<bool>(
69 "use_automatic_differentiation",
70 true,
71 "Whether to use automatic differentiation for all the terms in the equation");
72
73 return params;
74}
75
77 const InputParameters & parameters)
78 : PhysicsBase(parameters),
79 _species_names(getParam<std::vector<VariableName>>("species")),
80 _num_species(_species_names.size()),
81 _neumann_boundaries(getParam<std::vector<std::vector<BoundaryName>>>("neumann_boundaries")),
82 _dirichlet_boundaries(getParam<std::vector<std::vector<BoundaryName>>>("dirichlet_boundaries")),
83 _use_ad(getParam<bool>("use_automatic_differentiation"))
84{
85 // Keep track of variables
86 for (const auto & var_name : _species_names)
87 saveSolverVariableName(var_name);
88
89 // Parameter checking
90 checkTwoDVectorParamsSameLength<BoundaryName, MooseFunctorName>("neumann_boundaries",
91 "boundary_fluxes");
92 checkTwoDVectorParamsSameLength<BoundaryName, MooseFunctorName>("dirichlet_boundaries",
93 "boundary_values");
94 checkTwoDVectorParamsNoRespectiveOverlap<BoundaryName>(
95 {"neumann_boundaries", "dirichlet_boundaries"});
96 if (isParamSetByUser("source_coefs"))
97 checkParamsBothSetOrNotSet("source_functors", "source_coefs");
98 if (isParamValid("source_functors"))
99 checkVectorParamsSameLength<VariableName, MooseFunctorName>("species", "source_functors");
100 if (isParamValid("initial_conditions_species"))
101 checkVectorParamsSameLength<VariableName, FunctionName>("species",
102 "initial_conditions_species");
103
104 addRequiredPhysicsTask("add_preconditioning");
105 addRequiredPhysicsTask("add_ics_physics");
106}
107
108void
110{
111 // Use a multi-grid method, known to work for elliptic problems such as diffusion
112 if (_preconditioning == "default")
113 {
114 // We only pass petsc options as that's all that's needed to set up the preconditioner
115 const auto option_pair1 =
116 std::make_pair<MooseEnumItem, std::string>(MooseEnumItem("-pc_type"), "hypre");
117 const auto option_pair2 =
118 std::make_pair<MooseEnumItem, std::string>(MooseEnumItem("-pc_hypre_type"), "boomeramg");
119 addPetscPairsToPetscOptions({option_pair1, option_pair2});
120 }
121}
122
123void
125{
126 for (const auto i : index_range(_species_names))
127 {
128 const auto & var_name = _species_names[i];
129 for (const auto & boundary_name :
130 getParam<std::vector<BoundaryName>>("compute_diffusive_fluxes_on"))
131 {
132 // Create the boundary integration of the flux
133 const std::string pp_type =
134 _use_ad ? "ADSideDiffusiveFluxIntegral" : "SideDiffusiveFluxIntegral";
135 auto params = _factory.getValidParams(pp_type);
136 params.set<std::vector<VariableName>>("variable") = {var_name};
137 // FE variables require matprops for this postprocessor at the moment
138 if (isParamValid("diffusivity_matprops"))
139 params.set<MaterialPropertyName>("diffusivity") =
140 getParam<std::vector<MaterialPropertyName>>("diffusivity_matprops")[i];
141 // FV variables require functors
142 else if (isParamValid("diffusivity_functors"))
143 params.set<MooseFunctorName>("functor_diffusivity") =
144 getParam<std::vector<MooseFunctorName>>("diffusivity_functors")[i];
145 else
146 mooseError("No diffusivity parameter specified");
147 params.set<std::vector<BoundaryName>>("boundary") = {boundary_name};
148 // Default to maximum computation
149 params.set<ExecFlagEnum>("execute_on") = {
152 pp_type, prefix() + "diffusive_flux_" + var_name + "_" + boundary_name, params);
153 }
154 }
155}
156
157void
159{
160 for (const auto & block : component.blocks())
161 _blocks.push_back(block);
162}
163
164void
166{
167 InputParameters params = getFactory().getValidParams("FunctionIC");
168 assignBlocks(params, _blocks);
169
170 // always obey the user specification of initial conditions
171 // There are no default values, so no need to consider whether the app is restarting
172 for (const auto i : index_range(_species_names))
173 {
174 const auto & var_name = _species_names[i];
175 if (isParamValid("initial_conditions_species") &&
176 shouldCreateIC(var_name,
177 _blocks,
178 /*whether IC is a default*/ false,
179 /*error if already an IC*/ true))
180 {
181 params.set<VariableName>("variable") = var_name;
182 params.set<FunctionName>("function") =
183 getParam<std::vector<FunctionName>>("initial_conditions_species")[i];
184
185 getProblem().addInitialCondition("FunctionIC", prefix() + var_name + "_ic", params);
186 }
187 }
188}
const ExecFlagType EXEC_TIMESTEP_END
const ExecFlagType EXEC_INITIAL
const ExecFlagType EXEC_LINEAR
const ExecFlagType EXEC_NONLINEAR
virtual void addInitialCondition(const std::string &ic_name, const std::string &name, InputParameters &parameters)
virtual void addPostprocessor(const std::string &pp_name, const std::string &name, InputParameters &parameters)
InputParameters getValidParams(const std::string &name) const
void checkParamsBothSetOrNotSet(const std::string &param1, const std::string &param2) const
void addParamNamesToGroup(const std::string &space_delim_names, const std::string group_name)
void addRequiredParam(const std::string &name, const std::string &doc_string)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
T & set(const std::string &name, bool quiet_mode=false)
bool isParamSetByUser(const std::string &name) const
void mooseError(Args &&... args) const
const T & getParam(const std::string &name) const
bool isParamValid(const std::string &name) const
const bool _use_ad
Whether to use automatic differentiation or not.
void addComponent(const ActionComponent &component) override
virtual void addPreconditioning() override
Add default preconditioning options.
MultiSpeciesDiffusionPhysicsBase(const InputParameters &parameters)
const std::vector< VariableName > & _species_names
Name of the diffused variables.
virtual void addInitialConditions() override
Add initial conditions for each diffused variable.
virtual void addPostprocessors() override
Add postprocessing of the fluxes.
Factory & _factory
void addPetscPairsToPetscOptions(const std::vector< std::pair< MooseEnumItem, std::string > > &petsc_pair_options)
static InputParameters validParams()
virtual FEProblemBase & getProblem()
Factory & getFactory()
bool shouldCreateIC(const VariableName &var_name, const std::vector< SubdomainName > &blocks, const bool ic_is_default_ic, const bool error_if_already_defined) const
void assignBlocks(InputParameters &params, const std::vector< SubdomainName > &blocks) const
void saveSolverVariableName(const VariableName &var_name)
std::string prefix() const
std::vector< SubdomainName > _blocks
const MooseEnum & _preconditioning
void addRequiredPhysicsTask(const std::string &task)