Loading [MathJax]/extensions/tex2jax.js
https://mooseframework.inl.gov
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends
MaterialOutputAction.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 // MOOSE includes
11 #include "MaterialOutputAction.h"
12 #include "FEProblem.h"
13 #include "FEProblemBase.h"
14 #include "MooseApp.h"
15 #include "AddOutputAction.h"
16 #include "MaterialBase.h"
17 #include "RankTwoTensor.h"
18 #include "SymmetricRankTwoTensor.h"
19 #include "RankFourTensor.h"
21 #include "MooseEnum.h"
23 #include "FunctorMaterial.h"
24 
25 #include "libmesh/utility.h"
26 
27 registerMooseAction("MooseApp", MaterialOutputAction, "add_output_aux_variables");
28 registerMooseAction("MooseApp", MaterialOutputAction, "add_aux_kernel");
29 
32 {
34  params.addClassDescription("Outputs material properties to various Outputs objects, based on the "
35  "parameters set in each Material");
39  params.addPrivateParam("print_unsupported_prop_names", true);
40  params.addParam<bool>("print_automatic_aux_variable_creation",
41  true,
42  "Flag to print list of aux variables created for automatic output by "
43  "MaterialOutputAction.");
44  return params;
45 }
46 
48  : Action(params),
49  _block_material_data(nullptr),
50  _boundary_material_data(nullptr),
51  _output_warehouse(_app.getOutputWarehouse()),
52  _output_only_on_timestep_end(_app.parameters().get<bool>("use_legacy_material_output"))
53 {
54 }
55 
56 void
58 {
59  mooseAssert(_problem,
60  "FEProblemBase pointer is nullptr, it is needed for auto material property output");
61 
62  // Do nothing if the application does not have output
63  if (!_app.actionWarehouse().hasActions("add_output"))
64  return;
65 
66  bool get_names_only = _current_task == "add_output_aux_variables" ? true : false;
67 
68  // Set the pointers to the MaterialData objects (Note, these pointers are not available at
69  // construction)
72 
73  // A complete list of all MaterialBase objects
74  const auto & material_ptrs = _problem->getMaterialWarehouse().getObjects();
75 
76  // Handle setting of material property output in [Outputs] sub-blocks
77  // Output objects can enable material property output, the following code examines the parameters
78  // for each Output object and sets a flag if any Output object has output set and also builds a
79  // list if the
80  // properties are limited via the 'show_material_properties' parameters
81  bool outputs_has_properties = false;
82  std::set<std::string> output_object_properties;
83 
84  const auto & output_actions = _app.actionWarehouse().getActionListByName("add_output");
85  for (const auto & act : output_actions)
86  {
87  // Extract the Output action
88  AddOutputAction * action = dynamic_cast<AddOutputAction *>(act);
89  if (!action)
90  continue;
91 
92  // Add the material property names from the output object parameters to the list of properties
93  // to output
94  InputParameters & params = action->getObjectParams();
95  if (params.isParamValid("output_material_properties") &&
96  params.get<bool>("output_material_properties"))
97  {
98  outputs_has_properties = true;
99  std::vector<std::string> prop_names =
100  params.get<std::vector<std::string>>("show_material_properties");
101  output_object_properties.insert(prop_names.begin(), prop_names.end());
102  }
103  }
104 
105  // Loop through each material object
106  std::set<std::string> material_names;
107  std::set<std::string> unsupported_names;
108  for (const auto & mat : material_ptrs)
109  {
110  // Extract the names of the output objects to which the material properties will be exported
111  std::set<OutputName> outputs = mat->getOutputs();
112 
113  // Extract the property names that will actually be output
114  std::vector<std::string> output_properties =
115  mat->getParam<std::vector<std::string>>("output_properties");
116 
117  // Append the properties listed in the Outputs block
118  if (outputs_has_properties)
119  output_properties.insert(output_properties.end(),
120  output_object_properties.begin(),
121  output_object_properties.end());
122 
123  // Clear the list of variable names for the current material object, this list will be populated
124  // with all the
125  // variables names for the current material object and is needed for purposes of controlling the
126  // which output objects
127  // show the material property data
128  _material_variable_names.clear();
129 
130  // Create necessary outputs for the properties if:
131  // (1) The Outputs block has material output enabled
132  // (2) If the MaterialBase object itself has set the 'outputs' parameter
133  if (outputs_has_properties || outputs.find("none") == outputs.end())
134  {
135  // Get all material properties supplied by this material as a starting point
136  std::set<std::string> names = mat->getSuppliedItems();
137  if (const auto fmat_ptr = dynamic_cast<const FunctorMaterial *>(mat.get()))
138  names.insert(fmat_ptr->getSuppliedFunctors().begin(),
139  fmat_ptr->getSuppliedFunctors().end());
140 
141  for (const auto & name : names)
142  {
143  // Output the property only if the name is contained in the 'output_properties'
144  // list or if the list is empty (all properties)
145  if (output_properties.empty() ||
146  std::find(output_properties.begin(), output_properties.end(), name) !=
147  output_properties.end())
148  {
149  // Add the material property for output
150  auto curr_material_names = materialOutput(name, *mat, get_names_only);
151  if (curr_material_names.size() == 0)
152  unsupported_names.insert(name);
153  material_names.insert(curr_material_names.begin(), curr_material_names.end());
154  }
155  }
156  // If the material object has explicitly defined outputs, store the variables associated with
157  // the output objects
158  if (outputs.find("none") == outputs.end())
159  {
160  // Get all available output names from OutputWarehouse that support material output
161  const auto & all_output_names = _output_warehouse.getAllMaterialPropertyOutputNames();
162 
163  // For reserved name "all", set outputs to match all available output names
164  if (outputs.find("all") != outputs.end())
165  outputs = all_output_names;
166 
167  // Iterate through all available output names and update _material_variable_names_map
168  // based on which of these output names are found in 'outputs' parameter
169  for (const auto & output_name : all_output_names)
170  {
171  if (outputs.find(output_name) != outputs.end())
172  _material_variable_names_map[output_name].insert(_material_variable_names.begin(),
174  else
175  _material_variable_names_map[output_name].insert({});
176  }
177  }
178  }
179  else if (output_properties.size())
180  mooseWarning("Material properties output specified is not created because 'outputs' is not "
181  "set in the Material, and neither is Outputs/output_material_properties");
182  }
183  if (unsupported_names.size() > 0 && get_names_only &&
184  getParam<bool>("print_unsupported_prop_names"))
185  {
186  std::ostringstream oss;
187  for (const auto & name : unsupported_names)
188  oss << "\n " << name;
189  mooseWarning("The types for total ",
190  unsupported_names.size(),
191  " material properties:",
192  oss.str(),
193  "\nare not supported for automatic output by ",
194  type(),
195  ".");
196  }
197 
198  if (_current_task == "add_output_aux_variables")
199  {
200  auto params = _factory.getValidParams("MooseVariableConstMonomial");
201  // currently only elemental variables are supported for material property output
202  params.set<MooseEnum>("order") = "CONSTANT";
203  params.set<MooseEnum>("family") = "MONOMIAL";
204 
205  // Create the AuxVariables
206  std::ostringstream oss;
207  for (const auto & var_name : material_names)
208  {
209  oss << "\n " << var_name;
210  if (_problem->hasVariable(var_name))
211  mooseError("The material property output " + var_name +
212  " has the same name as an existing variable, either use the material"
213  " declare_suffix parameter to disambiguate or the output_properties parameter"
214  " to restrict the material properties to output");
215  _problem->addAuxVariable("MooseVariableConstMonomial", var_name, params);
216  }
217 
218  if (material_names.size() > 0 && getParam<bool>("print_automatic_aux_variable_creation"))
219  _console << COLOR_CYAN << "The following total " << material_names.size()
220  << " aux variables:" << oss.str() << "\nare added for automatic output by " << type()
221  << "." << COLOR_DEFAULT << std::endl;
222  }
223  else
224  {
225  // When a MaterialBase object has 'output_properties' defined all other properties not listed
226  // must be added to the hide list for the output objects so that properties that are not desired
227  // do not appear.
228  for (const auto & it : _material_variable_names_map)
229  {
230  std::set<std::string> hide;
231  std::set_difference(material_names.begin(),
232  material_names.end(),
233  it.second.begin(),
234  it.second.end(),
235  std::inserter(hide, hide.begin()));
236 
238  }
239  }
240 }
241 
242 std::vector<std::string>
243 MaterialOutputAction::materialOutput(const std::string & property_name,
244  const MaterialBase & material,
245  bool get_names_only)
246 {
247  std::vector<std::string> names;
248 
249  // Material Properties
250  if (hasProperty<Real>(property_name))
251  names = outputHelper(
252  {"MaterialRealAux", "", {}}, property_name, property_name, material, get_names_only);
253 
254  else if (hasADProperty<Real>(property_name))
255  names = outputHelper(
256  {"ADMaterialRealAux", "", {}}, property_name, property_name, material, get_names_only);
257 
258  else if (hasProperty<RealVectorValue>(property_name))
259  names = outputHelper({"MaterialRealVectorValueAux", "xyz", {"component"}},
260  property_name,
261  property_name + "_",
262  material,
263  get_names_only);
264 
265  else if (hasADProperty<RealVectorValue>(property_name))
266  names = outputHelper({"ADMaterialRealVectorValueAux", "xyz", {"component"}},
267  property_name,
268  property_name + "_",
269  material,
270  get_names_only);
271 
272  else if (hasProperty<RealTensorValue>(property_name))
273  names = outputHelper({"MaterialRealTensorValueAux", "012", {"row", "column"}},
274  property_name,
275  property_name + "_",
276  material,
277  get_names_only);
278 
279  else if (hasADProperty<RealTensorValue>(property_name))
280  names = outputHelper({"ADMaterialRealTensorValueAux", "012", {"row", "column"}},
281  property_name,
282  property_name + "_",
283  material,
284  get_names_only);
285 
286  else if (hasProperty<RankTwoTensor>(property_name))
287  names = outputHelper({"MaterialRankTwoTensorAux", "012", {"i", "j"}},
288  property_name,
289  property_name + "_",
290  material,
291  get_names_only);
292 
293  else if (hasADProperty<RankTwoTensor>(property_name))
294  names = outputHelper({"ADMaterialRankTwoTensorAux", "012", {"i", "j"}},
295  property_name,
296  property_name + "_",
297  material,
298  get_names_only);
299 
300  else if (hasProperty<RankFourTensor>(property_name))
301  names = outputHelper({"MaterialRankFourTensorAux", "012", {"i", "j", "k", "l"}},
302  property_name,
303  property_name + "_",
304  material,
305  get_names_only);
306 
307  else if (hasADProperty<RankFourTensor>(property_name))
308  names = outputHelper({"ADMaterialRankFourTensorAux", "012", {"i", "j", "k", "l"}},
309  property_name,
310  property_name + "_",
311  material,
312  get_names_only);
313 
314  else if (hasProperty<SymmetricRankTwoTensor>(property_name))
315  names = outputHelper({"MaterialSymmetricRankTwoTensorAux", "012345", {"component"}},
316  property_name,
317  property_name + "_",
318  material,
319  get_names_only);
320 
321  else if (hasADProperty<SymmetricRankTwoTensor>(property_name))
322  names = outputHelper({"ADMaterialSymmetricRankTwoTensorAux", "012345", {"component"}},
323  property_name,
324  property_name + "_",
325  material,
326  get_names_only);
327 
328  else if (hasProperty<SymmetricRankFourTensor>(property_name))
329  names = outputHelper({"MaterialSymmetricRankFourTensorAux", "012345", {"i", "j"}},
330  property_name,
331  property_name + "_",
332  material,
333  get_names_only);
334 
335  else if (hasADProperty<SymmetricRankFourTensor>(property_name))
336  names = outputHelper({"ADMaterialSymmetricRankFourTensorAux", "012345", {"i", "j"}},
337  property_name,
338  property_name + "_",
339  material,
340  get_names_only);
341 
342  // Functors
343  else if (hasFunctorProperty<Real>(property_name))
344  names = outputHelper({"FunctorMaterialRealAux", "", {}},
345  property_name,
346  property_name + "_out",
347  material,
348  get_names_only);
349 
350  else if (hasFunctorProperty<ADReal>(property_name))
351  names = outputHelper({"ADFunctorMaterialRealAux", "", {}},
352  property_name,
353  property_name + "_out",
354  material,
355  get_names_only);
356 
357  else if (hasFunctorProperty<RealVectorValue>(property_name))
358  names = outputHelper({"FunctorMaterialRealVectorValueAux", "xyz", {"component"}},
359  property_name,
360  property_name + "_out_",
361  material,
362  get_names_only);
363 
364  else if (hasFunctorProperty<ADRealVectorValue>(property_name))
365  names = outputHelper({"ADFunctorMaterialRealVectorValueAux", "xyz", {"component"}},
366  property_name,
367  property_name + "_out_",
368  material,
369  get_names_only);
370 
371  return names;
372 }
373 
374 std::vector<std::string>
376  const std::string & property_name,
377  const std::string & var_name_base,
378  const MaterialBase & material,
379  bool get_names_only)
380 {
381  const auto & [kernel_name, index_symbols, param_names] = metadata;
382  const auto dim = param_names.size();
383  const auto size = index_symbols.size();
384 
385  std::vector<std::string> names;
386  // general 0 to 4 dimensional loop
387  std::array<std::size_t, 4> i;
388  for (i[3] = 0; i[3] < (dim < 4 ? 1 : size); ++i[3])
389  for (i[2] = 0; i[2] < (dim < 3 ? 1 : size); ++i[2])
390  for (i[1] = 0; i[1] < (dim < 2 ? 1 : size); ++i[1])
391  for (i[0] = 0; i[0] < (dim < 1 ? 1 : size); ++i[0])
392  {
393  std::string var_name = var_name_base;
394  for (const auto j : make_range(dim))
395  var_name += Moose::stringify(index_symbols[i[j]]);
396  names.push_back(var_name);
397 
398  if (!get_names_only)
399  {
400  auto params = getParams(kernel_name, property_name, var_name, material);
401  for (const auto j : make_range(dim))
402  params.template set<unsigned int>(param_names[j]) = i[j];
403  _problem->addAuxKernel(kernel_name, material.name() + var_name, params);
404  }
405  }
406  return names;
407 }
408 
410 MaterialOutputAction::getParams(const std::string & type,
411  const std::string & property_name,
412  const std::string & variable_name,
413  const MaterialBase & material)
414 {
415  // Append the list of output variables for the current material
416  _material_variable_names.insert(variable_name);
417 
418  // Set the action parameters
420  if (params.have_parameter<MaterialPropertyName>("property"))
421  params.set<MaterialPropertyName>("property") = property_name;
422  else if (params.have_parameter<MooseFunctorName>("functor"))
423  params.set<MooseFunctorName>("functor") = property_name;
424  else
425  mooseError("Internal error. AuxKernel has neither a `functor` nor a `property` parameter.");
426 
427  params.set<AuxVariableName>("variable") = variable_name;
429  params.set<ExecFlagEnum>("execute_on") = EXEC_TIMESTEP_END;
430  else
431  params.set<ExecFlagEnum>("execute_on") = {EXEC_INITIAL, EXEC_TIMESTEP_END};
432 
433  if (material.boundaryRestricted())
434  params.set<std::vector<BoundaryName>>("boundary") = material.boundaryNames();
435  else
436  params.set<std::vector<SubdomainName>>("block") = material.blocks();
437 
438  return params;
439 }
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...
std::map< OutputName, std::set< std::string > > _material_variable_names_map
Map of output names and list of variables associated with the output.
static InputParameters validParams()
unsigned int size(THREAD_ID tid=0) const
Return how many kernels we store in the current warehouse.
OutputWarehouse & _output_warehouse
Reference to the OutputWarehouse.
A MultiMooseEnum object to hold "execute_on" flags.
Definition: ExecFlagEnum.h:21
virtual bool boundaryRestricted() const
Returns true if this object has been restricted to a boundary.
void addPrivateParam(const std::string &name, const T &value)
These method add a parameter to the InputParameters object which can be retrieved like any other para...
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.
T * get(const std::unique_ptr< T > &u)
The MooseUtils::get() specializations are used to support making forwards-compatible code changes fro...
Definition: MooseUtils.h:1191
T & set(const std::string &name, bool quiet_mode=false)
Returns a writable reference to the named parameters.
std::set< std::string > _material_variable_names
variables for the current MaterialBase object
InputParameters getValidParams(const std::string &name) const
Get valid parameters for the object.
Definition: Factory.C:68
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
static constexpr std::size_t dim
This is the dimension of all vector and tensor datastructures used in MOOSE.
Definition: Moose.h:148
const ExecFlagType EXEC_TIMESTEP_END
Definition: Moose.C:33
const std::list< Action * > & getActionListByName(const std::string &task) const
Retrieve a constant list of Action pointers associated with the passed in task.
virtual const std::string & name() const
Get the name of the class.
Definition: MooseBase.h:57
Base class for actions.
Definition: Action.h:33
void mooseWarning(Args &&... args) const
Emits a warning prefixed with object name and type.
Creates AuxVariables and AuxKernels for automatic output of material properties.
Factory & _factory
The Factory associated with the MooseApp.
std::set< OutputName > getAllMaterialPropertyOutputNames() const
Returns all output names that support material output.
Action for creating output objects.
static InputParameters validParams()
Definition: Action.C:24
InputParameters & getObjectParams()
Retrieve the parameters of the object to be created by this action.
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.
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:33
const std::string & _current_task
The current action (even though we have separate instances for each action)
Definition: Action.h:162
ActionWarehouse & actionWarehouse()
Return a writable reference to the ActionWarehouse associated with this app.
Definition: MooseApp.h:226
MooseApp & _app
The MOOSE application this is associated with.
Definition: MooseBase.h:84
std::string stringify(const T &t)
conversion to string
Definition: Conversion.h:64
bool have_parameter(std::string_view name) const
A wrapper around the Parameters base class method.
MaterialOutputAction(const InputParameters &params)
const MaterialData * _block_material_data
Pointer the MaterialData object storing the block restricted materials.
const std::vector< SubdomainName > & blocks() const
Return the block names for this object.
bool hasActions(const std::string &task) const
Check if Actions associated with passed in task exist.
IntRange< T > make_range(T beg, T end)
const bool _output_only_on_timestep_end
Output only on TIMESTEP_END, not on INITIAL?
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:168
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...
void addInterfaceHideVariables(const std::string &output_name, const std::set< std::string > &variable_names)
Insert variable names for hiding via the OutoutInterface.
virtual void act() override
Method to add objects to the simulation or perform other setup tasks.
const ConsoleStream _console
An instance of helper class to write streams to the Console objects.
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 std::vector< BoundaryName > & boundaryNames() const
Return the boundary names for this object.
Meta data describing the setup of an output object.
MaterialBases compute MaterialProperties.
Definition: MaterialBase.h:62
registerMooseAction("MooseApp", MaterialOutputAction, "add_output_aux_variables")
const MaterialData * _boundary_material_data
Pointer the MaterialData object storing the boundary restricted materials.
bool isParamValid(const std::string &name) const
This method returns parameters that have been initialized in one fashion or another, i.e.
const ExecFlagType EXEC_INITIAL
Definition: Moose.C:28