https://mooseframework.inl.gov
NEML2Action.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 
10 #include "NEML2Action.h"
11 #include "NEML2ActionCommon.h"
12 #include "FEProblem.h"
13 #include "Factory.h"
14 #include "NEML2Utils.h"
16 
17 #ifdef NEML2_ENABLED
18 #include "neml2/base/Parser.h"
19 #endif
20 
21 registerMooseAction("MooseApp", NEML2Action, "parse_neml2");
22 registerMooseAction("MooseApp", NEML2Action, "add_material");
23 registerMooseAction("MooseApp", NEML2Action, "add_user_object");
24 
25 #ifdef NEML2_ENABLED
26 // NEML2 variable type --> MOOSE type
27 const std::map<neml2::TensorType, std::string> tensor_type_map = {
28  {neml2::TensorType::kScalar, "Real"},
29  {neml2::TensorType::kSR2, "SymmetricRankTwoTensor"},
30  {neml2::TensorType::kR2, "RankTwoTensor"},
31  {neml2::TensorType::kSSR4, "SymmetricRankFourTensor"},
32  {neml2::TensorType::kR4, "RankFourTensor"},
33  {neml2::TensorType::kRot, "RealVectorValue"}};
34 // NEML2 (output, input) type --> NEML2 derivative type
35 const std::map<std::pair<neml2::TensorType, neml2::TensorType>, neml2::TensorType> deriv_type_map =
36  {
37  {{neml2::TensorType::kScalar, neml2::TensorType::kScalar}, neml2::TensorType::kScalar},
38  {{neml2::TensorType::kSR2, neml2::TensorType::kSR2}, neml2::TensorType::kSSR4},
39  {{neml2::TensorType::kSR2, neml2::TensorType::kScalar}, neml2::TensorType::kSR2},
40  {{neml2::TensorType::kScalar, neml2::TensorType::kSR2}, neml2::TensorType::kSR2},
41  {{neml2::TensorType::kR2, neml2::TensorType::kR2}, neml2::TensorType::kR4},
42  {{neml2::TensorType::kR2, neml2::TensorType::kScalar}, neml2::TensorType::kR2},
43  {{neml2::TensorType::kScalar, neml2::TensorType::kR2}, neml2::TensorType::kR2},
44 };
45 #endif
46 
49 {
51  params.addClassDescription(NEML2Utils::docstring("Set up the NEML2 material model"));
52  params.addParam<std::string>(
53  "executor_name",
54  NEML2Utils::docstring("Name of the NEML2ModelExecutor user object. The default name is "
55  "'neml2_<model-name>_<block-name>' where <model-name> is the NEML2 "
56  "model's name, and <block-name> is this action sub-block's name."));
57  params.addParam<std::string>(
58  "batch_index_generator_name",
60  "Name of the NEML2BatchIndexGenerator user object. The default name is "
61  "'neml2_index_<model-name>_<block-name>' where <model-name> is the NEML2 model's name, "
62  "and <block-name> is this action sub-block's name."));
63  params.addParam<std::vector<SubdomainName>>(
64  "block",
65  {},
66  NEML2Utils::docstring("List of blocks (subdomains) where the material model is defined"));
67  return params;
68 }
69 
71  : Action(params),
72  _executor_name(isParamValid("executor_name")
73  ? getParam<std::string>("executor_name")
74  : "neml2_" + getParam<std::string>("model") + "_" + name()),
75  _idx_generator_name(isParamValid("batch_index_generator_name")
76  ? getParam<std::string>("batch_index_generator_name")
77  : "neml2_index_" + getParam<std::string>("model") + "_" + name()),
78  _block(getParam<std::vector<SubdomainName>>("block"))
79 {
81 
82  // Apply parameters under the common area, i.e., under [NEML2]
83  const auto & all_params = _app.getInputParameterWarehouse().getInputParameters();
84  auto & sub_block_params = *(all_params.find(uniqueActionName())->second.get());
85  const auto & common_action = getCommonAction();
86  sub_block_params.applyParameters(common_action.parameters());
87 
88  // Set up optional output variable initialization
89  auto init_vars = getParam<std::vector<MaterialPropertyName>>("initialize_outputs");
90  auto init_vals = getParam<std::vector<MaterialPropertyName>>("initialize_output_values");
91  if (init_vars.size() != init_vals.size())
92  paramError("initialize_outputs",
93  "initialize_outputs should have the same length as initialize_output_values");
94  for (auto i : index_range(init_vars))
95  _initialize_output_values[init_vars[i]] = init_vals[i];
96 
97  // Set up additional outputs for each requested material property
98  auto outputs = getParam<std::vector<MaterialPropertyName>>("export_outputs");
99  auto output_targets = getParam<std::vector<std::vector<OutputName>>>("export_output_targets");
100  if (outputs.size() != output_targets.size())
101  paramError("export_outputs",
102  "export_outputs should have the same length as export_output_targets");
103  for (auto i : index_range(outputs))
104  _export_output_targets[outputs[i]] = output_targets[i];
105 
106 #ifdef NEML2_ENABLED
107  // File name and CLI args
108  _fname = getParam<DataFileName>("input");
109  _cli_args = getParam<std::vector<std::string>>("cli_args");
110 
111  // Load input file
112  auto factory = neml2::load_input(std::string(_fname), neml2::utils::join(_cli_args, " "));
113  _model = NEML2Utils::getModel(*factory, getParam<std::string>("model"));
114 #endif
115 }
116 
117 const NEML2ActionCommon &
119 {
120  auto common_block = _awh.getActions<NEML2ActionCommon>();
121  mooseAssert(common_block.size() == 1, "There must exist one and only one common NEML2 action.");
122  return *common_block[0];
123 }
124 
125 #ifndef NEML2_ENABLED
126 
127 void
129 {
130 }
131 
132 #else
133 
134 void
136 {
137  if (_current_task == "parse_neml2")
138  {
139  if (_app.parameters().have_parameter<bool>("parse_neml2_only"))
140  if (!_app.parameters().get<bool>("parse_neml2_only"))
141  return;
142  printSummary();
143  }
144 
145  if (_current_task == "add_user_object")
146  {
152 
153  printSummary();
154 
155  // MOOSEToNEML2 input gatherers
156  std::vector<UserObjectName> gatherers;
157  for (const auto & input : _inputs)
158  {
159  if (input.moose.type == MOOSEIOType::MATERIAL)
160  {
161  auto obj_name = "__moose(" + input.moose.name + ")->neml2(" +
162  neml2::utils::stringify(input.neml2.name) + ")_" + name() + "__";
163  if (!tensor_type_map.count(input.neml2.type))
164  mooseError("NEML2 type ", input.neml2.type, " not yet mapped to MOOSE");
165  auto obj_moose_type = tensor_type_map.at(input.neml2.type) + "MaterialProperty";
166  if (input.neml2.name.is_old_force() || input.neml2.name.is_old_state())
167  obj_moose_type = "Old" + obj_moose_type;
168  auto obj_type = "MOOSE" + obj_moose_type + "ToNEML2";
169  auto obj_params = _factory.getValidParams(obj_type);
170  obj_params.set<MaterialPropertyName>("from_moose") = input.moose.name;
171  obj_params.set<std::string>("to_neml2") = neml2::utils::stringify(input.neml2.name);
172  obj_params.set<std::vector<SubdomainName>>("block") = _block;
173  _problem->addUserObject(obj_type, obj_name, obj_params);
174  gatherers.push_back(obj_name);
175  }
176  else if (input.moose.type == MOOSEIOType::VARIABLE)
177  {
178  auto obj_name = "__moose(" + input.moose.name + ")->neml2(" +
179  neml2::utils::stringify(input.neml2.name) + ")_" + name() + "__";
180  std::string obj_moose_type = "Variable";
181  if (input.neml2.name.is_old_force() || input.neml2.name.is_old_state())
182  obj_moose_type = "Old" + obj_moose_type;
183  auto obj_type = "MOOSE" + obj_moose_type + "ToNEML2";
184  auto obj_params = _factory.getValidParams(obj_type);
185  obj_params.set<std::vector<VariableName>>("from_moose") = {input.moose.name};
186  obj_params.set<std::string>("to_neml2") = neml2::utils::stringify(input.neml2.name);
187  obj_params.set<std::vector<SubdomainName>>("block") = _block;
188  _problem->addUserObject(obj_type, obj_name, obj_params);
189  gatherers.push_back(obj_name);
190  }
191  else if (input.moose.type == MOOSEIOType::POSTPROCESSOR)
192  {
193  auto obj_name = "__moose(" + input.moose.name + ")->neml2(" +
194  neml2::utils::stringify(input.neml2.name) + ")" + name() + "__";
195  auto obj_moose_type = std::string("Postprocessor");
196  if (input.neml2.name.is_old_force() || input.neml2.name.is_old_state())
197  obj_moose_type = "Old" + obj_moose_type;
198  auto obj_type = "MOOSE" + obj_moose_type + "ToNEML2";
199  auto obj_params = _factory.getValidParams(obj_type);
200  obj_params.set<PostprocessorName>("from_moose") = input.moose.name;
201  obj_params.set<std::string>("to_neml2") = neml2::utils::stringify(input.neml2.name);
202  _problem->addUserObject(obj_type, obj_name, obj_params);
203  gatherers.push_back(obj_name);
204  }
205  else
206  paramError("moose_input_types",
207  "Unsupported type corresponding to the moose input ",
208  input.moose.name);
209  }
210 
211  // MOOSEToNEML2 parameter gatherers
212  std::vector<UserObjectName> param_gatherers;
213  for (const auto & param : _params)
214  {
215  if (param.moose.type == MOOSEIOType::MATERIAL)
216  {
217  auto obj_name =
218  "__moose(" + param.moose.name + ")->neml2(" + param.neml2.name + ")_" + name() + "__";
219  if (!tensor_type_map.count(param.neml2.type))
220  mooseError("NEML2 type ", param.neml2.type, " not yet mapped to MOOSE");
221  auto obj_moose_type = tensor_type_map.at(param.neml2.type);
222  auto obj_type = "MOOSE" + obj_moose_type + "MaterialPropertyToNEML2";
223  auto obj_params = _factory.getValidParams(obj_type);
224  obj_params.set<MaterialPropertyName>("from_moose") = param.moose.name;
225  obj_params.set<std::string>("to_neml2") = param.neml2.name;
226  obj_params.set<std::vector<SubdomainName>>("block") = _block;
227  _problem->addUserObject(obj_type, obj_name, obj_params);
228  param_gatherers.push_back(obj_name);
229  }
230  else if (param.moose.type == MOOSEIOType::VARIABLE)
231  {
232  auto obj_name =
233  "__moose(" + param.moose.name + ")->neml2(" + param.neml2.name + ")_" + name() + "__";
234  auto obj_type = "MOOSEVariableToNEML2";
235  auto obj_params = _factory.getValidParams(obj_type);
236  obj_params.set<std::vector<VariableName>>("from_moose") = {param.moose.name};
237  obj_params.set<std::string>("to_neml2") = neml2::utils::stringify(param.neml2.name);
238  obj_params.set<std::vector<SubdomainName>>("block") = _block;
239  _problem->addUserObject(obj_type, obj_name, obj_params);
240  param_gatherers.push_back(obj_name);
241  }
242  else if (param.moose.type == MOOSEIOType::POSTPROCESSOR)
243  {
244  auto obj_name =
245  "__moose(" + param.moose.name + ")->neml2(" + param.neml2.name + ")" + name() + "__";
246  auto obj_moose_type = std::string("Postprocessor");
247  auto obj_type = "MOOSE" + obj_moose_type + "ToNEML2";
248  auto obj_params = _factory.getValidParams(obj_type);
249  obj_params.set<PostprocessorName>("from_moose") = param.moose.name;
250  obj_params.set<std::string>("to_neml2") = param.neml2.name;
251  _problem->addUserObject(obj_type, obj_name, obj_params);
252  param_gatherers.push_back(obj_name);
253  }
254  else
255  paramError("moose_parameter_types",
256  "Unsupported type corresponding to the moose parameter ",
257  param.moose.name);
258  }
259 
260  // The index generator UO
261  {
262  auto type = "NEML2BatchIndexGenerator";
263  auto params = _factory.getValidParams(type);
264  params.applyParameters(parameters());
265  _problem->addUserObject(type, _idx_generator_name, params);
266  }
267 
268  // The Executor UO
269  {
270  auto type = "NEML2ModelExecutor";
271  auto params = _factory.getValidParams(type);
272  params.applyParameters(parameters());
273  params.set<UserObjectName>("batch_index_generator") = _idx_generator_name;
274  params.set<std::vector<UserObjectName>>("gatherers") = gatherers;
275  params.set<std::vector<UserObjectName>>("param_gatherers") = param_gatherers;
276  _problem->addUserObject(type, _executor_name, params);
277  }
278  }
279 
280  if (_current_task == "add_material")
281  {
282  // NEML2ToMOOSE output retrievers
283  for (const auto & output : _outputs)
284  {
285  if (output.moose.type == MOOSEIOType::MATERIAL)
286  {
287  auto obj_name = "__neml2(" + neml2::utils::stringify(output.neml2.name) + ")->moose(" +
288  output.moose.name + ")_" + name() + "__";
289  if (!tensor_type_map.count(output.neml2.type))
290  mooseError("NEML2 type ", output.neml2.type, " not yet mapped to MOOSE");
291  auto obj_type = "NEML2ToMOOSE" + tensor_type_map.at(output.neml2.type) + "MaterialProperty";
292  auto obj_params = _factory.getValidParams(obj_type);
293  obj_params.set<UserObjectName>("neml2_executor") = _executor_name;
294  obj_params.set<MaterialPropertyName>("to_moose") = output.moose.name;
295  obj_params.set<std::string>("from_neml2") = neml2::utils::stringify(output.neml2.name);
296  obj_params.set<std::vector<SubdomainName>>("block") = _block;
297  if (_initialize_output_values.count(output.moose.name))
298  obj_params.set<MaterialPropertyName>("moose_material_property_init") =
299  _initialize_output_values[output.moose.name];
300  if (_export_output_targets.count(output.moose.name))
301  obj_params.set<std::vector<OutputName>>("outputs") =
302  _export_output_targets[output.moose.name];
303  _problem->addMaterial(obj_type, obj_name, obj_params);
304  }
305  else
306  paramError("moose_output_types",
307  "Unsupported type corresponding to the moose output ",
308  output.moose.name);
309  }
310 
311  // NEML2ToMOOSE derivative retrievers
312  for (const auto & deriv : _derivs)
313  {
314  if (deriv.moose.type == MOOSEIOType::MATERIAL)
315  {
316  auto obj_name = "__neml2(d(" + neml2::utils::stringify(deriv.neml2.y.name) + ")/d(" +
317  neml2::utils::stringify(deriv.neml2.x.name) + "))->moose(" +
318  deriv.moose.name + ")_" + name() + "__";
319  if (!deriv_type_map.count({deriv.neml2.y.type, deriv.neml2.x.type}))
320  mooseError("NEML2 derivative type for d(",
321  deriv.neml2.y.type,
322  ")/d(",
323  deriv.neml2.x.type,
324  ") not yet mapped to MOOSE");
325  auto deriv_type = deriv_type_map.at({deriv.neml2.y.type, deriv.neml2.x.type});
326  if (!tensor_type_map.count(deriv_type))
327  mooseError("NEML2 type ", deriv_type, " not yet mapped to MOOSE");
328  auto obj_type = "NEML2ToMOOSE" + tensor_type_map.at(deriv_type) + "MaterialProperty";
329  auto obj_params = _factory.getValidParams(obj_type);
330  obj_params.set<UserObjectName>("neml2_executor") = _executor_name;
331  obj_params.set<MaterialPropertyName>("to_moose") = deriv.moose.name;
332  obj_params.set<std::string>("from_neml2") = neml2::utils::stringify(deriv.neml2.y.name);
333  obj_params.set<std::string>("neml2_input_derivative") =
334  neml2::utils::stringify(deriv.neml2.x.name);
335  obj_params.set<std::vector<SubdomainName>>("block") = _block;
336  if (_export_output_targets.count(deriv.moose.name))
337  obj_params.set<std::vector<OutputName>>("outputs") =
338  _export_output_targets[deriv.moose.name];
339  _problem->addMaterial(obj_type, obj_name, obj_params);
340  }
341  else
342  paramError("moose_derivative_types",
343  "Unsupported type corresponding to the moose derivative ",
344  deriv.moose.name);
345  }
346 
347  // NEML2ToMOOSE parameter derivative retrievers
348  for (const auto & param_deriv : _param_derivs)
349  {
350  if (param_deriv.moose.type == MOOSEIOType::MATERIAL)
351  {
352  auto obj_name = "__neml2(d(" + neml2::utils::stringify(param_deriv.neml2.y.name) + ")/d(" +
353  param_deriv.neml2.x.name + "))->moose(" + param_deriv.moose.name + ")_" +
354  name() + "__";
355  if (!deriv_type_map.count({param_deriv.neml2.y.type, param_deriv.neml2.x.type}))
356  mooseError("NEML2 derivative type for d(",
357  param_deriv.neml2.y.type,
358  ")/d(",
359  param_deriv.neml2.x.type,
360  ") not yet mapped to MOOSE");
361  auto deriv_type = deriv_type_map.at({param_deriv.neml2.y.type, param_deriv.neml2.x.type});
362  if (!tensor_type_map.count(deriv_type))
363  mooseError("NEML2 type ", deriv_type, " not yet mapped to MOOSE");
364  auto obj_type = "NEML2ToMOOSE" + tensor_type_map.at(deriv_type) + "MaterialProperty";
365  auto obj_params = _factory.getValidParams(obj_type);
366  obj_params.set<UserObjectName>("neml2_executor") = _executor_name;
367  obj_params.set<MaterialPropertyName>("to_moose") = param_deriv.moose.name;
368  obj_params.set<std::string>("from_neml2") =
369  neml2::utils::stringify(param_deriv.neml2.y.name);
370  obj_params.set<std::string>("neml2_parameter_derivative") = param_deriv.neml2.x.name;
371  obj_params.set<std::vector<SubdomainName>>("block") = _block;
372  if (_export_output_targets.count(param_deriv.moose.name))
373  obj_params.set<std::vector<OutputName>>("outputs") =
374  _export_output_targets[param_deriv.moose.name];
375  _problem->addMaterial(obj_type, obj_name, obj_params);
376  }
377  else
378  paramError("moose_parameter_derivative_types",
379  "Unsupported type corresponding to the moose parameter derivative ",
380  param_deriv.moose.name);
381  }
382  }
383 }
384 
385 void
386 NEML2Action::setupInputMappings(const neml2::Model & model)
387 {
388  const auto [moose_input_types, moose_inputs, neml2_inputs] =
389  getInputParameterMapping<MOOSEIOType, std::string, std::string>(
390  "moose_input_types", "moose_inputs", "neml2_inputs");
391 
392  for (auto i : index_range(moose_inputs))
393  {
394  auto neml2_input = NEML2Utils::parseVariableName(neml2_inputs[i]);
395  _inputs.push_back({
396  {moose_inputs[i], moose_input_types[i]},
397  {neml2_input, model.input_variable(neml2_input).type()},
398  });
399  }
400 }
401 
402 void
403 NEML2Action::setupParameterMappings(const neml2::Model & model)
404 {
405  const auto [moose_param_types, moose_params, neml2_params] =
406  getInputParameterMapping<MOOSEIOType, std::string, std::string>(
407  "moose_parameter_types", "moose_parameters", "neml2_parameters");
408 
409  for (auto i : index_range(moose_params))
410  _params.push_back({{moose_params[i], moose_param_types[i]},
411  {neml2_params[i], model.get_parameter(neml2_params[i]).type()}});
412 }
413 
414 void
415 NEML2Action::setupOutputMappings(const neml2::Model & model)
416 {
417  const auto [moose_output_types, moose_outputs, neml2_outputs] =
418  getInputParameterMapping<MOOSEIOType, std::string, std::string>(
419  "moose_output_types", "moose_outputs", "neml2_outputs");
420 
421  for (auto i : index_range(moose_outputs))
422  {
423  auto neml2_output = NEML2Utils::parseVariableName(neml2_outputs[i]);
424  _outputs.push_back({
425  {moose_outputs[i], moose_output_types[i]},
426  {neml2_output, model.output_variable(neml2_output).type()},
427  });
428  }
429 }
430 
431 void
432 NEML2Action::setupDerivativeMappings(const neml2::Model & model)
433 {
434  const auto [moose_deriv_types, moose_derivs, neml2_derivs] =
435  getInputParameterMapping<MOOSEIOType, std::string, std::vector<std::string>>(
436  "moose_derivative_types", "moose_derivatives", "neml2_derivatives");
437 
438  for (auto i : index_range(moose_derivs))
439  {
440  if (neml2_derivs[i].size() != 2)
441  paramError("neml2_derivatives", "The length of each pair in neml2_derivatives must be 2.");
442 
443  auto neml2_y = NEML2Utils::parseVariableName(neml2_derivs[i][0]);
444  auto neml2_x = NEML2Utils::parseVariableName(neml2_derivs[i][1]);
445  _derivs.push_back({
446  {moose_derivs[i], moose_deriv_types[i]},
447  {{neml2_y, model.output_variable(neml2_y).type()},
448  {neml2_x, model.input_variable(neml2_x).type()}},
449  });
450  }
451 }
452 
453 void
455 {
456  const auto [moose_param_deriv_types, moose_param_derivs, neml2_param_derivs] =
457  getInputParameterMapping<MOOSEIOType, std::string, std::vector<std::string>>(
458  "moose_parameter_derivative_types",
459  "moose_parameter_derivatives",
460  "neml2_parameter_derivatives");
461 
462  for (auto i : index_range(moose_param_derivs))
463  {
464  if (neml2_param_derivs[i].size() != 2)
465  paramError("neml2_parameter_derivatives",
466  "The length of each pair in neml2_parameter_derivatives must be 2.");
467 
468  auto neml2_y = NEML2Utils::parseVariableName(neml2_param_derivs[i][0]);
469  auto neml2_x = neml2_param_derivs[i][1];
470  _param_derivs.push_back({
471  {moose_param_derivs[i], moose_param_deriv_types[i]},
472  {{neml2_y, model.output_variable(neml2_y).type()},
473  {neml2_x, model.get_parameter(neml2_x).type()}},
474  });
475  }
476 }
477 
478 void
480 {
481  if (!_app.parameters().have_parameter<bool>("parse_neml2_only"))
482  return;
483 
484  // Save formatting of the output stream so that we can restore it later
485  const auto flags = _console.flags();
486 
487  // Default width for the summary
488  const int width = 79;
489 
490  _console << std::endl;
491  _console << COLOR_CYAN << std::setw(width) << std::setfill('*') << std::left
492  << "NEML2 MATERIAL MODEL SUMMARY BEGIN " << std::setfill(' ') << COLOR_DEFAULT
493  << std::endl;
494 
495  // Metadata
496  _console << "NEML2 input file location: " << fname() << std::endl;
497  _console << "NEML2 action path: " << parameters().blockFullpath() << std::endl;
498 
499  // List inputs, outputs, and parameters of the model
500  _console << COLOR_CYAN << std::setw(width) << std::setfill('-') << std::left
501  << "Material model structure " << std::setfill(' ') << COLOR_DEFAULT << std::endl;
502  _console << *_model;
503 
504  // List transfer between MOOSE and NEML2
505  if (!_app.parameters().get<bool>("parse_neml2_only"))
506  {
507  _console << COLOR_CYAN << std::setw(width) << std::setfill('-') << std::left
508  << "Transfer between MOOSE and NEML2 " << std::setfill(' ') << COLOR_DEFAULT
509  << std::endl;
510 
511  // Figure out the longest name length so that we could align the arrows
512  const auto max_moose_name_length = getLongestMOOSEName();
513 
514  // List input transfer, MOOSE -> NEML2
515  for (const auto & input : _inputs)
516  {
517  _console << std::setw(max_moose_name_length) << std::right
518  << (input.neml2.name.is_old_force() || input.neml2.name.is_old_state()
519  ? ("(old) " + input.moose.name)
520  : input.moose.name)
521  << " --> " << input.neml2.name << std::endl;
522  }
523 
524  // List parameter transfer, MOOSE -> NEML2
525  for (const auto & param : _params)
526  _console << std::setw(max_moose_name_length) << std::right << param.moose.name << " --> "
527  << param.neml2.name << std::endl;
528 
529  // List output transfer, NEML2 -> MOOSE
530  for (const auto & output : _outputs)
531  _console << std::setw(max_moose_name_length) << std::right << output.moose.name << " <-- "
532  << output.neml2.name << std::endl;
533 
534  // List derivative transfer, NEML2 -> MOOSE
535  for (const auto & deriv : _derivs)
536  _console << std::setw(max_moose_name_length) << std::right << deriv.moose.name << " <-- d("
537  << deriv.neml2.y.name << ")/d(" << deriv.neml2.x.name << ")" << std::endl;
538 
539  // List parameter derivative transfer, NEML2 -> MOOSE
540  for (const auto & param_deriv : _param_derivs)
541  _console << std::setw(max_moose_name_length) << std::right << param_deriv.moose.name
542  << " <-- d(" << param_deriv.neml2.y.name << ")/d(" << param_deriv.neml2.x.name << ")"
543  << std::endl;
544  }
545 
546  _console << COLOR_CYAN << std::setw(width) << std::setfill('*') << std::left
547  << "NEML2 MATERIAL MODEL SUMMARY END " << std::setfill(' ') << COLOR_DEFAULT << std::endl
548  << std::endl;
549 
550  // Restore the formatting of the output stream
551  _console.flags(flags);
552 }
553 
554 std::size_t
556 {
557  std::size_t max_moose_name_length = 0;
558  for (const auto & input : _inputs)
559  max_moose_name_length =
560  std::max(max_moose_name_length,
561  input.neml2.name.is_old_force() || input.neml2.name.is_old_state()
562  ? input.moose.name.size() + 6
563  : input.moose.name.size()); // 6 is the length of "(old) "
564  for (const auto & param : _params)
565  max_moose_name_length = std::max(max_moose_name_length, param.moose.name.size());
566  for (const auto & output : _outputs)
567  max_moose_name_length = std::max(max_moose_name_length, output.moose.name.size());
568  for (const auto & deriv : _derivs)
569  max_moose_name_length = std::max(max_moose_name_length, deriv.moose.name.size());
570  for (const auto & param_deriv : _param_derivs)
571  max_moose_name_length = std::max(max_moose_name_length, param_deriv.moose.name.size());
572  return max_moose_name_length;
573 }
574 #endif // NEML2_ENABLED
std::string name(const ElemQuality q)
std::string join(Iterator begin, Iterator end, const std::string &delimiter)
Python-like join function for strings over an iterator range.
Definition: MooseUtils.h:142
ActionWarehouse & _awh
Reference to ActionWarehouse where we store object build by actions.
Definition: Action.h:159
std::vector< std::string > _cli_args
List of cli-args.
Definition: NEML2Action.h:117
std::vector< std::pair< R1, R2 > > get(const std::string &param1, const std::string &param2) const
Combine two vector parameters into a single vector of pairs.
const FileName & fname() const
Definition: NEML2Action.h:39
InputParameterWarehouse & getInputParameterWarehouse()
Get the InputParameterWarehouse for MooseObjects.
Definition: MooseApp.C:2865
std::ios_base::fmtflags flags() const
Return the current flags.
Definition: ConsoleStream.C:56
std::vector< DerivativeMapping > _derivs
MOOSE-NEML2 derivative mappings.
Definition: NEML2Action.h:132
std::map< MaterialPropertyName, std::vector< OutputName > > _export_output_targets
Material property additional outputs.
Definition: NEML2Action.h:151
T & set(const std::string &name, bool quiet_mode=false)
Returns a writable reference to the named parameters.
InputParameters getValidParams(const std::string &name) const
Get valid parameters for the object.
Definition: Factory.C:68
Action to set up NEML2 objects.
Definition: NEML2Action.h:25
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
void applyParameters(const InputParameters &common, const std::vector< std::string > &exclude={}, const bool allow_private=false)
Method for applying common parameters.
Input parameters common to all block-restricted NEML2Actions.
const std::map< neml2::TensorType, std::string > tensor_type_map
Definition: NEML2Action.C:27
MooseObjectName uniqueActionName() const
The unique name for accessing input parameters of this action in the InputParameterWarehouse.
Definition: Action.h:98
void setupParameterDerivativeMappings(const neml2::Model &)
Set up MOOSE-NEML2 parameter derivative mappings.
Definition: NEML2Action.C:454
const InputParameters & parameters()
Get the parameters of the object.
Definition: MooseApp.h:161
virtual const std::string & name() const
Get the name of the class.
Definition: MooseBase.h:57
Base class for actions.
Definition: Action.h:33
auto max(const L &left, const R &right)
Factory & _factory
The Factory associated with the MooseApp.
const std::vector< SubdomainName > _block
Blocks this sub-block action applies to.
Definition: NEML2Action.h:145
virtual void act() override
Method to add objects to the simulation or perform other setup tasks.
Definition: NEML2Action.C:128
const UserObjectName _executor_name
Name of the NEML2Executor user object.
Definition: NEML2Action.h:139
Real deriv(unsigned n, unsigned alpha, unsigned beta, Real x)
const std::multimap< MooseObjectName, std::shared_ptr< InputParameters > > & getInputParameters(THREAD_ID tid=0) const
Return const reference to the map containing the InputParameter objects.
std::shared_ptr< neml2::Model > _model
The neml2 model.
Definition: NEML2Action.h:120
void printSummary() const
Print a summary of the NEML2 model.
Definition: NEML2Action.C:479
const std::string & type() const
Get the type of this class.
Definition: MooseBase.h:51
std::string docstring(const std::string &desc)
Augment docstring if NEML2 is not enabled.
Definition: NEML2Utils.C:77
const std::string & _current_task
The current action (even though we have separate instances for each action)
Definition: Action.h:162
std::map< MaterialPropertyName, MaterialPropertyName > _initialize_output_values
Material property initial conditions.
Definition: NEML2Action.h:148
const std::map< std::pair< neml2::TensorType, neml2::TensorType >, neml2::TensorType > deriv_type_map
Definition: NEML2Action.C:35
MooseApp & _app
The MOOSE application this is associated with.
Definition: MooseBase.h:84
void paramError(const std::string &param, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
std::vector< ParameterDerivativeMapping > _param_derivs
MOOSE-NEML2 parameter derivative mappings.
Definition: NEML2Action.h:135
std::string stringify(const T &t)
conversion to string
Definition: Conversion.h:64
void setupParameterMappings(const neml2::Model &)
Set up MOOSE-NEML2 model parameter mappings.
Definition: NEML2Action.C:403
FileName _fname
Name of the NEML2 input file.
Definition: NEML2Action.h:114
const NEML2ActionCommon & getCommonAction() const
Definition: NEML2Action.C:118
NEML2Action(const InputParameters &)
Definition: NEML2Action.C:70
bool have_parameter(std::string_view name) const
A wrapper around the Parameters base class method.
void assertNEML2Enabled()
Assert that NEML2 is enabled.
Definition: NEML2Utils.C:87
std::shared_ptr< neml2::Model > getModel(neml2::Factory &factory, const std::string &name, neml2::Dtype dtype=neml2::kFloat64)
Get the NEML2 Model.
Definition: NEML2Utils.C:18
void setupInputMappings(const neml2::Model &)
Set up MOOSE-NEML2 input variable mappings.
Definition: NEML2Action.C:386
std::string blockFullpath() const
void setupDerivativeMappings(const neml2::Model &)
Set up MOOSE-NEML2 derivative mappings.
Definition: NEML2Action.C:432
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type.
static InputParameters validParams()
Definition: NEML2Action.C:48
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:168
const InputParameters & parameters() const
Get the parameters of the object.
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an optional parameter and a documentation string to the InputParameters object...
const ConsoleStream _console
An instance of helper class to write streams to the Console objects.
void setupOutputMappings(const neml2::Model &)
Set up MOOSE-NEML2 output variable mappings.
Definition: NEML2Action.C:415
const UserObjectName _idx_generator_name
Name of the NEML2BatchIndexGenerator user object.
Definition: NEML2Action.h:142
registerMooseAction("MooseApp", NEML2Action, "parse_neml2")
std::vector< const T * > getActions()
Retrieve all actions in a specific type ordered by their names.
std::size_t getLongestMOOSEName() const
Get the maximum length of all MOOSE names (for printing purposes)
Definition: NEML2Action.C:555
std::vector< VariableMapping > _outputs
MOOSE-NEML2 output variable mappings.
Definition: NEML2Action.h:129
std::vector< ParameterMapping > _params
MOOSE-NEML2 model parameter mappings.
Definition: NEML2Action.h:126
neml2::VariableName parseVariableName(const std::string &)
Parse a raw string into NEML2 variable name.
Definition: NEML2Utils.C:49
auto index_range(const T &sizable)
std::vector< VariableMapping > _inputs
MOOSE-NEML2 input variable mappings.
Definition: NEML2Action.h:123
static InputParameters commonParams()
Parameters that can be specified EITHER under the common area OR under sub-blocks.