Skip to content

Commit

Permalink
Add functor material property shortcut output, closes idaholab#19382
Browse files Browse the repository at this point in the history
  • Loading branch information
GiudGiud committed Jan 2, 2024
1 parent 571d361 commit 70dbc8c
Show file tree
Hide file tree
Showing 2 changed files with 142 additions and 21 deletions.
46 changes: 46 additions & 0 deletions framework/include/actions/MaterialOutputAction.h
Expand Up @@ -32,6 +32,9 @@ class MaterialOutputAction : public Action
virtual void act() override;

protected:
/// Helper method for testing if the material exists as a block or boundary material
bool hasProperty(const std::string & property_name) const;

/**
* Helper method for testing if the material exists as a block or boundary material
* @tparam T The property type (e.g., REAL)
Expand All @@ -48,6 +51,14 @@ class MaterialOutputAction : public Action
template <typename T>
bool hasADProperty(const std::string & property_name);

/**
* Helper method for testing if the functor material property exists
* @tparam T The functor property type (e.g., REAL)
* @param property_name The name of the property to test
*/
template <typename T>
bool hasFunctorProperty(const std::string & property_name);

/**
* A function to be overriden by derived actions to handle a set of material property types
*/
Expand Down Expand Up @@ -88,6 +99,25 @@ class MaterialOutputAction : public Action
const MaterialBase & material,
bool get_names_only);

/**
* Template method for creating the necessary objects for the various functor material property
* types
* @tparam T The type of material property that automatic output is being performed
* @param property_name The name of the functor material property to output
* @param material A pointer to the MaterialBase object containing the property of interest
* @param get_names_only A bool used to indicate that only the variable names should be returned
*
* @return A vector of names that can be used as AuxVariable names
*
* By default this function produces an mooseError, you must create a specialization for any type
* that you wish to have the automatic output capability. Also, you need to add a test for this
* type within the act() method.
*/
template <typename T>
std::vector<std::string> functorMaterialOutputHelper(const std::string & property_name,
const MaterialBase & material,
bool get_names_only);

/// Pointer the MaterialData object storing the block restricted materials
const MaterialData * _block_material_data;

Expand Down Expand Up @@ -119,6 +149,15 @@ MaterialOutputAction::materialOutputHelper(const std::string & /*property_name*/
mooseError("Unknown type, you must create a specialization of materialOutputHelper");
}

template <typename T>
std::vector<std::string>
MaterialOutputAction::functorMaterialOutputHelper(const std::string & /*property_name*/,
const MaterialBase & /*material*/,
bool /*get_names_only*/)
{
mooseError("Unknown type, you must create a specialization of functorMaterialOutputHelper");
}

template <typename T>
bool
MaterialOutputAction::hasProperty(const std::string & property_name)
Expand All @@ -140,3 +179,10 @@ MaterialOutputAction::hasADProperty(const std::string & property_name)
else
return false;
}

template <typename T>
bool
MaterialOutputAction::hasFunctorProperty(const std::string & property_name)
{
return _problem->hasFunctorWithType<T>(property_name, 0);
}
117 changes: 96 additions & 21 deletions framework/src/actions/MaterialOutputAction.C
Expand Up @@ -53,6 +53,14 @@ template <>
std::vector<std::string> MaterialOutputAction::materialOutputHelper<RankFourTensor>(
const std::string & material_name, const MaterialBase & material, bool get_names_only);

template <>
std::vector<std::string> MaterialOutputAction::functorMaterialOutputHelper<Real>(
const std::string & material_name, const MaterialBase & material, bool get_names_only);

template <>
std::vector<std::string> MaterialOutputAction::functorMaterialOutputHelper<RealVectorValue>(
const std::string & material_name, const MaterialBase & material, bool get_names_only);

registerMooseAction("MooseApp", MaterialOutputAction, "add_output_aux_variables");

registerMooseAction("MooseApp", MaterialOutputAction, "add_aux_kernel");
Expand Down Expand Up @@ -153,29 +161,26 @@ MaterialOutputAction::act()
if (outputs_has_properties || outputs.find("none") == outputs.end())
{
// Add the material property for output if the name is contained in the 'output_properties'
// list
// or if the list is empty (all properties)
const std::set<std::string> names = mat->getSuppliedItems();
// list or if the list is empty (all properties)
const std::set<std::string> names =
output_properties.empty()
? mat->getSuppliedItems()
: std::set<std::string>(output_properties.begin(), output_properties.end());
for (const auto & name : names)
{
// Add the material property for output
if (output_properties.empty() ||
std::find(output_properties.begin(), output_properties.end(), name) !=
output_properties.end())
{
auto curr_material_names = materialOutput(name, *mat, get_names_only);
if (curr_material_names.size() == 0)
unsupported_names.insert(name);
material_names.insert(curr_material_names.begin(), curr_material_names.end());
}

// If the material object has limited outputs, store the variables associated with the
// output objects
if (!outputs.empty())
for (const auto & output_name : outputs)
_material_variable_names_map[output_name].insert(_material_variable_names.begin(),
_material_variable_names.end());
auto curr_material_names = materialOutput(name, *mat, get_names_only);
if (curr_material_names.size() == 0)
unsupported_names.insert(name);
material_names.insert(curr_material_names.begin(), curr_material_names.end());
}

// If the material object has limited outputs, store the variables associated with the
// output objects
if (!outputs.empty())
for (const auto & output_name : outputs)
_material_variable_names_map[output_name].insert(_material_variable_names.begin(),
_material_variable_names.end());
}
}
if (unsupported_names.size() > 0 && get_names_only)
Expand Down Expand Up @@ -209,7 +214,8 @@ MaterialOutputAction::act()
" has the same name as an existing variable, either use the material"
" declare_suffix parameter to disambiguate or the output_properties parameter"
" to restrict the material properties to output");
_problem->addAuxVariable("MooseVariableConstMonomial", var_name, params);
const auto suffix = hasProperty(var_name) ? "" : "_out";
_problem->addAuxVariable("MooseVariableConstMonomial", var_name + suffix, params);
}
if (material_names.size() > 0)
_console << COLOR_CYAN << "The following total " << material_names.size()
Expand Down Expand Up @@ -265,6 +271,18 @@ MaterialOutputAction::materialOutput(const std::string & property_name,
else if (hasProperty<RankFourTensor>(property_name))
names = materialOutputHelper<RankFourTensor>(property_name, material, get_names_only);

else if (hasFunctorProperty<Real>(property_name))
names = functorMaterialOutputHelper<Real>(property_name, material, get_names_only);

else if (hasFunctorProperty<ADReal>(property_name))
names = functorMaterialOutputHelper<Real>(property_name, material, get_names_only);

else if (hasFunctorProperty<RealVectorValue>(property_name))
names = functorMaterialOutputHelper<RealVectorValue>(property_name, material, get_names_only);

else if (hasFunctorProperty<ADRealVectorValue>(property_name))
names = functorMaterialOutputHelper<RealVectorValue>(property_name, material, get_names_only);

return names;
}

Expand All @@ -280,7 +298,12 @@ MaterialOutputAction::getParams(const std::string & type,
// Set the action parameters
InputParameters params = _factory.getValidParams(type);

params.set<MaterialPropertyName>("property") = property_name;
// Adapt for regular or functor materials
if (type.find("Material") != std::string::npos)
params.set<MaterialPropertyName>("property") = property_name;
else
params.set<MooseFunctorName>("functor") = property_name;

params.set<AuxVariableName>("variable") = variable_name;
if (_output_only_on_timestep_end)
params.set<ExecFlagEnum>("execute_on") = EXEC_TIMESTEP_END;
Expand All @@ -295,6 +318,16 @@ MaterialOutputAction::getParams(const std::string & type,
return params;
}

bool
MaterialOutputAction::hasProperty(const std::string & property_name) const
{
if (_block_material_data->hasProperty(property_name) ||
_boundary_material_data->hasProperty(property_name))
return true;
else
return false;
}

template <>
std::vector<std::string>
MaterialOutputAction::materialOutputHelper<Real>(const std::string & property_name,
Expand Down Expand Up @@ -491,3 +524,45 @@ MaterialOutputAction::materialOutputHelper<RankFourTensor>(const std::string & p

return names;
}

template <>
std::vector<std::string>
MaterialOutputAction::functorMaterialOutputHelper<Real>(const std::string & property_name,
const MaterialBase & material,
bool get_names_only)
{
std::vector<std::string> names = {property_name};
if (!get_names_only)
{
// add a '_out' suffix to avoid name conflicts between the functor property and aux-variable
auto params = getParams("FunctorAux", property_name, property_name + "_out", material);
_problem->addAuxKernel("FunctorAux", material.name() + property_name, params);
}

return names;
}

template <>
std::vector<std::string>
MaterialOutputAction::functorMaterialOutputHelper<RealVectorValue>(
const std::string & property_name, const MaterialBase & material, bool get_names_only)
{
std::array<char, 3> suffix = {{'x', 'y', 'z'}};
std::vector<std::string> names(3);
for (const auto i : make_range(Moose::dim))
{
std::ostringstream oss;
// add a '_out' suffix to avoid name conflicts between the functor property and aux-variable
oss << property_name << "_out_" << suffix[i];
names[i] = oss.str();

if (!get_names_only)
{
auto params = getParams("FunctorVectorElementalAux", property_name, oss.str(), material);
params.set<unsigned int>("component") = i;
_problem->addAuxKernel("FunctorVectorElementalAux", material.name() + oss.str(), params);
}
}

return names;
}

0 comments on commit 70dbc8c

Please sign in to comment.