www.mooseframework.org
MaterialDerivativeTestAction.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 
12 #include "Conversion.h"
13 #include "MooseEnum.h"
14 #include "FEProblemBase.h"
15 #include "MoosePreconditioner.h"
16 #include "NonlinearSystemBase.h"
17 #include "MooseVariableBase.h"
18 
19 #include "libmesh/fe.h"
20 #include "libmesh/string_to_enum.h"
21 
22 registerMooseAction("MooseApp", MaterialDerivativeTestAction, "add_variable");
23 
24 registerMooseAction("MooseApp", MaterialDerivativeTestAction, "add_kernel");
25 
26 registerMooseAction("MooseApp", MaterialDerivativeTestAction, "add_preconditioning");
27 
30 {
32  params.addClassDescription(
33  "Action for setting up the necessary objects for debugging material property derivatives.");
34  params.addParam<std::vector<VariableName>>("args",
35  "Variables the tested material property depends on.");
36  params.addRequiredParam<MaterialPropertyName>(
37  "prop_name", "Name of the material property to test the derivatives of.");
38  MooseEnum prop_type_enum("Real RankTwoTensor RankFourTensor");
39  params.addParam<MooseEnum>(
40  "prop_type", prop_type_enum, "Type of the material property to test the derivatives of.");
41  params.addParam<unsigned int>(
42  "derivative_order", 0, "Highest order derivative to test derivatives of.");
43  return params;
44 }
45 
47  : Action(parameters),
48  _args(getParam<std::vector<VariableName>>("args")),
49  _prop_name(getParam<MaterialPropertyName>("prop_name")),
50  _prop_type(getParam<MooseEnum>("prop_type").getEnum<PropTypeEnum>()),
51  _derivative_order(getParam<unsigned int>("derivative_order")),
52  _second(false),
53  _derivatives({{_prop_name, {}}})
54 {
55  std::vector<std::vector<std::vector<SymbolName>>> derivative_table(_derivative_order + 1);
56 
57  // 0th derivative is a (single) derivative w.r.t. to _no_ variables
58  derivative_table[0] = {{}};
59 
60  // build higher order derivatives
61  for (unsigned int n = 1; n <= _derivative_order; ++n)
62  for (const auto & function : derivative_table[n - 1])
63  for (const auto & var : _args)
64  {
65  // take previous order derivative and derive w.r.t. one of the args
66  auto derivative = std::vector<SymbolName>(function);
67  derivative.push_back(var);
68 
69  // add derivative to list
70  derivative_table[n].push_back(derivative);
71  _derivatives.insert(
72  std::make_pair(derivativePropertyName(_prop_name, derivative), derivative));
73  }
74 }
75 
76 void
78 {
79  // finite element type
80  const std::string order = _second ? "SECOND" : "FIRST";
81  const std::string family("LAGRANGE");
82  const auto type = "MooseVariable";
83  auto params = _factory.getValidParams(type);
84  params.set<MooseEnum>("order") = order;
85  params.set<MooseEnum>("family") = family;
86 
87  // build higher order derivatives
88  for (const auto & derivative : _derivatives)
89  {
90  // Create variables
91  if (_current_task == "add_variable")
92  {
93  switch (_prop_type)
94  {
95  case PropTypeEnum::REAL:
96  _problem->addVariable(type, "var_" + derivative.first, params);
97  break;
98 
100  for (unsigned int i = 0; i < 3; ++i)
101  for (unsigned int j = 0; j < 3; ++j)
102  _problem->addVariable(type,
103  "var_" + derivative.first + '_' + Moose::stringify(i) + '_' +
104  Moose::stringify(j),
105  params);
106  break;
107 
109  for (unsigned int i = 0; i < 3; ++i)
110  for (unsigned int j = 0; j < 3; ++j)
111  for (unsigned int k = 0; k < 3; ++k)
112  for (unsigned int l = 0; l < 3; ++l)
113  _problem->addVariable(type,
114  "var_" + derivative.first + '_' + Moose::stringify(i) +
115  '_' + Moose::stringify(j) + '_' + Moose::stringify(k) +
116  '_' + Moose::stringify(l),
117  params);
118  break;
119 
120  default:
121  mooseError("Unknown property type.");
122  }
123  }
124 
125  if (_current_task == "add_kernel")
126  {
127  switch (_prop_type)
128  {
129  case PropTypeEnum::REAL:
130  {
131  auto params = _factory.getValidParams("MaterialDerivativeTestKernel");
132  params.set<std::vector<VariableName>>("args") = _args;
133  params.set<std::vector<SymbolName>>("derivative") = derivative.second;
134  params.set<MaterialPropertyName>("material_property") = _prop_name;
135  params.set<NonlinearVariableName>("variable") = "var_" + derivative.first;
136  _problem->addKernel("MaterialDerivativeTestKernel", "kernel_" + derivative.first, params);
137  break;
138  }
139 
141  {
142  auto params = _factory.getValidParams("MaterialDerivativeRankTwoTestKernel");
143  params.set<std::vector<VariableName>>("args") = _args;
144  params.set<std::vector<SymbolName>>("derivative") = derivative.second;
145  params.set<MaterialPropertyName>("material_property") = _prop_name;
146  for (unsigned int i = 0; i < 3; ++i)
147  for (unsigned int j = 0; j < 3; ++j)
148  {
149  auto suffix =
150  derivative.first + '_' + Moose::stringify(i) + '_' + Moose::stringify(j);
151  params.set<NonlinearVariableName>("variable") = "var_" + suffix;
152  params.set<unsigned int>("i") = i;
153  params.set<unsigned int>("j") = j;
154  _problem->addKernel(
155  "MaterialDerivativeRankTwoTestKernel", "kernel_" + suffix, params);
156  }
157  break;
158  }
159 
161  {
162  auto params = _factory.getValidParams("MaterialDerivativeRankFourTestKernel");
163  params.set<std::vector<VariableName>>("args") = _args;
164  params.set<std::vector<SymbolName>>("derivative") = derivative.second;
165  params.set<MaterialPropertyName>("material_property") = _prop_name;
166  for (unsigned int i = 0; i < 3; ++i)
167  for (unsigned int j = 0; j < 3; ++j)
168  for (unsigned int k = 0; k < 3; ++k)
169  for (unsigned int l = 0; l < 3; ++l)
170  {
171  auto suffix = derivative.first + '_' + Moose::stringify(i) + '_' +
172  Moose::stringify(j) + '_' + Moose::stringify(k) + '_' +
173  Moose::stringify(l);
174  params.set<NonlinearVariableName>("variable") = "var_" + suffix;
175  params.set<unsigned int>("i") = i;
176  params.set<unsigned int>("j") = j;
177  params.set<unsigned int>("k") = k;
178  params.set<unsigned int>("l") = l;
179  _problem->addKernel(
180  "MaterialDerivativeRankFourTestKernel", "kernel_" + suffix, params);
181  }
182  break;
183  }
184 
185  default:
186  mooseError("Unknown property type.");
187  }
188  }
189  }
190 
191  if (_current_task == "add_preconditioning")
192  {
193  auto params = _factory.getValidParams("SMP");
194  auto & row = params.set<std::vector<NonlinearVariableName>>("off_diag_row");
195  auto & col = params.set<std::vector<NonlinearVariableName>>("off_diag_column");
196 
197  for (const auto & derivative : _derivatives)
198  {
199  switch (_prop_type)
200  {
201  case PropTypeEnum::REAL:
202  for (auto & arg : _args)
203  {
204  row.push_back("var_" + derivative.first);
205  col.push_back(arg);
206  }
207  break;
208 
210  for (unsigned int i = 0; i < 3; ++i)
211  for (unsigned int j = 0; j < 3; ++j)
212  for (auto & arg : _args)
213  {
214  row.push_back("var_" + derivative.first + '_' + Moose::stringify(i) + '_' +
215  Moose::stringify(j));
216  col.push_back(arg);
217  }
218  break;
219 
221  for (unsigned int i = 0; i < 3; ++i)
222  for (unsigned int j = 0; j < 3; ++j)
223  for (unsigned int k = 0; k < 3; ++k)
224  for (unsigned int l = 0; l < 3; ++l)
225  for (auto & arg : _args)
226  {
227  row.push_back("var_" + derivative.first + '_' + Moose::stringify(i) + '_' +
228  Moose::stringify(j) + '_' + Moose::stringify(k) + '_' +
229  Moose::stringify(l));
230  col.push_back(arg);
231  }
232  break;
233 
234  default:
235  mooseError("Unknown property type.");
236  }
237  }
238 
239  if (_problem.get() != nullptr)
240  {
241  std::shared_ptr<MoosePreconditioner> pc =
242  _factory.create<MoosePreconditioner>("SMP", "material_derivative_SMP", params);
243 
244  _problem->getNonlinearSystemBase(/*nl_sys=*/0).setPreconditioner(pc);
245  }
246  else
247  mooseError("_problem.get() returned nullptr");
248  }
249 }
Sets up variables and Kernels to test the derivatives of material properties via the Jacobian checker...
std::map< MaterialPropertyName, std::vector< SymbolName > > _derivatives
every derivative given by a list of variables to derive w.r.t
T & set(const std::string &name, bool quiet_mode=false)
Returns a writable reference to the named parameters.
std::shared_ptr< MooseObject > create(const std::string &obj_name, const std::string &name, const InputParameters &parameters, THREAD_ID tid=0, bool print_deprecated=true)
Definition: Factory.C:110
InputParameters getValidParams(const std::string &name) const
Get valid parameters for the object.
Definition: Factory.C:67
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
registerMooseAction("MooseApp", MaterialDerivativeTestAction, "add_variable")
Base class for actions.
Definition: Action.h:38
void addRequiredParam(const std::string &name, const std::string &doc_string)
This method adds a parameter and documentation string to the InputParameters object that will be extr...
Base class for MOOSE preconditioners.
Factory & _factory
The Factory associated with the MooseApp.
static InputParameters validParams()
Definition: Action.C:24
const std::string & type() const
Get the type of this class.
Definition: MooseBase.h:51
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition: MooseEnum.h:31
const std::string & _current_task
The current action (even though we have separate instances for each action)
Definition: Action.h:173
std::string stringify(const T &t)
conversion to string
Definition: Conversion.h:62
MaterialDerivativeTestAction(const InputParameters &parameters)
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type.
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...
std::shared_ptr< FEProblemBase > & _problem
Convenience reference to a problem this action works on.
Definition: Action.h:179
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an option parameter and a documentation string to the InputParameters object...
enum MaterialDerivativeTestAction::PropTypeEnum _prop_type
void ErrorVector unsigned int
virtual void act() override
Method to add objects to the simulation or perform other setup tasks.