26#include "libmesh/utility.h"
35 params.
addClassDescription(
"Outputs material properties to various Outputs objects, based on the "
36 "parameters set in each Material");
38 "print_unsupported_prop_names",
40 "Flag to tell this action whether or not to print the unsupported properties.");
41 params.
addParam<
bool>(
"print_automatic_aux_variable_creation",
43 "Flag to print list of aux variables created for automatic output by "
44 "MaterialOutputAction.");
50 _block_material_data(nullptr),
51 _boundary_material_data(nullptr),
52 _output_warehouse(_app.getOutputWarehouse()),
53 _output_only_on_timestep_end(_app.parameters().get<bool>(
"use_legacy_material_output"))
61 "FEProblemBase pointer is nullptr, it is needed for auto material property output");
67 bool get_names_only =
_current_task ==
"add_output_aux_variables" ? true :
false;
75 const auto & material_ptrs =
_problem->getMaterialWarehouse().getObjects();
82 bool outputs_has_properties =
false;
83 std::set<std::string> output_object_properties;
86 for (
const auto &
act : output_actions)
97 params.
get<
bool>(
"output_material_properties"))
99 outputs_has_properties =
true;
100 std::vector<std::string> prop_names =
101 params.
get<std::vector<std::string>>(
"show_material_properties");
102 output_object_properties.insert(prop_names.begin(), prop_names.end());
107 std::set<std::string> material_names;
108 std::set<std::string> unsupported_names;
109 for (
const auto & mat : material_ptrs)
112 std::set<OutputName> outputs = mat->getOutputs();
115 std::vector<std::string> output_properties =
116 mat->getParam<std::vector<std::string>>(
"output_properties");
119 if (outputs_has_properties)
120 output_properties.insert(output_properties.end(),
121 output_object_properties.begin(),
122 output_object_properties.end());
134 if (outputs_has_properties || outputs.find(
"none") == outputs.end())
137 std::set<std::string> names = mat->getSuppliedItems();
138 if (
const auto fmat_ptr =
dynamic_cast<const FunctorMaterial *
>(mat.get()))
139 names.insert(fmat_ptr->getSuppliedFunctors().begin(),
140 fmat_ptr->getSuppliedFunctors().end());
142 for (
const auto &
name : names)
146 if (output_properties.empty() ||
147 std::find(output_properties.begin(), output_properties.end(),
name) !=
148 output_properties.end())
152 if (curr_material_names.size() == 0)
153 unsupported_names.insert(
name);
154 material_names.insert(curr_material_names.begin(), curr_material_names.end());
159 if (outputs.find(
"none") == outputs.end())
165 if (outputs.find(
"all") != outputs.end())
166 outputs = all_output_names;
170 for (
const auto & output_name : all_output_names)
172 if (outputs.find(output_name) != outputs.end())
180 else if (output_properties.size())
181 mooseWarning(
"Material properties output specified is not created because 'outputs' is not "
182 "set in the Material, and neither is output_material_properties in any of the "
183 "outputs in the [Outputs] block");
185 if (unsupported_names.size() > 0 && get_names_only &&
186 getParam<bool>(
"print_unsupported_prop_names"))
188 std::ostringstream oss;
189 for (
const auto &
name : unsupported_names)
190 oss <<
"\n " <<
name;
192 unsupported_names.size(),
193 " material properties:",
195 "\nare not supported for automatic output by ",
205 params.set<
MooseEnum>(
"family") =
"MONOMIAL";
208 std::ostringstream oss;
209 for (
const auto & var_name : material_names)
211 oss <<
"\n " << var_name;
212 if (
_problem->hasVariable(var_name))
213 mooseError(
"The material property output " + var_name +
214 " has the same name as an existing variable, either use the material"
215 " declare_suffix parameter to disambiguate or the output_properties parameter"
216 " to restrict the material properties to output");
217 _problem->addAuxVariable(
"MooseVariableConstMonomial", var_name, params);
220 if (material_names.size() > 0 && getParam<bool>(
"print_automatic_aux_variable_creation"))
221 _console << COLOR_CYAN <<
"The following total " << material_names.size()
222 <<
" aux variables:" << oss.str() <<
"\nare added for automatic output by " <<
type()
223 <<
"." << COLOR_DEFAULT << std::endl;
232 std::set<std::string> hide;
233 std::set_difference(material_names.begin(),
234 material_names.end(),
237 std::inserter(hide, hide.begin()));
244std::vector<std::string>
249 std::vector<std::string> names;
252 if (hasProperty<Real>(property_name))
254 {
"MaterialRealAux",
"", {}}, property_name, property_name, material, get_names_only);
256 else if (hasADProperty<Real>(property_name))
258 {
"ADMaterialRealAux",
"", {}}, property_name, property_name, material, get_names_only);
260 else if (hasProperty<RealVectorValue>(property_name))
261 names =
outputHelper({
"MaterialRealVectorValueAux",
"xyz", {
"component"}},
267 else if (hasADProperty<RealVectorValue>(property_name))
268 names =
outputHelper({
"ADMaterialRealVectorValueAux",
"xyz", {
"component"}},
274 else if (
hasProperty<std::vector<Real>>(property_name))
275 names =
outputHelper({
"MaterialStdVectorAux",
"variable_size", {
"index"}},
282 names =
outputHelper({
"ADMaterialStdVectorAux",
"variable_size", {
"index"}},
288 else if (hasProperty<RealTensorValue>(property_name))
289 names =
outputHelper({
"MaterialRealTensorValueAux",
"012", {
"row",
"column"}},
295 else if (hasADProperty<RealTensorValue>(property_name))
296 names =
outputHelper({
"ADMaterialRealTensorValueAux",
"012", {
"row",
"column"}},
302 else if (hasProperty<RankTwoTensor>(property_name))
303 names =
outputHelper({
"MaterialRankTwoTensorAux",
"012", {
"i",
"j"}},
309 else if (hasADProperty<RankTwoTensor>(property_name))
310 names =
outputHelper({
"ADMaterialRankTwoTensorAux",
"012", {
"i",
"j"}},
316 else if (hasProperty<RankFourTensor>(property_name))
317 names =
outputHelper({
"MaterialRankFourTensorAux",
"012", {
"i",
"j",
"k",
"l"}},
323 else if (hasADProperty<RankFourTensor>(property_name))
324 names =
outputHelper({
"ADMaterialRankFourTensorAux",
"012", {
"i",
"j",
"k",
"l"}},
330 else if (hasProperty<SymmetricRankTwoTensor>(property_name))
331 names =
outputHelper({
"MaterialSymmetricRankTwoTensorAux",
"012345", {
"component"}},
337 else if (hasADProperty<SymmetricRankTwoTensor>(property_name))
338 names =
outputHelper({
"ADMaterialSymmetricRankTwoTensorAux",
"012345", {
"component"}},
344 else if (hasProperty<SymmetricRankFourTensor>(property_name))
345 names =
outputHelper({
"MaterialSymmetricRankFourTensorAux",
"012345", {
"i",
"j"}},
351 else if (hasADProperty<SymmetricRankFourTensor>(property_name))
352 names =
outputHelper({
"ADMaterialSymmetricRankFourTensorAux",
"012345", {
"i",
"j"}},
359 else if (hasFunctorProperty<Real>(property_name))
360 names =
outputHelper({
"FunctorMaterialRealAux",
"", {}},
362 property_name +
"_out",
366 else if (hasFunctorProperty<ADReal>(property_name))
367 names =
outputHelper({
"ADFunctorMaterialRealAux",
"", {}},
369 property_name +
"_out",
373 else if (hasFunctorProperty<RealVectorValue>(property_name))
374 names =
outputHelper({
"FunctorMaterialRealVectorValueAux",
"xyz", {
"component"}},
376 property_name +
"_out_",
380 else if (hasFunctorProperty<ADRealVectorValue>(property_name))
381 names =
outputHelper({
"ADFunctorMaterialRealVectorValueAux",
"xyz", {
"component"}},
383 property_name +
"_out_",
390std::vector<std::string>
392 const std::string & property_name,
393 const std::string & var_name_base,
397 const auto & [kernel_name, index_symbols, param_names] = metadata;
398 const auto dim = param_names.size();
399 const auto size = index_symbols.size();
400 auto size_inner = size;
403 bool variable_size =
false;
404 if (index_symbols ==
"variable_size")
406 variable_size =
true;
408 const auto *
const vsmi =
415 mooseWarning(
"Vector material property '" + property_name +
"' will not be output as we " +
416 (vsmi ?
"have a 0-size vector during the simulation setup."
417 :
"do not know the size of the vector at initialization. Add the "
418 "'VariableSizeMaterialPropertiesInterface' as a base class of the "
419 "Material defining the vector property and implement the "
420 "get...Size(property_name) routine. Note that "
421 "the size must be known during the simulation setup phase."));
426 std::vector<std::string> names;
428 std::array<std::size_t, 4> i;
429 for (i[3] = 0; i[3] < (
dim < 4 ? 1 : size); ++i[3])
430 for (i[2] = 0; i[2] < (
dim < 3 ? 1 : size); ++i[2])
431 for (i[1] = 0; i[1] < (
dim < 2 ? 1 : size); ++i[1])
432 for (i[0] = 0; i[0] < (
dim < 1 ? 1 : size_inner); ++i[0])
434 std::string var_name = var_name_base;
435 for (
const auto j : make_range(
dim))
441 names.push_back(var_name);
445 auto params =
getParams(kernel_name, property_name, var_name, material);
446 for (
const auto j : make_range(
dim))
447 params.template set<unsigned int>(param_names[j]) = i[j];
448 _problem->addAuxKernel(kernel_name, material.
name() +
"_" + var_name, params);
456 const std::string & property_name,
457 const std::string & variable_name,
466 params.
set<MaterialPropertyName>(
"property") = property_name;
468 params.
set<MooseFunctorName>(
"functor") = property_name;
470 mooseError(
"Internal error. AuxKernel has neither a `functor` nor a `property` parameter.");
472 params.
set<AuxVariableName>(
"variable") = variable_name;
479 params.
set<std::vector<BoundaryName>>(
"boundary") = material.
boundaryNames();
481 params.
set<std::vector<SubdomainName>>(
"block") = material.
blocks();
registerMooseAction("MooseApp", MaterialOutputAction, "add_output_aux_variables")
const ExecFlagType EXEC_TIMESTEP_END
const ExecFlagType EXEC_INITIAL
bool hasActions(const std::string &task) const
Check if Actions associated with passed in task exist.
const std::list< Action * > & getActionListByName(const std::string &task) const
Retrieve a constant list of Action pointers associated with the passed in task.
static InputParameters validParams()
MooseApp & _app
The MOOSE application this is associated with.
std::shared_ptr< FEProblemBase > & _problem
Convenience reference to a problem this action works on.
const std::string & _current_task
The current action (even though we have separate instances for each action)
Action for creating output objects.
const std::vector< SubdomainName > & blocks() const
Return the block names for this object.
const std::vector< BoundaryName > & boundaryNames() const
Return the boundary names for this object.
virtual bool boundaryRestricted() const
Returns true if this object has been restricted to a boundary.
const ConsoleStream _console
An instance of helper class to write streams to the Console objects.
A MultiMooseEnum object to hold "execute_on" flags.
InputParameters getValidParams(const std::string &name) const
Get valid parameters for the object.
FunctorMaterials compute functor material properties.
MaterialBases compute MaterialProperties.
Creates AuxVariables and AuxKernels for automatic output of material properties.
bool hasADProperty(const std::string &property_name)
Helper method for testing if the material exists as a block or boundary material.
virtual std::vector< std::string > materialOutput(const std::string &property_name, const MaterialBase &material, bool get_names_only)
A function to be overriden by derived actions to handle a set of material property types.
MaterialOutputAction(const InputParameters ¶ms)
bool hasProperty(const std::string &property_name)
Helper method for testing if the material exists as a block or boundary material.
const MaterialData * _block_material_data
Pointer the MaterialData object storing the block restricted materials.
std::set< std::string > _material_variable_names
variables for the current MaterialBase object
std::map< OutputName, std::set< std::string > > _material_variable_names_map
Map of output names and list of variables associated with the output.
const bool _output_only_on_timestep_end
Output only on TIMESTEP_END, not on INITIAL?
InputParameters getParams(const std::string &type, const std::string &property_name, const std::string &variable_name, const MaterialBase &material)
A method for retrieving and partially filling the InputParameters object for an AuxVariable.
virtual void act() override
Method to add objects to the simulation or perform other setup tasks.
static InputParameters validParams()
OutputWarehouse & _output_warehouse
Reference to the OutputWarehouse.
std::vector< std::string > outputHelper(const OutputMetaData &metadata, const std::string &property_name, const std::string &var_name_base, const MaterialBase &material, bool get_names_only)
Universal output object setup function.
const MaterialData * _boundary_material_data
Pointer the MaterialData object storing the boundary restricted materials.
ActionWarehouse & actionWarehouse()
Return a writable reference to the ActionWarehouse associated with this app.
const std::string & type() const
Get the type of this class.
const std::string & name() const
Get the name of the class.
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type and optionally a file path to the top-level block p...
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
InputParameters & getObjectParams()
Retrieve the parameters of the object to be created by this action.
std::set< OutputName > getAllMaterialPropertyOutputNames() const
Returns all output names that support material output.
void addInterfaceHideVariables(const std::string &output_name, const std::set< std::string > &variable_names)
Insert variable names for hiding via the OutoutInterface.
Factory & _factory
The Factory associated with the MooseApp.
void mooseWarning(Args &&... args) const
Interface class to return the size of material properties that do not have a fixed size.
virtual std::size_t getVectorPropertySize(const MaterialPropertyName &) const =0
Return the size of the variable size vector material property that the material defines.
void insert(const std::string &)
std::string stringify(const T &t)
conversion to string