Line data Source code
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 "ConservedAction.h"
11 : // MOOSE includes
12 : #include "Conversion.h"
13 : #include "FEProblem.h"
14 : #include "Factory.h"
15 : #include "MooseObjectAction.h"
16 : #include "MooseMesh.h"
17 : #include "AddVariableAction.h"
18 :
19 : #include "libmesh/string_to_enum.h"
20 :
21 : using namespace libMesh;
22 :
23 : registerMooseAction("PhaseFieldApp", ConservedAction, "add_variable");
24 :
25 : registerMooseAction("PhaseFieldApp", ConservedAction, "add_kernel");
26 :
27 : InputParameters
28 81 : ConservedAction::validParams()
29 : {
30 81 : InputParameters params = Action::validParams();
31 81 : params.addClassDescription(
32 : "Set up the variable(s) and the kernels needed for a conserved phase field variable."
33 : " Note that for a direct solve, the element family and order are overwritten with hermite "
34 : "and third.");
35 162 : MooseEnum solves("DIRECT REVERSE_SPLIT FORWARD_SPLIT");
36 162 : params.addRequiredParam<MooseEnum>("solve_type", solves, "Split or direct solve?");
37 : // Get MooseEnums for the possible order/family options for this variable
38 81 : MooseEnum families(AddVariableAction::getNonlinearVariableFamilies());
39 81 : MooseEnum orders(AddVariableAction::getNonlinearVariableOrders());
40 162 : params.addParam<MooseEnum>("family",
41 : families,
42 : "Specifies the family of FE "
43 : "shape functions to use for this variable");
44 162 : params.addParam<MooseEnum>("order",
45 : orders,
46 : "Specifies the order of the FE "
47 : "shape function to use for this variable");
48 162 : params.addParam<Real>("scaling", 1.0, "Specifies a scaling factor to apply to this variable");
49 162 : params.addParam<bool>("implicit", true, "Whether kernels are implicit or not");
50 162 : params.addParam<bool>(
51 162 : "use_displaced_mesh", false, "Whether to use displaced mesh in the kernels");
52 162 : params.addParamNamesToGroup("scaling implicit use_displaced_mesh", "Advanced");
53 162 : params.addRequiredParam<MaterialPropertyName>("mobility", "The mobility used with the kernel");
54 162 : params.addCoupledVar("coupled_variables",
55 : "Vector of nonlinear variable arguments this kernel depends on");
56 :
57 162 : params.addRequiredParam<MaterialPropertyName>(
58 : "free_energy", "Base name of the free energy function F defined in a free energy material");
59 162 : params.addRequiredParam<MaterialPropertyName>("kappa", "The kappa used with the kernel");
60 162 : params.addParam<std::vector<SubdomainName>>(
61 : "block", {}, "Block restriction for the variables and kernels");
62 81 : return params;
63 81 : }
64 :
65 81 : ConservedAction::ConservedAction(const InputParameters & params)
66 : : Action(params),
67 162 : _solve_type(getParam<MooseEnum>("solve_type").getEnum<SolveType>()),
68 : _var_name(name()),
69 243 : _scaling(getParam<Real>("scaling"))
70 : {
71 81 : switch (_solve_type)
72 : {
73 28 : case SolveType::DIRECT:
74 28 : _fe_type = FEType(Utility::string_to_enum<Order>("THIRD"),
75 : Utility::string_to_enum<FEFamily>("HERMITE"));
76 56 : if (!parameters().isParamSetByAddParam("order") &&
77 28 : !parameters().isParamSetByAddParam("family"))
78 0 : mooseWarning("Order and family autoset to third and hermite in ConservedAction");
79 : break;
80 53 : case SolveType::REVERSE_SPLIT:
81 : case SolveType::FORWARD_SPLIT:
82 159 : _fe_type = FEType(Utility::string_to_enum<Order>(getParam<MooseEnum>("order")),
83 53 : Utility::string_to_enum<FEFamily>(getParam<MooseEnum>("family")));
84 : // Set name of chemical potential variable
85 53 : _chempot_name = "chem_pot_" + _var_name;
86 53 : break;
87 0 : default:
88 0 : paramError("solve_type", "Incorrect solve_type in ConservedAction");
89 : }
90 81 : }
91 :
92 : void
93 162 : ConservedAction::act()
94 : {
95 : //
96 : // Add variable(s)
97 : //
98 162 : if (_current_task == "add_variable")
99 : {
100 81 : auto type = AddVariableAction::variableType(_fe_type);
101 81 : auto var_params = _factory.getValidParams(type);
102 162 : var_params.set<MooseEnum>("family") = Moose::stringify(_fe_type.family);
103 81 : var_params.set<MooseEnum>("order") = _fe_type.order.get_order();
104 81 : var_params.set<std::vector<Real>>("scaling") = {_scaling};
105 81 : var_params.applySpecificParameters(parameters(), {"block"});
106 :
107 : // Create conserved variable _var_name
108 81 : _problem->addVariable(type, _var_name, var_params);
109 :
110 : // Create chemical potential variable for split form
111 81 : switch (_solve_type)
112 : {
113 : case SolveType::DIRECT:
114 : break;
115 53 : case SolveType::REVERSE_SPLIT:
116 : case SolveType::FORWARD_SPLIT:
117 53 : _problem->addVariable(type, _chempot_name, var_params);
118 : }
119 81 : }
120 :
121 : //
122 : // Add Kernels
123 : //
124 81 : else if (_current_task == "add_kernel")
125 : {
126 81 : switch (_solve_type)
127 : {
128 : case SolveType::DIRECT:
129 : // Add time derivative kernel
130 : {
131 28 : std::string kernel_type = "TimeDerivative";
132 :
133 28 : std::string kernel_name = _var_name + "_" + kernel_type;
134 28 : InputParameters params = _factory.getValidParams(kernel_type);
135 56 : params.set<NonlinearVariableName>("variable") = _var_name;
136 28 : params.applyParameters(parameters());
137 :
138 28 : _problem->addKernel(kernel_type, kernel_name, params);
139 28 : }
140 :
141 : // Add CahnHilliard kernel
142 : {
143 28 : std::string kernel_type = "CahnHilliard";
144 :
145 28 : std::string kernel_name = _var_name + "_" + kernel_type;
146 28 : InputParameters params = _factory.getValidParams(kernel_type);
147 28 : params.set<NonlinearVariableName>("variable") = _var_name;
148 84 : params.set<MaterialPropertyName>("mob_name") = getParam<MaterialPropertyName>("mobility");
149 56 : params.set<MaterialPropertyName>("f_name") =
150 56 : getParam<MaterialPropertyName>("free_energy");
151 28 : params.applyParameters(parameters());
152 :
153 28 : _problem->addKernel(kernel_type, kernel_name, params);
154 28 : }
155 :
156 : // Add ACInterface kernel
157 : {
158 28 : std::string kernel_type = "CHInterface";
159 :
160 28 : std::string kernel_name = _var_name + "_" + kernel_type;
161 28 : InputParameters params = _factory.getValidParams(kernel_type);
162 28 : params.set<NonlinearVariableName>("variable") = _var_name;
163 84 : params.set<MaterialPropertyName>("mob_name") = getParam<MaterialPropertyName>("mobility");
164 84 : params.set<MaterialPropertyName>("kappa_name") = getParam<MaterialPropertyName>("kappa");
165 28 : params.applyParameters(parameters());
166 :
167 28 : _problem->addKernel(kernel_type, kernel_name, params);
168 28 : }
169 28 : break;
170 :
171 : case SolveType::REVERSE_SPLIT:
172 : // Add time derivative kernel
173 : {
174 46 : std::string kernel_type = "CoupledTimeDerivative";
175 :
176 46 : std::string kernel_name = _var_name + "_" + kernel_type;
177 46 : InputParameters params = _factory.getValidParams(kernel_type);
178 92 : params.set<NonlinearVariableName>("variable") = _chempot_name;
179 138 : params.set<std::vector<VariableName>>("v") = {_var_name};
180 46 : params.applyParameters(parameters());
181 :
182 46 : _problem->addKernel(kernel_type, kernel_name, params);
183 46 : }
184 :
185 : // Add SplitCHWRes kernel
186 : {
187 46 : std::string kernel_type = "SplitCHWRes";
188 :
189 46 : std::string kernel_name = _var_name + "_" + kernel_type;
190 46 : InputParameters params = _factory.getValidParams(kernel_type);
191 92 : params.set<NonlinearVariableName>("variable") = _chempot_name;
192 138 : params.set<MaterialPropertyName>("mob_name") = getParam<MaterialPropertyName>("mobility");
193 46 : params.applyParameters(parameters());
194 :
195 46 : _problem->addKernel(kernel_type, kernel_name, params);
196 46 : }
197 :
198 : // Add SplitCHParsed kernel
199 : {
200 46 : std::string kernel_type = "SplitCHParsed";
201 :
202 46 : std::string kernel_name = _var_name + "_" + kernel_type;
203 46 : InputParameters params = _factory.getValidParams(kernel_type);
204 92 : params.set<NonlinearVariableName>("variable") = _var_name;
205 138 : params.set<std::vector<VariableName>>("w") = {_chempot_name};
206 92 : params.set<MaterialPropertyName>("f_name") =
207 46 : getParam<MaterialPropertyName>("free_energy");
208 138 : params.set<MaterialPropertyName>("kappa_name") = getParam<MaterialPropertyName>("kappa");
209 46 : params.applyParameters(parameters());
210 :
211 46 : _problem->addKernel(kernel_type, kernel_name, params);
212 46 : }
213 46 : break;
214 :
215 : case SolveType::FORWARD_SPLIT:
216 : // Add time derivative kernel
217 : {
218 7 : std::string kernel_type = "TimeDerivative";
219 :
220 7 : std::string kernel_name = _var_name + "_" + kernel_type;
221 7 : InputParameters params = _factory.getValidParams(kernel_type);
222 14 : params.set<NonlinearVariableName>("variable") = _var_name;
223 7 : params.applyParameters(parameters());
224 :
225 7 : _problem->addKernel(kernel_type, kernel_name, params);
226 7 : }
227 :
228 : // Add MatDiffusion kernel for c residual
229 : {
230 7 : std::string kernel_type = "MatDiffusion";
231 :
232 7 : std::string kernel_name = _var_name + "_" + kernel_type;
233 7 : InputParameters params = _factory.getValidParams(kernel_type);
234 7 : params.set<NonlinearVariableName>("variable") = _var_name;
235 21 : params.set<std::vector<VariableName>>("v") = {_chempot_name};
236 14 : params.set<MaterialPropertyName>("diffusivity") =
237 14 : getParam<MaterialPropertyName>("mobility");
238 7 : params.applyParameters(parameters());
239 :
240 7 : _problem->addKernel(kernel_type, kernel_name, params);
241 7 : }
242 : // Add MatDiffusion kernel for chemical potential residual
243 : {
244 7 : std::string kernel_type = "MatDiffusion";
245 :
246 7 : std::string kernel_name = _chempot_name + "_" + kernel_type;
247 7 : InputParameters params = _factory.getValidParams(kernel_type);
248 14 : params.set<NonlinearVariableName>("variable") = _chempot_name;
249 21 : params.set<std::vector<VariableName>>("v") = {_var_name};
250 21 : params.set<MaterialPropertyName>("diffusivity") = getParam<MaterialPropertyName>("kappa");
251 7 : params.applyParameters(parameters());
252 :
253 7 : _problem->addKernel(kernel_type, kernel_name, params);
254 7 : }
255 :
256 : // Add CoupledMaterialDerivative kernel
257 : {
258 7 : std::string kernel_type = "CoupledMaterialDerivative";
259 :
260 7 : std::string kernel_name = _chempot_name + "_" + kernel_type;
261 7 : InputParameters params = _factory.getValidParams(kernel_type);
262 14 : params.set<NonlinearVariableName>("variable") = _chempot_name;
263 21 : params.set<std::vector<VariableName>>("v") = {_var_name};
264 14 : params.set<MaterialPropertyName>("f_name") =
265 14 : getParam<MaterialPropertyName>("free_energy");
266 7 : params.applyParameters(parameters());
267 :
268 7 : _problem->addKernel(kernel_type, kernel_name, params);
269 7 : }
270 :
271 : // Add CoefReaction kernel
272 : {
273 7 : std::string kernel_type = "CoefReaction";
274 :
275 7 : std::string kernel_name = _chempot_name + "_" + kernel_type;
276 7 : InputParameters params = _factory.getValidParams(kernel_type);
277 14 : params.set<NonlinearVariableName>("variable") = _chempot_name;
278 7 : params.set<Real>("coefficient") = -1.0;
279 7 : params.applyParameters(parameters());
280 :
281 7 : _problem->addKernel(kernel_type, kernel_name, params);
282 7 : }
283 : }
284 : }
285 162 : }
|