18 #include "neml2/base/Parser.h" 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"}};
35 const std::map<std::pair<neml2::TensorType, neml2::TensorType>, neml2::TensorType>
deriv_type_map =
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},
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."));
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>>(
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"))
84 auto & sub_block_params = *(all_params.find(
uniqueActionName())->second.get());
86 sub_block_params.applyParameters(common_action.parameters());
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())
93 "initialize_outputs should have the same length as initialize_output_values");
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())
102 "export_outputs should have the same length as export_output_targets");
108 _fname = getParam<DataFileName>(
"input");
109 _cli_args = getParam<std::vector<std::string>>(
"cli_args");
121 mooseAssert(common_block.size() == 1,
"There must exist one and only one common NEML2 action.");
122 return *common_block[0];
125 #ifndef NEML2_ENABLED 156 std::vector<UserObjectName> gatherers;
157 for (
const auto & input :
_inputs)
161 auto obj_name =
"__moose(" + input.moose.name +
")->neml2(" +
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";
170 obj_params.
set<MaterialPropertyName>(
"from_moose") = input.moose.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);
178 auto obj_name =
"__moose(" + input.moose.name +
")->neml2(" +
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";
185 obj_params.
set<std::vector<VariableName>>(
"from_moose") = {input.moose.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);
193 auto obj_name =
"__moose(" + input.moose.name +
")->neml2(" +
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";
200 obj_params.
set<PostprocessorName>(
"from_moose") = input.moose.name;
202 _problem->addUserObject(obj_type, obj_name, obj_params);
203 gatherers.push_back(obj_name);
207 "Unsupported type corresponding to the moose input ",
212 std::vector<UserObjectName> param_gatherers;
213 for (
const auto & param :
_params)
218 "__moose(" + param.moose.name +
")->neml2(" + param.neml2.name +
")_" +
name() +
"__";
220 mooseError(
"NEML2 type ", param.neml2.type,
" not yet mapped to MOOSE");
222 auto obj_type =
"MOOSE" + obj_moose_type +
"MaterialPropertyToNEML2";
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);
233 "__moose(" + param.moose.name +
")->neml2(" + param.neml2.name +
")_" +
name() +
"__";
234 auto obj_type =
"MOOSEVariableToNEML2";
236 obj_params.
set<std::vector<VariableName>>(
"from_moose") = {param.moose.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);
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";
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);
256 "Unsupported type corresponding to the moose parameter ",
262 auto type =
"NEML2BatchIndexGenerator";
270 auto type =
"NEML2ModelExecutor";
274 params.set<std::vector<UserObjectName>>(
"gatherers") = gatherers;
275 params.set<std::vector<UserObjectName>>(
"param_gatherers") = param_gatherers;
283 for (
const auto & output :
_outputs)
288 output.moose.name +
")_" +
name() +
"__";
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";
294 obj_params.set<MaterialPropertyName>(
"to_moose") = output.moose.name;
296 obj_params.set<std::vector<SubdomainName>>(
"block") =
_block;
298 obj_params.set<MaterialPropertyName>(
"moose_material_property_init") =
301 obj_params.set<std::vector<OutputName>>(
"outputs") =
303 _problem->addMaterial(obj_type, obj_name, obj_params);
307 "Unsupported type corresponding to the moose output ",
312 for (
const auto & deriv :
_derivs)
319 if (!
deriv_type_map.count({deriv.neml2.y.type, deriv.neml2.x.type}))
324 ") not yet mapped to MOOSE");
327 mooseError(
"NEML2 type ", deriv_type,
" not yet mapped to MOOSE");
328 auto obj_type =
"NEML2ToMOOSE" +
tensor_type_map.at(deriv_type) +
"MaterialProperty";
331 obj_params.set<MaterialPropertyName>(
"to_moose") =
deriv.moose.name;
333 obj_params.set<std::string>(
"neml2_input_derivative") =
335 obj_params.set<std::vector<SubdomainName>>(
"block") =
_block;
337 obj_params.set<std::vector<OutputName>>(
"outputs") =
339 _problem->addMaterial(obj_type, obj_name, obj_params);
343 "Unsupported type corresponding to the moose derivative ",
353 param_deriv.neml2.x.name +
"))->moose(" + param_deriv.moose.name +
")_" +
355 if (!
deriv_type_map.count({param_deriv.neml2.y.type, param_deriv.neml2.x.type}))
357 param_deriv.neml2.y.type,
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});
363 mooseError(
"NEML2 type ", deriv_type,
" not yet mapped to MOOSE");
364 auto obj_type =
"NEML2ToMOOSE" +
tensor_type_map.at(deriv_type) +
"MaterialProperty";
367 obj_params.set<MaterialPropertyName>(
"to_moose") = param_deriv.moose.name;
368 obj_params.set<std::string>(
"from_neml2") =
370 obj_params.set<std::string>(
"neml2_parameter_derivative") = param_deriv.neml2.x.name;
371 obj_params.set<std::vector<SubdomainName>>(
"block") =
_block;
373 obj_params.set<std::vector<OutputName>>(
"outputs") =
375 _problem->addMaterial(obj_type, obj_name, obj_params);
378 paramError(
"moose_parameter_derivative_types",
379 "Unsupported type corresponding to the moose parameter derivative ",
380 param_deriv.moose.name);
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");
396 {moose_inputs[i], moose_input_types[i]},
397 {neml2_input, model.input_variable(neml2_input).type()},
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");
410 _params.push_back({{moose_params[i], moose_param_types[i]},
411 {neml2_params[i], model.get_parameter(neml2_params[i]).type()}});
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");
425 {moose_outputs[i], moose_output_types[i]},
426 {neml2_output, model.output_variable(neml2_output).type()},
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");
440 if (neml2_derivs[i].size() != 2)
441 paramError(
"neml2_derivatives",
"The length of each pair in neml2_derivatives must be 2.");
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()}},
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");
464 if (neml2_param_derivs[i].size() != 2)
466 "The length of each pair in neml2_parameter_derivatives must be 2.");
469 auto neml2_x = neml2_param_derivs[i][1];
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()}},
488 const int width = 79;
491 _console << COLOR_CYAN << std::setw(width) << std::setfill(
'*') << std::left
492 <<
"NEML2 MATERIAL MODEL SUMMARY BEGIN " << std::setfill(
' ') << COLOR_DEFAULT
496 _console <<
"NEML2 input file location: " <<
fname() << std::endl;
500 _console << COLOR_CYAN << std::setw(width) << std::setfill(
'-') << std::left
501 <<
"Material model structure " << std::setfill(
' ') << COLOR_DEFAULT << std::endl;
507 _console << COLOR_CYAN << std::setw(width) << std::setfill(
'-') << std::left
508 <<
"Transfer between MOOSE and NEML2 " << std::setfill(
' ') << COLOR_DEFAULT
515 for (
const auto & input :
_inputs)
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)
521 <<
" --> " << input.neml2.name << std::endl;
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;
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;
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;
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 <<
")" 546 _console << COLOR_CYAN << std::setw(width) << std::setfill(
'*') << std::left
547 <<
"NEML2 MATERIAL MODEL SUMMARY END " << std::setfill(
' ') << COLOR_DEFAULT << std::endl
557 std::size_t max_moose_name_length = 0;
558 for (
const auto & input :
_inputs)
559 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());
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());
569 max_moose_name_length =
std::max(max_moose_name_length,
deriv.moose.name.size());
571 max_moose_name_length =
std::max(max_moose_name_length, param_deriv.moose.name.size());
572 return max_moose_name_length;
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.
ActionWarehouse & _awh
Reference to ActionWarehouse where we store object build by actions.
std::vector< std::string > _cli_args
List of cli-args.
const FileName & fname() const
InputParameterWarehouse & getInputParameterWarehouse()
Get the InputParameterWarehouse for MooseObjects.
std::ios_base::fmtflags flags() const
Return the current flags.
std::vector< DerivativeMapping > _derivs
MOOSE-NEML2 derivative mappings.
std::map< MaterialPropertyName, std::vector< OutputName > > _export_output_targets
Material property additional outputs.
InputParameters getValidParams(const std::string &name) const
Get valid parameters for the object.
Action to set up NEML2 objects.
Input parameters common to all block-restricted NEML2Actions.
const std::map< neml2::TensorType, std::string > tensor_type_map
MooseObjectName uniqueActionName() const
The unique name for accessing input parameters of this action in the InputParameterWarehouse.
void setupParameterDerivativeMappings(const neml2::Model &)
Set up MOOSE-NEML2 parameter derivative mappings.
const InputParameters & parameters()
Get the parameters of the object.
virtual const std::string & name() const
Get the name of the class.
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.
virtual void act() override
Method to add objects to the simulation or perform other setup tasks.
const UserObjectName _executor_name
Name of the NEML2Executor user object.
Real deriv(unsigned n, unsigned alpha, unsigned beta, Real x)
std::shared_ptr< neml2::Model > _model
The neml2 model.
void printSummary() const
Print a summary of the NEML2 model.
const std::string & type() const
Get the type of this class.
std::string docstring(const std::string &desc)
Augment docstring if NEML2 is not enabled.
const std::string & _current_task
The current action (even though we have separate instances for each action)
std::map< MaterialPropertyName, MaterialPropertyName > _initialize_output_values
Material property initial conditions.
const std::map< std::pair< neml2::TensorType, neml2::TensorType >, neml2::TensorType > deriv_type_map
MooseApp & _app
The MOOSE application this is associated with.
void paramError(const std::string ¶m, 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.
std::string stringify(const T &t)
conversion to string
void setupParameterMappings(const neml2::Model &)
Set up MOOSE-NEML2 model parameter mappings.
FileName _fname
Name of the NEML2 input file.
const NEML2ActionCommon & getCommonAction() const
NEML2Action(const InputParameters &)
void assertNEML2Enabled()
Assert that NEML2 is enabled.
std::shared_ptr< neml2::Model > getModel(neml2::Factory &factory, const std::string &name, neml2::Dtype dtype=neml2::kFloat64)
Get the NEML2 Model.
void setupInputMappings(const neml2::Model &)
Set up MOOSE-NEML2 input variable mappings.
void setupDerivativeMappings(const neml2::Model &)
Set up MOOSE-NEML2 derivative mappings.
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type.
static InputParameters validParams()
std::shared_ptr< FEProblemBase > & _problem
Convenience reference to a problem this action works on.
const InputParameters & parameters() const
Get the parameters of the 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.
const UserObjectName _idx_generator_name
Name of the NEML2BatchIndexGenerator user object.
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)
std::vector< VariableMapping > _outputs
MOOSE-NEML2 output variable mappings.
std::vector< ParameterMapping > _params
MOOSE-NEML2 model parameter mappings.
neml2::VariableName parseVariableName(const std::string &)
Parse a raw string into NEML2 variable name.
auto index_range(const T &sizable)
std::vector< VariableMapping > _inputs
MOOSE-NEML2 input variable mappings.
static InputParameters commonParams()
Parameters that can be specified EITHER under the common area OR under sub-blocks.