Skip to content

Commit

Permalink
New approach (idaholab#26053)
Browse files Browse the repository at this point in the history
  • Loading branch information
dschwen authored and oanaoana committed Dec 12, 2023
1 parent 4a1f074 commit 347b81e
Show file tree
Hide file tree
Showing 21 changed files with 812 additions and 488 deletions.
156 changes: 128 additions & 28 deletions framework/include/actions/ProjectedStatefulMaterialStorageAction.h
Expand Up @@ -10,8 +10,18 @@
#pragma once

#include "Action.h"
#include "Registry.h"
#include "Conversion.h"
#include "SerialAccess.h"
#include "RankTwoTensorForward.h"
#include "RankFourTensorForward.h"
#include "libmesh/fe_type.h"

// created types
#include <InterpolatedStatefulMaterial.h>
#include <ProjectedStatefulMaterialAux.h>
#include <ProjectedStatefulMaterialNodalPatchRecovery.h>

/**
* Set up AuxKernels and AuxVariables for projected material property storage (PoMPS).
*/
Expand All @@ -30,38 +40,26 @@ class ProjectedStatefulMaterialStorageAction : public Action
/// List of supported types
typedef Moose::TypeList<Real, RealVectorValue, RankTwoTensor, RankFourTensor> SupportedTypes;

/// get an enum with all supported types
static MooseEnum getTypeEnum();

template <typename T, bool is_ad>
void processProperty(const MaterialPropertyName & prop_name);

protected:
/**
* Perform setup for a single scalar component of the material property prop_name, and gather the
* names of teh AuxVariables used to represent each component in `vars`.
*/
void processComponent(const std::string & prop_name,
std::vector<unsigned int> idx,
std::vector<VariableName> & vars,
bool is_ad);

/**
* Add the material object to obtain the interpolated old state (for use with
* InterpolatedStatefulMaterialPropertyInterface)
*/
void addMaterial(const std::string & prop_type,
const std::string & prop_name,
std::vector<VariableName> & vars);

enum class PropertyType
template <typename T, int I>
struct ProcessProperty
{
REAL,
REALVECTORVALUE,
RANKTWOTENSOR,
RANKFOURTENSOR
static void apply(ProjectedStatefulMaterialStorageAction * self,
const MaterialPropertyName & prop_name)
{
self->processProperty<T, false>(prop_name);
self->processProperty<T, true>(prop_name);
}
};
typedef std::pair<PropertyType, bool> PropertyInfo;

/**
* Return the property type and whether to use AD or not. If no property with a supported type is
* found, throw an error.
*/
PropertyInfo checkProperty(const std::string & prop_name);
template <typename... Ts>
static MooseEnum getTypeEnum(typename Moose::TypeList<Ts...>);

const std::vector<MaterialPropertyName> & _prop_names;

Expand All @@ -70,3 +68,105 @@ class ProjectedStatefulMaterialStorageAction : public Action
const std::string _var_type;
const std::string _pomps_prefix;
};

template <typename... Ts>
MooseEnum
ProjectedStatefulMaterialStorageAction::getTypeEnum(Moose::TypeList<Ts...>)
{
return MooseEnum(Moose::stringify(std::vector<std::string>{typeid(Ts).name()...}, " "));
}

template <typename T, bool is_ad>
void
ProjectedStatefulMaterialStorageAction::processProperty(const MaterialPropertyName & prop_name)
{
// check if a property of type T exists
const auto & data = _problem->getMaterialData(Moose::BLOCK_MATERIAL_DATA);
if (!data.haveGenericProperty<T, is_ad>(prop_name))
return;

// number of scalar components
const auto size = Moose::SerialAccess<T>::size();

// generate variable names
std::vector<VariableName> vars;
for (const auto i : make_range(size))
vars.push_back("_var_" + prop_name + '_' + Moose::stringify(i));

if (_current_task == "setup_projected_properties")
{
// add the AuxVars for storage
for (const auto & var : vars)
{
auto params = _factory.getValidParams(_var_type);
params.applyParameters(parameters());
params.set<std::vector<OutputName>>("outputs") = {"none"};
_problem->addAuxVariable(_var_type, var, params);
}

// add material
{
const auto type = Registry::getClassName<InterpolatedStatefulMaterialTempl<T>>();
auto params = _factory.getValidParams(type);
params.applySpecificParameters(parameters(), {"block"});
params.template set<std::vector<VariableName>>("old_state") = vars;
params.template set<MaterialPropertyName>("prop_name") = prop_name;
_problem->addMaterial(type, "_mat_" + prop_name, params);
}

// use nodal patch recovery for lagrange
if (_fe_type.family == LAGRANGE)
{
// nodal variables require patch recovery (add user object)
const auto & type =
Registry::getClassName<ProjectedStatefulMaterialNodalPatchRecoveryTempl<T, is_ad>>();
auto params = _factory.getValidParams(type);
params.applySpecificParameters(parameters(), {"block"});
params.template set<MaterialPropertyName>("property") = prop_name;
params.template set<MooseEnum>("patch_polynomial_order") = _order;
params.template set<ExecFlagEnum>("execute_on") = {EXEC_INITIAL, EXEC_TIMESTEP_END};
params.template set<bool>("force_preaux") = true;
_problem->addUserObject(type, "_npruo_" + prop_name, params);
}
}

if (_current_task == "add_aux_kernel")
{
// create variables
std::vector<std::string> auxnames;
for (const auto i : make_range(size))
auxnames.push_back("_aux_" + prop_name + '_' + Moose::stringify(i));

// use nodal patch recovery for lagrange
if (_fe_type.family == LAGRANGE)
{
// nodal variables require patch recovery (add aux kernel)
const auto & type = "ProjectedMaterialPropertyNodalPatchRecoveryAux";
for (const auto i : make_range(size))
{
auto params = _factory.getValidParams(type);
params.applySpecificParameters(parameters(), {"block"});
params.template set<AuxVariableName>("variable") = vars[i];
params.template set<unsigned int>("component") = i;
params.template set<UserObjectName>("nodal_patch_recovery_uo") = "_npruo_" + prop_name;
params.template set<ExecFlagEnum>("execute_on") = {EXEC_INITIAL, EXEC_TIMESTEP_END};
_problem->addAuxKernel(type, auxnames[i], params);
}
}
else
{
// elemental variables
const auto & type = Registry::getClassName<ProjectedStatefulMaterialAuxTempl<T, is_ad>>();
for (const auto i : make_range(size))
{
auto params = _factory.getValidParams(type);
params.applySpecificParameters(parameters(), {"block"});
params.template set<AuxVariableName>("variable") = vars[i];
params.template set<unsigned int>("component") = i;
params.template set<MaterialPropertyName>("prop") = prop_name;
params.template set<ExecFlagEnum>("execute_on") = {EXEC_INITIAL, EXEC_TIMESTEP_END};
_problem->addAuxKernel(type, auxnames[i], params);
}
}
}
}
13 changes: 4 additions & 9 deletions framework/include/auxkernels/NodalPatchRecoveryAux.h
Expand Up @@ -9,25 +9,20 @@

#pragma once

#include "AuxKernel.h"
#include "NodalPatchRecoveryAuxBase.h"

/// Forward declare user object
class NodalPatchRecoveryBase;

class NodalPatchRecoveryAux : public AuxKernel
class NodalPatchRecoveryAux : public NodalPatchRecoveryAuxBase
{
public:
static InputParameters validParams();

NodalPatchRecoveryAux(const InputParameters & parameters);

/**
* Block restrict elements on which to perform the variable/property nodal recovery.
*/
void blockRestrictElements(std::vector<dof_id_type> & elem_ids,
const std::vector<dof_id_type> & node_to_elem_pair_elems) const;

protected:
virtual Real computeValue() override;
virtual Real nodalPatchRecovery() override;

private:
const NodalPatchRecoveryBase & _npr;
Expand Down
36 changes: 36 additions & 0 deletions framework/include/auxkernels/NodalPatchRecoveryAuxBase.h
@@ -0,0 +1,36 @@
//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

#pragma once

#include "AuxKernel.h"

class NodalPatchRecoveryBase;

class NodalPatchRecoveryAuxBase : public AuxKernel
{
public:
static InputParameters validParams();

NodalPatchRecoveryAuxBase(const InputParameters & parameters);

/**
* Block restrict elements on which to perform the variable/property nodal recovery.
*/
void blockRestrictElements(std::vector<dof_id_type> & elem_ids,
const std::vector<dof_id_type> & node_to_elem_pair_elems) const;

protected:
virtual Real computeValue() override;

/// Override this to get the fitted value form a Nodal Patch Recovery User Object
virtual Real nodalPatchRecovery() = 0;

std::vector<dof_id_type> _elem_ids;
};
@@ -0,0 +1,30 @@
//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

#pragma once

#include "NodalPatchRecoveryAuxBase.h"

/// Forward declare user object
class ProjectedStatefulMaterialNodalPatchRecoveryBase;

class ProjectedMaterialPropertyNodalPatchRecoveryAux : public NodalPatchRecoveryAuxBase
{
public:
static InputParameters validParams();

ProjectedMaterialPropertyNodalPatchRecoveryAux(const InputParameters & parameters);

protected:
virtual Real nodalPatchRecovery() override;

private:
const ProjectedStatefulMaterialNodalPatchRecoveryBase & _npr;
const unsigned int _component;
};
23 changes: 19 additions & 4 deletions framework/include/auxkernels/ProjectedStatefulMaterialAux.h
Expand Up @@ -16,7 +16,7 @@

class MaterialBase;

template <bool is_ad>
template <typename T, bool is_ad>
class ProjectedStatefulMaterialAuxTempl : public AuxKernel
{
public:
Expand All @@ -29,11 +29,26 @@ class ProjectedStatefulMaterialAuxTempl : public AuxKernel
protected:
virtual Real computeValue() override;

const IndexableProperty<AuxKernel, is_ad> _prop;
const SubdomainID & _current_subdomain_id;

std::map<SubdomainID, std::vector<MaterialBase *>> _required_materials;

const GenericMaterialProperty<T, is_ad> & _prop;

const unsigned int _component;
};

typedef ProjectedStatefulMaterialAuxTempl<false> ProjectedStatefulMaterialAux;
typedef ProjectedStatefulMaterialAuxTempl<true> ADProjectedStatefulMaterialAux;
typedef ProjectedStatefulMaterialAuxTempl<Real, false> ProjectedStatefulMaterialRealAux;
typedef ProjectedStatefulMaterialAuxTempl<Real, true> ADProjectedStatefulMaterialRealAux;
typedef ProjectedStatefulMaterialAuxTempl<RealVectorValue, false>
ProjectedStatefulMaterialRealVectorValueAux;
typedef ProjectedStatefulMaterialAuxTempl<RealVectorValue, true>
ADProjectedStatefulMaterialRealVectorValueAux;
typedef ProjectedStatefulMaterialAuxTempl<RankTwoTensor, false>
ProjectedStatefulMaterialRankTwoTensorAux;
typedef ProjectedStatefulMaterialAuxTempl<RankTwoTensor, true>
ADProjectedStatefulMaterialRankTwoTensorAux;
typedef ProjectedStatefulMaterialAuxTempl<RankFourTensor, false>
ProjectedStatefulMaterialRankFourTensorAux;
typedef ProjectedStatefulMaterialAuxTempl<RankFourTensor, true>
ADProjectedStatefulMaterialRankFourTensorAux;
6 changes: 2 additions & 4 deletions framework/include/base/Registry.h
Expand Up @@ -253,10 +253,8 @@ template <typename T>
std::string
Registry::getRegisteredName()
{
for (const auto & [name, reg_ptr] : getRegistry()._name_to_entry)
if (std::dynamic_pointer_cast<T>(reg_ptr))
return name;
mooseError("The object of C++ type '", demangle(typeid(T).name()), "' has not registered.");
mooseDeprecated("Use Registry::getClassName() instead.");
return getClassName<T>();
}

template <typename T>
Expand Down
47 changes: 20 additions & 27 deletions framework/include/materials/InterpolatedStatefulMaterial.h
Expand Up @@ -14,16 +14,16 @@
#include "RankFourTensorForward.h"

/**
* PowerLawSoftening is a smeared crack softening model that
* uses a power law equation to soften the tensile response.
* It is for use with ComputeSmearedCrackingStress.
* Reconstitute a materal property from the old and older states of projected AuxVariables. Use
* though the ProjectedStatefulMaterialStorageAction.
*/
class InterpolatedStatefulMaterial : public Material
template <typename T>
class InterpolatedStatefulMaterialTempl : public Material
{
public:
static InputParameters validParams();

InterpolatedStatefulMaterial(const InputParameters & parameters);
InterpolatedStatefulMaterialTempl(const InputParameters & parameters);

virtual void computeQpProperties() override;

Expand All @@ -34,29 +34,22 @@ class InterpolatedStatefulMaterial : public Material
/// Older projected state
const std::vector<const VariableValue *> _older_state;

/// total number of components
const std::size_t _size;

/// emitted property name
const MaterialPropertyName _prop_name;

/// Property type
enum class PropType
{
REAL,
REALVECTORVALUE,
RANKTWOTENSOR,
RANKFOURTENSOR
} _prop_type;

///@{ Old interpolated properties
MaterialProperty<Real> * _prop_old_real;
MaterialProperty<RealVectorValue> * _prop_old_realvectorvalue;
MaterialProperty<RankTwoTensor> * _prop_old_ranktwotensor;
MaterialProperty<RankFourTensor> * _prop_old_rankfourtensor;
///@}

///@{ Older interpolated properties
MaterialProperty<Real> * _prop_older_real;
MaterialProperty<RealVectorValue> * _prop_older_realvectorvalue;
MaterialProperty<RankTwoTensor> * _prop_older_ranktwotensor;
MaterialProperty<RankFourTensor> * _prop_older_rankfourtensor;
///@}
/// Old interpolated property
MaterialProperty<T> & _prop_old;

/// Older interpolated properties
MaterialProperty<T> & _prop_older;
};

typedef InterpolatedStatefulMaterialTempl<Real> InterpolatedStatefulMaterialReal;
typedef InterpolatedStatefulMaterialTempl<RealVectorValue>
InterpolatedStatefulMaterialRealVectorValue;
typedef InterpolatedStatefulMaterialTempl<RankTwoTensor> InterpolatedStatefulMaterialRankTwoTensor;
typedef InterpolatedStatefulMaterialTempl<RankFourTensor>
InterpolatedStatefulMaterialRankFourTensor;

0 comments on commit 347b81e

Please sign in to comment.