Skip to content

Commit

Permalink
Refactor material output action (#27513)
Browse files Browse the repository at this point in the history
  • Loading branch information
dschwen committed May 2, 2024
1 parent 6e0f653 commit 436427c
Show file tree
Hide file tree
Showing 18 changed files with 253 additions and 581 deletions.
114 changes: 51 additions & 63 deletions framework/include/actions/MaterialOutputAction.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,15 @@
#include "Action.h"
#include "MaterialData.h"
#include "FEProblemBase.h"
#include "SerialAccess.h"

class MooseObjectAction;
class MaterialBase;

struct MaterialOutputActionDescriptor
{
};

/**
* Creates AuxVariables and AuxKernels for automatic output of material properties
*/
Expand All @@ -32,7 +37,45 @@ class MaterialOutputAction : public Action
MaterialOutputAction(const InputParameters & params);
virtual void act() override;

/// output function called from SetupOutput::apply (through Moose::typeLoop)
template <typename T, int I, bool is_ad>
void setupOutput(const MaterialPropertyName & prop_name, const MaterialBase & material);

protected:
template <typename T, int I, bool is_ad>
void setupOutputHelper(const MaterialPropertyName & prop_name, const MaterialBase & material);

/// List of supported raw types (equivalent AD types are also supported)
typedef Moose::TypeList<Real,
RealVectorValue,
RealTensorValue,
RankTwoTensor,
RankFourTensor,
SymmetricRankTwoTensor,
SymmetricRankFourTensor>
SupportedTypes;

/// List of AuxKernels used for the respective property type output ('AD' prefix is added automatically for is_ad)
static const std::vector<std::string> _aux_kernel_names;

/// List of index symbols
static const std::vector<std::string> _index_symbols;

/// List of coefficient parameter names
static const std::vector<std::vector<std::string>> _param_names;

template <typename T, int I>
struct SetupOutput
{
static void apply(MaterialOutputAction * self,
const MaterialPropertyName & prop_name,
const MaterialBase & material)
{
self->setupOutput<T, I, false>(prop_name, material);
self->setupOutput<T, I, true>(prop_name, material);
}
};

/**
* Helper method for testing if the material exists as a block or boundary material
* @tparam T The property type (e.g., REAL)
Expand All @@ -57,13 +100,6 @@ class MaterialOutputAction : public Action
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
*/
virtual std::vector<std::string> materialOutput(const std::string & property_name,
const MaterialBase & material,
bool get_names_only);

/**
* A method for retrieving and partially filling the InputParameters object for an AuxVariable
* @param type The type of AuxVariable
Expand All @@ -79,43 +115,6 @@ class MaterialOutputAction : public Action
const MaterialBase & material);

private:
/**
* Template method for creating the necessary objects for the various material property types
* @tparam T The type of material property that automatic output is being performed
* @param property_name The name of the 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> materialOutputHelper(const std::string & property_name,
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 a 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 All @@ -128,6 +127,9 @@ class MaterialOutputAction : public Action
/// List of variables for the current MaterialBase object
std::set<std::string> _material_variable_names;

/// property names we succeeded to set output up for
std::set<std::string> _supported_names;

/// Map of output names and list of variables associated with the output
std::map<OutputName, std::set<std::string>> _material_variable_names_map;

Expand All @@ -138,24 +140,6 @@ class MaterialOutputAction : public Action
const bool _output_only_on_timestep_end;
};

template <typename T>
std::vector<std::string>
MaterialOutputAction::materialOutputHelper(const std::string & /*property_name*/,
const MaterialBase & /*material*/,
bool /*get_names_only*/)
{
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 @@ -182,5 +166,9 @@ template <typename T>
bool
MaterialOutputAction::hasFunctorProperty(const std::string & property_name)
{
return _problem->hasFunctorWithType<T>(property_name, 0);
// functors support a limited set of types
if constexpr (std::is_same_v<T, Real> || std::is_same_v<T, RealVectorValue>)
return _problem->hasFunctorWithType<T>(property_name, 0);
else
return false;
}
50 changes: 47 additions & 3 deletions framework/include/auxkernels/MaterialAuxBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,29 @@ class MaterialAuxBaseTempl : public AuxKernelTempl<RT>
*/
MaterialAuxBaseTempl(const InputParameters & parameters);

/// Functors really only work for Real and RealVectorValue for now :(
using MaterialAuxFunctorType =
typename std::conditional<std::is_same_v<T, Real> || std::is_same_v<T, RealVectorValue>,
Moose::Functor<Moose::GenericType<T, is_ad>>,
void>::type;

protected:
virtual RT computeValue() override;

/// Perform a sanity check on teh retrieved value (e.g. to check dynamic sizes)
virtual void checkFullValue() {}

/// Returns material property values at quadrature points
virtual RT getRealValue() = 0;

/// Reference to the material property for this AuxKernel
const GenericMaterialProperty<T, is_ad> & _prop;
/// Material property for this AuxKernel
const GenericMaterialProperty<T, is_ad> * _property;

/// Functor for this AuxKernel
const MaterialAuxFunctorType * _functor;

/// T Value evaluated from either the property or the functor
Moose::GenericType<T, is_ad> _full_value;

private:
/// Multiplier for the material property
Expand All @@ -60,16 +75,45 @@ MaterialAuxBaseTempl<T, is_ad, RT>::validParams()
template <typename T, bool is_ad, typename RT>
MaterialAuxBaseTempl<T, is_ad, RT>::MaterialAuxBaseTempl(const InputParameters & parameters)
: AuxKernelTempl<RT>(parameters),
_prop(this->template getGenericMaterialProperty<T, is_ad>("property")),
_property(this->isParamValid("property")
? &this->template getGenericMaterialProperty<T, is_ad>("property")
: nullptr),
_functor(this->isParamValid("functor")
? [this]() {
if constexpr (!std::is_same_v<MaterialAuxFunctorType, void>)
return &this->template getFunctor<Moose::GenericType<T, is_ad>>("functor");
else
return nullptr;
}()
: nullptr),
_factor(this->template getParam<Real>("factor")),
_offset(this->template getParam<RT>("offset"))
{
if (!_property == !_functor)
mooseError("Specify either a `property` or a `functor` parameter.");
}

template <typename T, bool is_ad, typename RT>
RT
MaterialAuxBaseTempl<T, is_ad, RT>::computeValue()
{
if (_property)
_full_value = (*_property)[this->_qp];

if (_functor)
{
if constexpr (!std::is_same_v<MaterialAuxFunctorType, void>)
{
const auto elem_arg = this->makeElemArg(this->_current_elem);
const auto state = this->determineState();
_full_value = (*_functor)(elem_arg, state);
}
else
mooseError("Unsupported functor type");
}

checkFullValue();

return _factor * getRealValue() + _offset;
}

Expand Down
2 changes: 2 additions & 0 deletions framework/include/auxkernels/MaterialRateAuxBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ MaterialRateAuxBaseTempl<T, is_ad, RT>::MaterialRateAuxBaseTempl(const InputPara
: MaterialAuxBaseTempl<RT, is_ad>(parameters),
_prop_old(this->template getMaterialPropertyOld<T>("property"))
{
if (!this->_property)
this->paramError("functor", "This object does not support functors yet.");
}

template <typename T = Real>
Expand Down
8 changes: 5 additions & 3 deletions framework/include/auxkernels/MaterialRealVectorValueAux.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ class MaterialRealVectorValueAuxTempl : public MaterialAuxBaseTempl<T, is_ad>
};

typedef MaterialRealVectorValueAuxTempl<RealVectorValue, false> MaterialRealVectorValueAux;
typedef MaterialRealVectorValueAuxTempl<RealVectorValue,true> ADMaterialRealVectorValueAux;
typedef MaterialRealVectorValueAuxTempl<SymmetricRankTwoTensor, false> MaterialSymmetricRankTwoTensorAux;
typedef MaterialRealVectorValueAuxTempl<SymmetricRankTwoTensor,true> ADMaterialSymmetricRankTwoTensorAux;
typedef MaterialRealVectorValueAuxTempl<RealVectorValue, true> ADMaterialRealVectorValueAux;
typedef MaterialRealVectorValueAuxTempl<SymmetricRankTwoTensor, false>
MaterialSymmetricRankTwoTensorAux;
typedef MaterialRealVectorValueAuxTempl<SymmetricRankTwoTensor, true>
ADMaterialSymmetricRankTwoTensorAux;
1 change: 0 additions & 1 deletion framework/include/auxkernels/MaterialStdVectorAux.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ class MaterialStdVectorAuxTempl : public MaterialStdVectorAuxBaseTempl<Real, is_

using MaterialStdVectorAuxBaseTempl<Real, is_ad>::_qp;
using MaterialStdVectorAuxBaseTempl<Real, is_ad>::_q_point;
using MaterialStdVectorAuxBaseTempl<Real, is_ad>::_prop;
using MaterialStdVectorAuxBaseTempl<Real, is_ad>::_index;
};

Expand Down
21 changes: 8 additions & 13 deletions framework/include/auxkernels/MaterialStdVectorAuxBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#include "MaterialAuxBase.h"

/**
* A base class for the various Material related AuxKernal objects
* A base class for the various Material related AuxKernel objects
*/
template <typename T, bool is_ad>
class MaterialStdVectorAuxBaseTempl : public MaterialAuxBaseTempl<std::vector<T>, is_ad>
Expand All @@ -24,15 +24,10 @@ class MaterialStdVectorAuxBaseTempl : public MaterialAuxBaseTempl<std::vector<T>
MaterialStdVectorAuxBaseTempl(const InputParameters & parameters);

protected:
virtual Real computeValue() override;
virtual void checkFullValue() override;

/// index of the vecor element
/// index of the vector element
unsigned int _index;

// Explicitly declare the origin of the following inherited members
// https://isocpp.org/wiki/faq/templates#nondependent-name-lookup-members
using MaterialAuxBaseTempl<std::vector<T>, is_ad, Real>::_qp;
using MaterialAuxBaseTempl<std::vector<T>, is_ad, Real>::_prop;
};

template <typename T, bool is_ad>
Expand All @@ -53,13 +48,13 @@ MaterialStdVectorAuxBaseTempl<T, is_ad>::MaterialStdVectorAuxBaseTempl(
}

template <typename T, bool is_ad>
Real
MaterialStdVectorAuxBaseTempl<T, is_ad>::computeValue()
void
MaterialStdVectorAuxBaseTempl<T, is_ad>::checkFullValue()
{
mooseAssert(_prop[_qp].size() > _index,
mooseAssert(this->_full_value.size() > _index,
"MaterialStdVectorRealGradientAux: You chose to extract component "
<< _index << " but your Material property only has size " << _prop[_qp].size());
return MaterialAuxBaseTempl<std::vector<T>, is_ad>::computeValue();
<< _index << " but your Material property/functor only has size "
<< this->_full_value.size());
}

template <typename T = Real>
Expand Down
15 changes: 15 additions & 0 deletions framework/include/utils/MooseTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,11 @@ struct ADType<ChainedReal>
typedef ChainedADReal type;
};
template <>
struct ADType<RealVectorValue>
{
typedef ADRealVectorValue type;
};
template <>
struct ADType<RankTwoTensor>
{
typedef ADRankTwoTensor type;
Expand Down Expand Up @@ -414,6 +419,11 @@ struct ADType<W<Real>>
{
typedef W<ADReal> type;
};
template <template <typename> class W>
struct ADType<W<RealVectorValue>>
{
typedef W<ADRealVectorValue> type;
};
template <>
struct ADType<RealEigenVector>
{
Expand Down Expand Up @@ -477,6 +487,11 @@ struct ADType<W<ADReal>>
{
typedef W<ADReal> type;
};
template <template <typename> class W>
struct ADType<W<ADRealVectorValue>>
{
typedef W<ADRealVectorValue> type;
};

template <>
struct ADType<ADVariableValue>
Expand Down
Loading

0 comments on commit 436427c

Please sign in to comment.