https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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
12#include "FEProblem.h"
13#include "FEProblemBase.h"
14#include "MooseApp.h"
15#include "AddOutputAction.h"
16#include "MaterialBase.h"
17#include "RankTwoTensor.h"
19#include "RankFourTensor.h"
21#include "MooseEnum.h"
23#include "FunctorMaterial.h"
25
26#include "libmesh/utility.h"
27
28registerMooseAction("MooseApp", MaterialOutputAction, "add_output_aux_variables");
29registerMooseAction("MooseApp", MaterialOutputAction, "add_aux_kernel");
30
33{
35 params.addClassDescription("Outputs material properties to various Outputs objects, based on the "
36 "parameters set in each Material");
37 params.addParam<bool>(
38 "print_unsupported_prop_names",
39 true,
40 "Flag to tell this action whether or not to print the unsupported properties.");
41 params.addParam<bool>("print_automatic_aux_variable_creation",
42 true,
43 "Flag to print list of aux variables created for automatic output by "
44 "MaterialOutputAction.");
45 return params;
46}
47
49 : Action(params),
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"))
54{
55}
56
57void
59{
60 mooseAssert(_problem,
61 "FEProblemBase pointer is nullptr, it is needed for auto material property output");
62
63 // Do nothing if the application does not have output
64 if (!_app.actionWarehouse().hasActions("add_output"))
65 return;
66
67 bool get_names_only = _current_task == "add_output_aux_variables" ? true : false;
68
69 // Set the pointers to the MaterialData objects (Note, these pointers are not available at
70 // construction)
73
74 // A complete list of all MaterialBase objects
75 const auto & material_ptrs = _problem->getMaterialWarehouse().getObjects();
76
77 // Handle setting of material property output in [Outputs] sub-blocks
78 // Output objects can enable material property output, the following code examines the parameters
79 // for each Output object and sets a flag if any Output object has output set and also builds a
80 // list if the
81 // properties are limited via the 'show_material_properties' parameters
82 bool outputs_has_properties = false;
83 std::set<std::string> output_object_properties;
84
85 const auto & output_actions = _app.actionWarehouse().getActionListByName("add_output");
86 for (const auto & act : output_actions)
87 {
88 // Extract the Output action
89 AddOutputAction * action = dynamic_cast<AddOutputAction *>(act);
90 if (!action)
91 continue;
92
93 // Add the material property names from the output object parameters to the list of properties
94 // to output
95 InputParameters & params = action->getObjectParams();
96 if (params.isParamValid("output_material_properties") &&
97 params.get<bool>("output_material_properties"))
98 {
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());
103 }
104 }
105
106 // Loop through each material object
107 std::set<std::string> material_names;
108 std::set<std::string> unsupported_names;
109 for (const auto & mat : material_ptrs)
110 {
111 // Extract the names of the output objects to which the material properties will be exported
112 std::set<OutputName> outputs = mat->getOutputs();
113
114 // Extract the property names that will actually be output
115 std::vector<std::string> output_properties =
116 mat->getParam<std::vector<std::string>>("output_properties");
117
118 // Append the properties listed in the Outputs block
119 if (outputs_has_properties)
120 output_properties.insert(output_properties.end(),
121 output_object_properties.begin(),
122 output_object_properties.end());
123
124 // Clear the list of variable names for the current material object, this list will be populated
125 // with all the
126 // variables names for the current material object and is needed for purposes of controlling the
127 // which output objects
128 // show the material property data
130
131 // Create necessary outputs for the properties if:
132 // (1) The Outputs block has material output enabled
133 // (2) If the MaterialBase object itself has set the 'outputs' parameter
134 if (outputs_has_properties || outputs.find("none") == outputs.end())
135 {
136 // Get all material properties supplied by this material as a starting point
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());
141
142 for (const auto & name : names)
143 {
144 // Output the property only if the name is contained in the 'output_properties'
145 // list or if the list is empty (all properties)
146 if (output_properties.empty() ||
147 std::find(output_properties.begin(), output_properties.end(), name) !=
148 output_properties.end())
149 {
150 // Add the material property for output
151 auto curr_material_names = materialOutput(name, *mat, get_names_only);
152 if (curr_material_names.size() == 0)
153 unsupported_names.insert(name);
154 material_names.insert(curr_material_names.begin(), curr_material_names.end());
155 }
156 }
157 // If the material object has explicitly defined outputs, store the variables associated with
158 // the output objects
159 if (outputs.find("none") == outputs.end())
160 {
161 // Get all available output names from OutputWarehouse that support material output
162 const auto & all_output_names = _output_warehouse.getAllMaterialPropertyOutputNames();
163
164 // For reserved name "all", set outputs to match all available output names
165 if (outputs.find("all") != outputs.end())
166 outputs = all_output_names;
167
168 // Iterate through all available output names and update _material_variable_names_map
169 // based on which of these output names are found in 'outputs' parameter
170 for (const auto & output_name : all_output_names)
171 {
172 if (outputs.find(output_name) != outputs.end())
173 _material_variable_names_map[output_name].insert(_material_variable_names.begin(),
175 else
176 _material_variable_names_map[output_name].insert({});
177 }
178 }
179 }
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");
184 }
185 if (unsupported_names.size() > 0 && get_names_only &&
186 getParam<bool>("print_unsupported_prop_names"))
187 {
188 std::ostringstream oss;
189 for (const auto & name : unsupported_names)
190 oss << "\n " << name;
191 mooseWarning("The types for total ",
192 unsupported_names.size(),
193 " material properties:",
194 oss.str(),
195 "\nare not supported for automatic output by ",
196 type(),
197 ".");
198 }
199
200 if (_current_task == "add_output_aux_variables")
201 {
202 auto params = _factory.getValidParams("MooseVariableConstMonomial");
203 // currently only elemental variables are supported for material property output
204 params.set<MooseEnum>("order") = "CONSTANT";
205 params.set<MooseEnum>("family") = "MONOMIAL";
206
207 // Create the AuxVariables
208 std::ostringstream oss;
209 for (const auto & var_name : material_names)
210 {
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);
218 }
219
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;
224 }
225 else
226 {
227 // When a MaterialBase object has 'output_properties' defined all other properties not listed
228 // must be added to the hide list for the output objects so that properties that are not desired
229 // do not appear.
230 for (const auto & it : _material_variable_names_map)
231 {
232 std::set<std::string> hide;
233 std::set_difference(material_names.begin(),
234 material_names.end(),
235 it.second.begin(),
236 it.second.end(),
237 std::inserter(hide, hide.begin()));
238
240 }
241 }
242}
243
244std::vector<std::string>
245MaterialOutputAction::materialOutput(const std::string & property_name,
246 const MaterialBase & material,
247 bool get_names_only)
248{
249 std::vector<std::string> names;
250
251 // Material Properties
252 if (hasProperty<Real>(property_name))
253 names = outputHelper(
254 {"MaterialRealAux", "", {}}, property_name, property_name, material, get_names_only);
255
256 else if (hasADProperty<Real>(property_name))
257 names = outputHelper(
258 {"ADMaterialRealAux", "", {}}, property_name, property_name, material, get_names_only);
259
260 else if (hasProperty<RealVectorValue>(property_name))
261 names = outputHelper({"MaterialRealVectorValueAux", "xyz", {"component"}},
262 property_name,
263 property_name + "_",
264 material,
265 get_names_only);
266
267 else if (hasADProperty<RealVectorValue>(property_name))
268 names = outputHelper({"ADMaterialRealVectorValueAux", "xyz", {"component"}},
269 property_name,
270 property_name + "_",
271 material,
272 get_names_only);
273
274 else if (hasProperty<std::vector<Real>>(property_name))
275 names = outputHelper({"MaterialStdVectorAux", "variable_size", {"index"}},
276 property_name,
277 property_name + "_",
278 material,
279 get_names_only);
280
281 else if (hasADProperty<std::vector<Real>>(property_name))
282 names = outputHelper({"ADMaterialStdVectorAux", "variable_size", {"index"}},
283 property_name,
284 property_name + "_",
285 material,
286 get_names_only);
287
288 else if (hasProperty<RealTensorValue>(property_name))
289 names = outputHelper({"MaterialRealTensorValueAux", "012", {"row", "column"}},
290 property_name,
291 property_name + "_",
292 material,
293 get_names_only);
294
295 else if (hasADProperty<RealTensorValue>(property_name))
296 names = outputHelper({"ADMaterialRealTensorValueAux", "012", {"row", "column"}},
297 property_name,
298 property_name + "_",
299 material,
300 get_names_only);
301
302 else if (hasProperty<RankTwoTensor>(property_name))
303 names = outputHelper({"MaterialRankTwoTensorAux", "012", {"i", "j"}},
304 property_name,
305 property_name + "_",
306 material,
307 get_names_only);
308
309 else if (hasADProperty<RankTwoTensor>(property_name))
310 names = outputHelper({"ADMaterialRankTwoTensorAux", "012", {"i", "j"}},
311 property_name,
312 property_name + "_",
313 material,
314 get_names_only);
315
316 else if (hasProperty<RankFourTensor>(property_name))
317 names = outputHelper({"MaterialRankFourTensorAux", "012", {"i", "j", "k", "l"}},
318 property_name,
319 property_name + "_",
320 material,
321 get_names_only);
322
323 else if (hasADProperty<RankFourTensor>(property_name))
324 names = outputHelper({"ADMaterialRankFourTensorAux", "012", {"i", "j", "k", "l"}},
325 property_name,
326 property_name + "_",
327 material,
328 get_names_only);
329
330 else if (hasProperty<SymmetricRankTwoTensor>(property_name))
331 names = outputHelper({"MaterialSymmetricRankTwoTensorAux", "012345", {"component"}},
332 property_name,
333 property_name + "_",
334 material,
335 get_names_only);
336
337 else if (hasADProperty<SymmetricRankTwoTensor>(property_name))
338 names = outputHelper({"ADMaterialSymmetricRankTwoTensorAux", "012345", {"component"}},
339 property_name,
340 property_name + "_",
341 material,
342 get_names_only);
343
344 else if (hasProperty<SymmetricRankFourTensor>(property_name))
345 names = outputHelper({"MaterialSymmetricRankFourTensorAux", "012345", {"i", "j"}},
346 property_name,
347 property_name + "_",
348 material,
349 get_names_only);
350
351 else if (hasADProperty<SymmetricRankFourTensor>(property_name))
352 names = outputHelper({"ADMaterialSymmetricRankFourTensorAux", "012345", {"i", "j"}},
353 property_name,
354 property_name + "_",
355 material,
356 get_names_only);
357
358 // Functors
359 else if (hasFunctorProperty<Real>(property_name))
360 names = outputHelper({"FunctorMaterialRealAux", "", {}},
361 property_name,
362 property_name + "_out",
363 material,
364 get_names_only);
365
366 else if (hasFunctorProperty<ADReal>(property_name))
367 names = outputHelper({"ADFunctorMaterialRealAux", "", {}},
368 property_name,
369 property_name + "_out",
370 material,
371 get_names_only);
372
373 else if (hasFunctorProperty<RealVectorValue>(property_name))
374 names = outputHelper({"FunctorMaterialRealVectorValueAux", "xyz", {"component"}},
375 property_name,
376 property_name + "_out_",
377 material,
378 get_names_only);
379
380 else if (hasFunctorProperty<ADRealVectorValue>(property_name))
381 names = outputHelper({"ADFunctorMaterialRealVectorValueAux", "xyz", {"component"}},
382 property_name,
383 property_name + "_out_",
384 material,
385 get_names_only);
386
387 return names;
388}
389
390std::vector<std::string>
392 const std::string & property_name,
393 const std::string & var_name_base,
394 const MaterialBase & material,
395 bool get_names_only)
396{
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;
401
402 // Handle the case the material property is of a variable input-defined size
403 bool variable_size = false;
404 if (index_symbols == "variable_size")
405 {
406 variable_size = true;
407 size_inner = 0;
408 const auto * const vsmi =
409 dynamic_cast<const VariableSizeMaterialPropertiesInterface *>(&material);
410 if (vsmi)
411 size_inner = vsmi->getVectorPropertySize(property_name);
412
413 if (!size_inner)
414 {
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."));
422 return {};
423 }
424 }
425
426 std::vector<std::string> names;
427 // general 0 to 4 dimensional loop
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])
433 {
434 std::string var_name = var_name_base;
435 for (const auto j : make_range(dim))
436 if (variable_size)
437 var_name += Moose::stringify(i[j]);
438 else
439 var_name += Moose::stringify(index_symbols[i[j]]);
440
441 names.push_back(var_name);
442
443 if (!get_names_only)
444 {
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);
449 }
450 }
451 return names;
452}
453
455MaterialOutputAction::getParams(const std::string & type,
456 const std::string & property_name,
457 const std::string & variable_name,
458 const MaterialBase & material)
459{
460 // Append the list of output variables for the current material
461 _material_variable_names.insert(variable_name);
462
463 // Set the action parameters
465 if (params.have_parameter<MaterialPropertyName>("property"))
466 params.set<MaterialPropertyName>("property") = property_name;
467 else if (params.have_parameter<MooseFunctorName>("functor"))
468 params.set<MooseFunctorName>("functor") = property_name;
469 else
470 mooseError("Internal error. AuxKernel has neither a `functor` nor a `property` parameter.");
471
472 params.set<AuxVariableName>("variable") = variable_name;
474 params.set<ExecFlagEnum>("execute_on") = EXEC_TIMESTEP_END;
475 else
476 params.set<ExecFlagEnum>("execute_on") = {EXEC_INITIAL, EXEC_TIMESTEP_END};
477
478 if (material.boundaryRestricted())
479 params.set<std::vector<BoundaryName>>("boundary") = material.boundaryNames();
480 else
481 params.set<std::vector<SubdomainName>>("block") = material.blocks();
482
483 return params;
484}
registerMooseAction("MooseApp", MaterialOutputAction, "add_output_aux_variables")
const ExecFlagType EXEC_TIMESTEP_END
Definition Moose.C:36
const ExecFlagType EXEC_INITIAL
Definition Moose.C:30
unsigned int dim
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.
Base class for actions.
Definition Action.h:38
static InputParameters validParams()
Definition Action.C:26
MooseApp & _app
The MOOSE application this is associated with.
Definition MooseBase.h:375
std::shared_ptr< FEProblemBase > & _problem
Convenience reference to a problem this action works on.
Definition Action.h:178
const std::string & _current_task
The current action (even though we have separate instances for each action)
Definition Action.h:172
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.
Definition Factory.C:68
FunctorMaterials compute functor material properties.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
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.
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.
bool have_parameter(std::string_view name) const
A wrapper around the Parameters base class method.
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.
T & set(const std::string &name, bool quiet_mode=false)
Returns a writable reference to the named parameters.
bool isParamValid(const std::string &name) const
This method returns parameters that have been initialized in one fashion or another,...
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 &params)
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.
Definition MooseApp.h:217
const std::string & type() const
Get the type of this class.
Definition MooseBase.h:93
const std::string & name() const
Get the name of the class.
Definition MooseBase.h:103
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...
Definition MooseBase.h:271
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition MooseEnum.h:55
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
Definition Conversion.h:64
@ BOUNDARY_MATERIAL_DATA
Definition MooseTypes.h:748
@ BLOCK_MATERIAL_DATA
Definition MooseTypes.h:747
Meta data describing the setup of an output object.