www.mooseframework.org
GrandPotentialKernelAction.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
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 "Factory.h"
12 #include "Parser.h"
13 #include "Conversion.h"
14 #include "FEProblem.h"
15 
16 registerMooseAction("PhaseFieldApp", GrandPotentialKernelAction, "add_kernel");
17 
18 template <>
19 InputParameters
21 {
22  InputParameters parameters = validParams<Action>();
23  parameters.addClassDescription(
24  "Automatically generate most or all of the kernels for the grand potential model");
25  parameters.addRequiredParam<std::vector<NonlinearVariableName>>(
26  "chemical_potentials", "List of chemical potential variables");
27  parameters.addRequiredParam<std::vector<MaterialPropertyName>>(
28  "susceptibilities", "List of susceptibilities that correspond to chemical_potentials");
29  parameters.addRequiredParam<std::vector<MaterialPropertyName>>(
30  "free_energies_gr",
31  "List of free energies for each phase. Place in same order as switching_function_names.");
32  parameters.addRequiredParam<std::vector<MaterialPropertyName>>(
33  "free_energies_w",
34  "List of functions for each phase. Length should be length of chemical_potentials * length "
35  "of switching_function_names.");
36  parameters.addRequiredParam<std::vector<MaterialPropertyName>>(
37  "switching_function_names",
38  "Switching function materials that provide switching function for free_energies_*.");
39  parameters.addRequiredParam<std::vector<MaterialPropertyName>>(
40  "mobilities", "Vector of mobilities that must match chemical_potentials");
41  parameters.addRequiredParam<unsigned int>("op_num", "specifies the number of grains to create");
42  parameters.addRequiredParam<std::string>("var_name_base",
43  "specifies the base name of the grain variables");
44  parameters.addParam<std::vector<NonlinearVariableName>>(
45  "additional_ops", "List of any additional order parameters which are not grains");
46  parameters.addParam<std::vector<MaterialPropertyName>>("free_energies_op",
47  "List of free energies used by additional "
48  "order parameters. Places in same order "
49  "as switching_function_names.");
50  parameters.addParam<MaterialPropertyName>("kappa_gr", "kappa", "The kappa used with the grains");
51  parameters.addParam<MaterialPropertyName>(
52  "kappa_op", "kappa", "The kappa used with additional_ops");
53  parameters.addParam<MaterialPropertyName>(
54  "gamma_gr", "gamma", "Name of the gamma used with grains");
55  parameters.addParam<MaterialPropertyName>(
56  "gamma_op", "gamma", "Name of the gamma used with additional order parameters");
57  parameters.addParam<MaterialPropertyName>(
58  "gamma_grxop",
59  "gamma",
60  "Name of the gamma used when grains interact with other order parameters");
61  parameters.addParam<MaterialPropertyName>(
62  "mobility_name_gr", "L", "Name of mobility to be used with grains");
63  parameters.addParam<MaterialPropertyName>(
64  "mobility_name_op", "L", "Name of mobility to be used with additional_ops");
65  parameters.addParam<bool>("implicit", true, "Whether kernels are implicit or not");
66  parameters.addParam<bool>(
67  "use_displaced_mesh", false, "Whether to use displaced mesh in the kernels");
68  MultiMooseEnum anisotropy("true=1 false=0", "false");
69  parameters.addRequiredParam<MultiMooseEnum>(
70  "anisotropic", anisotropy, "Whether or not each mobility is anisotropic");
71 
72  return parameters;
73 }
74 
75 GrandPotentialKernelAction::GrandPotentialKernelAction(const InputParameters & parameters)
76  : Action(parameters)
77 {
78 }
79 
80 void
82 {
83  // Get Variables from parameters
84  const auto w_names = getParam<std::vector<NonlinearVariableName>>("chemical_potentials");
85  const auto chis = getParam<std::vector<MaterialPropertyName>>("susceptibilities");
86  const auto Fj_gr = getParam<std::vector<MaterialPropertyName>>("free_energies_gr");
87  const auto Fj_w = getParam<std::vector<MaterialPropertyName>>("free_energies_w");
88  const auto hj = getParam<std::vector<MaterialPropertyName>>("switching_function_names");
89  const auto M = getParam<std::vector<MaterialPropertyName>>("mobilities");
90  auto n_grs = getParam<unsigned int>("op_num");
91  const auto var_name_base = getParam<std::string>("var_name_base");
92  const auto Fj_op = getParam<std::vector<MaterialPropertyName>>("free_energies_op");
93  const auto kappa_gr = getParam<MaterialPropertyName>("kappa_gr");
94  const auto kappa_op = getParam<MaterialPropertyName>("kappa_op");
95  const auto gamma_gr = getParam<MaterialPropertyName>("gamma_gr");
96  const auto gamma_op = getParam<MaterialPropertyName>("gamma_op");
97  const auto gamma_xx = getParam<MaterialPropertyName>("gamma_grxop");
98  const auto gr_mob = getParam<MaterialPropertyName>("mobility_name_gr");
99  const auto op_mob = getParam<MaterialPropertyName>("mobility_name_op");
100  auto implicity = getParam<bool>("implicit");
101  auto displaced_mesh = getParam<bool>("use_displaced_mesh");
102  auto aniso = getParam<MultiMooseEnum>("anisotropic");
103 
104  // Size definitions and checks
105  unsigned int n_w = w_names.size();
106  unsigned int n_hj = hj.size();
107  std::vector<NonlinearVariableName> etas;
108  unsigned int n_etas = 0;
109  std::string kernel_name;
110  if (isParamValid("additional_ops"))
111  {
112  etas = getParam<std::vector<NonlinearVariableName>>("additional_ops");
113  n_etas = etas.size();
114  }
115 
116  if (chis.size() != n_w)
117  mooseError("susceptibilities and chemical_potentials should be vectors of the same length.");
118  if (Fj_w.size() != n_w * n_hj)
119  mooseError("free_energies_w should be length of chemcial_potentials * length of "
120  "switching_function_names");
121  if (M.size() != n_w)
122  mooseError("M and chemical_potentials should be vectors of the same length.");
123  if (aniso.size() != n_w)
124  paramError("anisotropic", "Provide as many values as entries in 'chemical_potentials'.");
125 
126  // Define additional vectors
127  std::vector<std::string> grs; // vector of all grain variable names
128  grs.resize(n_grs);
129  for (unsigned int i = 0; i < n_grs; ++i)
130  grs[i] = var_name_base + Moose::stringify(i);
131 
132  std::vector<NonlinearVariableName> all_etas; // vector of all grain variables and order parameters
133  all_etas.reserve(n_etas + n_grs);
134  all_etas.insert(all_etas.end(), etas.begin(), etas.end());
135  all_etas.insert(all_etas.end(), grs.begin(), grs.end());
136 
137  std::vector<std::string> all_vars; // vector of all variables
138  all_vars.reserve(n_etas + n_grs + n_w);
139  all_vars.insert(all_vars.end(), all_etas.begin(), all_etas.end());
140  all_vars.insert(all_vars.end(), w_names.begin(), w_names.end());
141 
142  std::vector<MaterialPropertyName> fj_temp;
143  fj_temp.resize(n_hj);
144  std::vector<VariableName> notarealvector;
145  notarealvector.resize(1);
146  std::vector<VariableName> v0;
147  v0.resize(n_etas + n_grs + n_w);
148  for (unsigned int i = 0; i < n_etas + n_grs + n_w; ++i)
149  v0[i] = all_vars[i];
150  std::vector<VariableName> v1;
151  v1.resize(n_etas + n_grs);
152  for (unsigned int i = 0; i < n_etas + n_grs; ++i)
153  v1[i] = all_etas[i];
154  std::vector<VariableName> v2;
155  v2.resize(n_etas + n_grs - 1);
156 
157  // Grains and order parameters
158  NonlinearVariableName var_name;
159  MaterialPropertyName kappa;
160  MaterialPropertyName mob_name;
161  std::vector<MaterialPropertyName> Fj_names;
162 
163  for (unsigned int i = 0; i < n_etas + n_grs; ++i)
164  {
165  var_name = all_etas[i];
166  // Distinguish between grains and the additional order parameters
167  if (i < n_etas) // First part of list is grain variables
168  {
169  kappa = kappa_op;
170  mob_name = op_mob;
171  Fj_names.resize(Fj_op.size());
172  Fj_names = Fj_op;
173  }
174  else // Second part of list is additional order parameters
175  {
176  kappa = kappa_gr;
177  mob_name = gr_mob;
178  Fj_names.resize(Fj_gr.size());
179  Fj_names = Fj_gr;
180  }
181 
182  // Remove var_name from coupled variables
183  std::vector<MaterialPropertyName> gam;
184  gam.resize(n_etas + n_grs - 1);
185  unsigned int op = 0;
186  for (unsigned int j = 0; j < n_etas + n_grs; ++j)
187  {
188  if (i != j)
189  {
190  v2[op] = all_etas[j];
191  if (j < n_etas)
192  gam[op] = gamma_op;
193  else
194  gam[op] = gamma_gr;
195  if (i < n_etas && j < n_etas)
196  gam[op] = gamma_op;
197  else if (i >= n_etas && j >= n_etas)
198  gam[op] = gamma_gr;
199  else
200  gam[op] = gamma_xx;
201  ++op;
202  }
203  }
204 
205  // TimeDerivative Kernel
206  InputParameters params = _factory.getValidParams("TimeDerivative");
207  params.set<NonlinearVariableName>("variable") = var_name;
208  params.set<bool>("implicit") = implicity;
209  params.set<bool>("use_displaced_mesh") = displaced_mesh;
210  kernel_name = "DT_" + var_name;
211  _problem->addKernel("TimeDerivative", kernel_name, params);
212 
213  // ACInterface Kernel
214  params = _factory.getValidParams("ACInterface");
215  params.set<NonlinearVariableName>("variable") = var_name;
216  params.set<bool>("implicit") = implicity;
217  params.set<bool>("use_displaced_mesh") = displaced_mesh;
218  params.set<MaterialPropertyName>("kappa_name") = kappa;
219  params.set<MaterialPropertyName>("mob_name") = mob_name;
220  params.set<std::vector<VariableName>>("args") = v2;
221  kernel_name = "ACInt_" + var_name;
222  _problem->addKernel("ACInterface", kernel_name, params);
223 
224  // ACSwitching Kernel
225  params = _factory.getValidParams("ACSwitching");
226  params.set<NonlinearVariableName>("variable") = var_name;
227  params.set<bool>("implicit") = implicity;
228  params.set<bool>("use_displaced_mesh") = displaced_mesh;
229  params.set<std::vector<MaterialPropertyName>>("Fj_names") = Fj_names;
230  params.set<std::vector<MaterialPropertyName>>("hj_names") = hj;
231  params.set<MaterialPropertyName>("mob_name") = mob_name;
232  params.set<std::vector<VariableName>>("args") = v0;
233  kernel_name = "ACSwitch_" + var_name;
234  _problem->addKernel("ACSwitching", kernel_name, params);
235 
236  // ACGrGrMulti Kernel
237  params = _factory.getValidParams("ACGrGrMulti");
238  params.set<NonlinearVariableName>("variable") = var_name;
239  params.set<bool>("implicit") = implicity;
240  params.set<bool>("use_displaced_mesh") = displaced_mesh;
241  params.set<MaterialPropertyName>("mob_name") = mob_name;
242  params.set<std::vector<VariableName>>("v") = v2;
243  params.set<std::vector<MaterialPropertyName>>("gamma_names") = gam;
244  kernel_name = "AcGrGr_" + var_name;
245  _problem->addKernel("ACGrGrMulti", kernel_name, params);
246  } // for (unsigned int i = 0; i < n_etas + n_grs; ++i)
247 
248  // Chemical Potentials
249  for (unsigned int i = 0; i < n_w; ++i)
250  {
251  // SusceptibilityTimeDerivative
252  InputParameters params = _factory.getValidParams("SusceptibilityTimeDerivative");
253  params.set<NonlinearVariableName>("variable") = w_names[i];
254  params.set<MaterialPropertyName>("f_name") = chis[i];
255  params.set<std::vector<VariableName>>("args") = v0;
256  params.set<bool>("implicit") = implicity;
257  params.set<bool>("use_displaced_mesh") = displaced_mesh;
258  kernel_name = "ChiDt_" + w_names[i];
259  _problem->addKernel("SusceptibilityTimeDerivative", kernel_name, params);
260 
261  // MatDiffusion
262  params = _factory.getValidParams("MatDiffusion");
263  params.set<NonlinearVariableName>("variable") = w_names[i];
264  params.set<bool>("implicit") = implicity;
265  params.set<bool>("use_displaced_mesh") = displaced_mesh;
266  params.set<MaterialPropertyName>("diffusivity") = M[i];
267  kernel_name = "MatDif_" + w_names[i];
268  if (aniso.get(i))
269  _problem->addKernel("MatAnisoDiffusion", kernel_name, params);
270  else
271  {
272  params.set<std::vector<VariableName>>("args") = v0;
273  _problem->addKernel("MatDiffusion", kernel_name, params);
274  }
275 
276  // CoupledSwitchingTimeDerivative
277  for (unsigned int j = 0; j < n_hj; ++j)
278  fj_temp[j] = Fj_w[i * n_hj + j];
279  for (unsigned int j = 0; j < n_etas + n_grs; ++j)
280  {
281  notarealvector[0] = all_etas[j];
282  params = _factory.getValidParams("CoupledSwitchingTimeDerivative");
283  params.set<NonlinearVariableName>("variable") = w_names[i];
284  params.set<std::vector<VariableName>>("v") = notarealvector;
285  params.set<std::vector<VariableName>>("args") = v0;
286  params.set<std::vector<MaterialPropertyName>>("Fj_names") = fj_temp;
287  params.set<std::vector<MaterialPropertyName>>("hj_names") = hj;
288  params.set<bool>("implicit") = implicity;
289  params.set<bool>("use_displaced_mesh") = displaced_mesh;
290  kernel_name = "Coupled_" + w_names[i] + "_" + all_etas[j];
291  _problem->addKernel("CoupledSwitchingTimeDerivative", kernel_name, params);
292  }
293  }
294 } // GrandPotentialKernelAction::act()
GrandPotentialKernelAction::act
virtual void act()
Definition: GrandPotentialKernelAction.C:81
validParams< GrandPotentialKernelAction >
InputParameters validParams< GrandPotentialKernelAction >()
Definition: GrandPotentialKernelAction.C:20
registerMooseAction
registerMooseAction("PhaseFieldApp", GrandPotentialKernelAction, "add_kernel")
GrandPotentialKernelAction::GrandPotentialKernelAction
GrandPotentialKernelAction(const InputParameters &parameters)
Definition: GrandPotentialKernelAction.C:75
GrandPotentialKernelAction.h
GrandPotentialKernelAction
Generates the necessary kernels for the Grand Potential Function for any number of order parameters a...
Definition: GrandPotentialKernelAction.h:37