Skip to content

Commit

Permalink
document improvements and more flexibility of interface variable chec…
Browse files Browse the repository at this point in the history
…k for the domain user object idaholab#19995
  • Loading branch information
YaqiWang committed Jul 9, 2022
1 parent 8a6ec04 commit 00a0a25
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 35 deletions.
4 changes: 3 additions & 1 deletion framework/doc/content/syntax/UserObjects/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@ and use the interface without the use of dynamic casts.
within the mesh on each execution flag.
- +SideUserObject+: "execute" is called for each +side+, that is on a boundary, within the mesh
on each execution flag.
- +InterfaceUserObject+: "execute" is called for each +side+, that is on an internal boundary, within the mesh
on each execution flag.
- +DomainUserObject+: this object is capable of executing all the operations of
a +ElementUserObject+, +InternalSideUserObject+, and +SideUserObject+
a +ElementUserObject+, +InternalSideUserObject+, +SideUserObject+ and +InterfaceUserObject+

## Restartable Data

Expand Down
1 change: 1 addition & 0 deletions framework/include/materials/MaterialPropertyInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ class MaterialPropertyInterface

/**
* Retrieve the property deduced from the name \p name for the specified \p material_data
* that can be defined on element, face and neighboring face.
*/
template <typename T>
const MaterialProperty<T> & getMaterialProperty(const std::string & name,
Expand Down
8 changes: 8 additions & 0 deletions framework/include/materials/ThreeMaterialPropertyInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@

// Forward Declarations
class MaterialData;

/**
* This interface is designed currently for DomainUserObject where material properties
* on element, face and neighboring face may all required. It can be used in the future
* by objects having similar requirements as DomainUserObject. The base interface
* TwoMaterialPropertyInterface only provides functions to retrieve material properties
* on face and neighboring face.
*/
class ThreeMaterialPropertyInterface : public TwoMaterialPropertyInterface
{
public:
Expand Down
31 changes: 23 additions & 8 deletions framework/include/userobject/DomainUserObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,17 @@ class Elem;
class QBase;
}

/**
* This user object allows related evaluations on elements, boundaries, internal sides,
* interfaces in one single place. DomainUserObject is still block restrictable.
* While evaluations on elements, boundaries and internal sides always happen,
* a parameter 'interface_boundaries' needs to be set to invoke evaluations on interfaces.
* We require this parameter for interface evaluations because we want to enforce sanity
* checks on coupling variables that are not defined on the domain this user object works on
* but only are available on interfaces.
* With this user object, evaluations do not have to be put into ElementUserObject,
* SideUserObject, InternalSideUserObject, and InterfaceUserObject separately.
*/
class DomainUserObject : public UserObject,
public BlockRestrictable,
public ThreeMaterialPropertyInterface,
Expand Down Expand Up @@ -101,10 +112,14 @@ class DomainUserObject : public UserObject,
/**
* Routes through to \p Coupleable::getFieldVar, but also inserts the return variable into a set
* of field variables to check on interface-connected blocks, as opposed to our blocks, when
* performing our block-restriction integrity check
* performing our block-restriction integrity check.
* The argument \p interfaces is optional specifying on what interfaces the variable are expected
* to be defined. Default value means that the variable should be defined on all interfaces.
*/
const MooseVariableFieldBase * getInterfaceFieldVar(const std::string & var_name,
unsigned int comp);
const MooseVariableFieldBase *
getInterfaceFieldVar(const std::string & var_name,
unsigned int comp,
const std::set<BoundaryID> * interfaces = nullptr);

/// the Moose mesh
MooseMesh & _mesh;
Expand Down Expand Up @@ -144,11 +159,8 @@ class DomainUserObject : public UserObject,
/// The set of boundary IDs on which this object should perform \p executeOnInterface
std::set<BoundaryID> _interface_bnd_ids;

/// The set of blocks connected to our blocks through the \p _interface_bnd_ids data member
std::set<SubdomainID> _interface_connected_blocks;

/// The set of variables we wish to evaluate on the interface connected blocks
std::set<const MooseVariableFieldBase *> _interface_vars;
/// The set of blocks connected to our blocks through boundaries of the \p _interface_bnd_ids data member
std::map<BoundaryID, std::set<SubdomainID>> _interface_connected_blocks;

private:
void setVolumeData();
Expand Down Expand Up @@ -179,6 +191,9 @@ class DomainUserObject : public UserObject,
/// An array representing coordinate system volume modifications. Unity for Cartesian, 2piR for
/// RZ, 4piR^2 for spherical
const MooseArray<Real> & _coord;

/// The set of boundaries where variables we wish to evaluate
std::map<unsigned int, std::set<BoundaryID>> _interface_var_blocks;
};

inline void
Expand Down
11 changes: 7 additions & 4 deletions framework/include/utils/MooseMeshUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,13 @@ void changeBoundaryId(MeshBase & mesh,
const libMesh::boundary_id_type new_id,
bool delete_prev);

std::vector<libMesh::boundary_id_type>
getBoundaryIDs(const libMesh::MeshBase & mesh,
const std::vector<BoundaryName> & boundary_name,
bool generate_unknown);
std::vector<BoundaryID> getBoundaryIDs(const libMesh::MeshBase & mesh,
const std::vector<BoundaryName> & boundary_name,
bool generate_unknown);

std::set<BoundaryID> getBoundaryIDSet(const libMesh::MeshBase & mesh,
const std::vector<BoundaryName> & boundary_name,
bool generate_unknown);

/**
* Gets the boundary ID associated with the given BoundaryName.
Expand Down
17 changes: 9 additions & 8 deletions framework/src/loops/ComputeUserObjectsThread.C
Original file line number Diff line number Diff line change
Expand Up @@ -245,20 +245,21 @@ ComputeUserObjectsThread::onInterface(const Elem * elem, unsigned int side, Boun
if (!(neighbor->active()))
return;

std::vector<UserObject *> userobjs;
queryBoundary(Interfaces::InterfaceUserObject, bnd_id, userobjs);

bool should_execute = !userobjs.empty();
std::vector<UserObject *> interface_objs;
queryBoundary(Interfaces::InterfaceUserObject, bnd_id, interface_objs);

if (!should_execute && !_domain_objs.empty())
bool has_domain_objs = false;
if (!_domain_objs.empty())
for (const auto * const domain_uo : _domain_objs)
if (domain_uo->shouldExecuteOnInterface())
{
should_execute = true;
has_domain_objs = true;
break;
}

if (!should_execute)
// if we do not have any interface user objects and no domain user objects on the current
// interface
if (interface_objs.empty() && !has_domain_objs)
return;

_fe_problem.prepareFace(elem, _tid);
Expand All @@ -280,7 +281,7 @@ ComputeUserObjectsThread::onInterface(const Elem * elem, unsigned int side, Boun
// with the current element and side
_fe_problem.reinitMaterialsInterface(bnd_id, _tid);

for (const auto & uo : userobjs)
for (const auto & uo : interface_objs)
uo->execute();

for (auto & uo : _domain_objs)
Expand Down
37 changes: 23 additions & 14 deletions framework/src/userobject/DomainUserObject.C
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,7 @@ DomainUserObject::DomainUserObject(const InputParameters & parameters)
if (isParamValid("interface_boundaries"))
{
const auto & interface_boundaries = getParam<std::vector<BoundaryName>>("interface_boundaries");
const auto & interface_bnd_ids_vec = _mesh.getBoundaryIDs(interface_boundaries);
_interface_bnd_ids =
std::set<BoundaryID>(interface_bnd_ids_vec.begin(), interface_bnd_ids_vec.end());
_interface_bnd_ids = MooseMeshUtils::getBoundaryIDSet(_mesh, interface_boundaries, false);

for (const auto interface_bnd_id : _interface_bnd_ids)
{
Expand All @@ -78,35 +76,46 @@ DomainUserObject::DomainUserObject(const InputParameters & parameters)
continue;

// these are blocks connected to our blocks
_interface_connected_blocks.insert(interface_connected_block);
_interface_connected_blocks[interface_bnd_id].insert(interface_connected_block);
}
}
}
}

const MooseVariableFieldBase *
DomainUserObject::getInterfaceFieldVar(const std::string & var_name, const unsigned int comp)
DomainUserObject::getInterfaceFieldVar(const std::string & var_name,
const unsigned int comp,
const std::set<BoundaryID> * interfaces)
{
const auto * const field_var = getFieldVar(var_name, comp);
mooseAssert(field_var, "We should not be able to return a null variable");
_interface_vars.insert(field_var);
if (interfaces)
_interface_var_blocks[field_var->number()] = *interfaces;
else
_interface_var_blocks[field_var->number()] = _interface_bnd_ids;
return field_var;
}

void
DomainUserObject::checkVariable(const MooseVariableFieldBase & variable) const
{
if (_interface_vars.count(&variable))
auto it = _interface_var_blocks.find(variable.number());
if (it != _interface_var_blocks.end())
{
// we could have done this check in the constructor but to be consistent with other block
// restrictable checks, we'll do it here
for (const auto connected_block : _interface_connected_blocks)
if (!variable.hasBlocks(connected_block))
mooseError("Variable '",
variable.name(),
"' is not defined on the interface connected block '",
_mesh.getSubdomainName(connected_block),
"'");
auto & bnd_ids = it->second;
for (const auto bnd_id : bnd_ids)
{
const auto & connected_blocks = _interface_connected_blocks.at(bnd_id);
for (const auto & bid : connected_blocks)
if (!variable.hasBlocks(bid))
mooseError("Variable '",
variable.name(),
"' is not defined on the interface connected block '",
_mesh.getSubdomainName(bid),
"'");
}
}
else
BlockRestrictable::checkVariable(variable);
Expand Down
9 changes: 9 additions & 0 deletions framework/src/utils/MooseMeshUtils.C
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,15 @@ getBoundaryIDs(const libMesh::MeshBase & mesh,
return ids;
}

std::set<BoundaryID>
getBoundaryIDSet(const libMesh::MeshBase & mesh,
const std::vector<BoundaryName> & boundary_name,
bool generate_unknown)
{
auto boundaries = getBoundaryIDs(mesh, boundary_name, generate_unknown);
return std::set<BoundaryID>(boundaries.begin(), boundaries.end());
}

std::vector<subdomain_id_type>
getSubdomainIDs(const libMesh::MeshBase & mesh, const std::vector<SubdomainName> & subdomain_name)
{
Expand Down

0 comments on commit 00a0a25

Please sign in to comment.