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