Skip to content

Commit

Permalink
Making objects that live on internal sides work with stateful materia…
Browse files Browse the repository at this point in the history
…ls - refs idaholab#2972

More work is needed for boundary material objects.
  • Loading branch information
permcody authored and bobkinl committed Apr 29, 2014
1 parent 36bc3fb commit 90525c6
Show file tree
Hide file tree
Showing 19 changed files with 324 additions and 85 deletions.
6 changes: 6 additions & 0 deletions framework/include/base/AuxiliarySystem.h
Expand Up @@ -115,6 +115,12 @@ class AuxiliarySystem : public SystemTempl<TransientExplicitSystem>
*/
virtual Order getMinQuadratureOrder();

/**
* Indicated whether this system needs material properties on boundaries.
* @return Boolean if IntegratedBCs are active
*/
bool needMaterialOnSide(BoundaryID bnd_id, THREAD_ID tid);

protected:
void computeScalarVars(std::vector<AuxWarehouse> & auxs);
void computeNodalVars(std::vector<AuxWarehouse> & auxs);
Expand Down
1 change: 1 addition & 0 deletions framework/include/base/ComputeMaterialsObjectThread.h
Expand Up @@ -55,6 +55,7 @@ class ComputeMaterialsObjectThread : public ThreadedElementLoop<ConstElemRange>
MaterialPropertyStorage & _bnd_material_props;
std::vector<MaterialWarehouse> & _materials;
std::vector<Assembly *> & _assembly;
bool _need_internal_side_material;
};

#endif //COMPUTERESIDUALTHREAD_H
37 changes: 30 additions & 7 deletions framework/include/base/FEProblem.h
Expand Up @@ -699,6 +699,30 @@ class FEProblem :
*/
void setDebugTopResiduals(unsigned int n) { _dbg_top_residuals = n; }

/**
* These methods are used to determine whether stateful material properties need to be stored on
* internal sides. There are four situations where this may be the case: 1) DGKernels
* 2) IntegratedBCs 3)InternalSideUserObjects 4)ElementalAuxBCs
*
* Method 1:
* @param bnd_id the boundary id for which to see if stateful material properties need to be stored
* @param tid the THREAD_ID of the caller
* @return Boolean indicating whether material properties need to be stored
*
* Method 2:
* @param subdomain_id the subdomain id for which to see if stateful material properties need to be stored
* @param tid the THREAD_ID of the caller
* @return Boolean indicating whether material properties need to be stored
*/
bool needMaterialOnSide(BoundaryID bnd_id, THREAD_ID tid);
bool needMaterialOnSide(SubdomainID subdomain_id, THREAD_ID tid);

/**
* Dimension of the subspace spanned by vectors with a given prefix.
* @param prefix Prefix of the vectors spanning the subspace.
*/
unsigned int subspaceDim(const std::string& prefix) const {if (_subspace_dim.count(prefix)) return _subspace_dim.find(prefix)->second; else return 0;}

protected:
MooseMesh & _mesh;
EquationSystems _eq;
Expand Down Expand Up @@ -781,14 +805,13 @@ class FEProblem :
/// A map of objects that consume random numbers
std::map<std::string, RandomData *> _random_data_objects;

void computeUserObjectsInternal(std::vector<UserObjectWarehouse> & user_objects, UserObjectWarehouse::GROUP group);
// Cache for calculating materials on side
std::vector<LIBMESH_BEST_UNORDERED_MAP<SubdomainID, bool> > _block_mat_side_cache;

public:
/**
* Dimension of the subspace spanned by vectors with a given prefix.
* @param prefix Prefix of the vectors spanning the subspace.
*/
unsigned int subspaceDim(const std::string& prefix) const {if (_subspace_dim.count(prefix)) return _subspace_dim.find(prefix)->second; else return 0;}
// Cache for calculating materials on side
std::vector<LIBMESH_BEST_UNORDERED_MAP<BoundaryID, bool> > _bnd_mat_side_cache;

void computeUserObjectsInternal(std::vector<UserObjectWarehouse> & user_objects, UserObjectWarehouse::GROUP group);

protected:
void checkUserObjects();
Expand Down
14 changes: 12 additions & 2 deletions framework/include/base/NonlinearSystem.h
Expand Up @@ -33,6 +33,8 @@
#include "libmesh/sparse_matrix.h"
#include "libmesh/petsc_matrix.h"
#include "libmesh/coupling_matrix.h"
#include "libmesh/libmesh_common.h"
#include LIBMESH_INCLUDE_UNORDERED_MAP

class FEProblem;
class MoosePreconditioner;
Expand Down Expand Up @@ -389,9 +391,17 @@ class NonlinearSystem : public SystemTempl<TransientNonlinearImplicitSystem>

Moose::PCSideType getPCSide() { return _pc_side; }

bool doingDG() { return _doing_dg; }
/**
* Indicated whether this system needs material properties on boundaries.
* @return Boolean if IntegratedBCs are active
*/
bool needMaterialOnSide(BoundaryID bnd_id, THREAD_ID tid) const;

bool hasActiveIntegratedBCs(BoundaryID bnd_id, THREAD_ID tid) { return ! _bcs[tid].activeIntegrated(bnd_id).empty(); }
/**
* Indicates whether this system needs material properties on internal sides.
* @return Boolean if DGKernels are active
*/
bool needMaterialOnSide(SubdomainID subdomain_id, THREAD_ID tid) const;

public:
FEProblem & _fe_problem;
Expand Down
1 change: 1 addition & 0 deletions framework/include/base/ProjectMaterialProperties.h
Expand Up @@ -58,6 +58,7 @@ class ProjectMaterialProperties : public ThreadedElementLoop<ConstElemPointerRan
MaterialPropertyStorage & _bnd_material_props;
std::vector<MaterialWarehouse> & _materials;
std::vector<Assembly *> & _assembly;
bool _need_internal_side_material;
};

#endif //PROJECTMATERIALPROPERTIES_H
5 changes: 3 additions & 2 deletions framework/include/base/ThreadedElementLoopBase.h
Expand Up @@ -17,6 +17,7 @@

#include "ParallelUniqueId.h"
#include "MooseMesh.h"
#include "MooseTypes.h"

/**
* Base class for assembling-like calculations
Expand Down Expand Up @@ -88,10 +89,10 @@ class ThreadedElementLoopBase
THREAD_ID _tid;

/// The subdomain for the current element
unsigned int _subdomain;
SubdomainID _subdomain;

/// The subdomain for the last element
unsigned int _old_subdomain;
SubdomainID _old_subdomain;
};


Expand Down
6 changes: 3 additions & 3 deletions framework/include/bcs/BCWarehouse.h
Expand Up @@ -67,21 +67,21 @@ class BCWarehouse
* @param boundary_id Boundary ID
* @return Set of active integrated BCs
*/
std::vector<IntegratedBC *> activeIntegrated(BoundaryID boundary_id);
std::vector<IntegratedBC *> activeIntegrated(BoundaryID boundary_id) const;

/**
* Get active nodal boundary conditions
* @param boundary_id Boundary ID
* @return Set of active nodal BCs
*/
std::vector<NodalBC *> activeNodal(BoundaryID boundary_id);
std::vector<NodalBC *> activeNodal(BoundaryID boundary_id) const;

/**
* Get active preset nodal boundary conditions
* @param boundary_id Boundary ID
* @return Set of active preset nodal BCs
*/
std::vector<PresetNodalBC *> activePresetNodal(BoundaryID boundary_id);
std::vector<PresetNodalBC *> activePresetNodal(BoundaryID boundary_id) const;

protected:
/// integrated boundary conditions on a boundary
Expand Down
11 changes: 11 additions & 0 deletions framework/src/base/AuxiliarySystem.C
Expand Up @@ -418,3 +418,14 @@ AuxiliarySystem::getMinQuadratureOrder()

return order;
}

bool
AuxiliarySystem::needMaterialOnSide(BoundaryID bnd_id, THREAD_ID tid)
{
for (unsigned int i=0; i < Moose::exec_types.size(); ++i)
if (!_auxs(Moose::exec_types[i])[0].activeBCs(bnd_id).empty() ||
!_auxs(Moose::exec_types[i])[0].activeBCs(Moose::ANY_BOUNDARY_ID).empty())
return true;

return false;
}
36 changes: 20 additions & 16 deletions framework/src/base/ComputeMaterialsObjectThread.C
Expand Up @@ -37,7 +37,8 @@ ThreadedElementLoop<ConstElemRange>(fe_problem, sys),
_material_props(material_props),
_bnd_material_props(bnd_material_props),
_materials(materials),
_assembly(assembly)
_assembly(assembly),
_need_internal_side_material(false)
{
}

Expand All @@ -51,7 +52,8 @@ ComputeMaterialsObjectThread::ComputeMaterialsObjectThread(ComputeMaterialsObjec
_material_props(x._material_props),
_bnd_material_props(x._bnd_material_props),
_materials(x._materials),
_assembly(x._assembly)
_assembly(x._assembly),
_need_internal_side_material(x._need_internal_side_material)
{
}

Expand All @@ -62,6 +64,8 @@ ComputeMaterialsObjectThread::~ComputeMaterialsObjectThread()
void
ComputeMaterialsObjectThread::subdomainChanged()
{
_need_internal_side_material = _fe_problem.needMaterialOnSide(_subdomain, _tid);

mooseAssert(_materials[_tid].hasMaterials(_subdomain), "No materials on subdomain block");
_fe_problem.subdomainSetup(_subdomain, _tid);
}
Expand All @@ -78,25 +82,25 @@ ComputeMaterialsObjectThread::onElement(const Elem *elem)
void
ComputeMaterialsObjectThread::onBoundary(const Elem *elem, unsigned int side, BoundaryID bnd_id)
{
// if (!_sys.hasActiveIntegratedBCs(bnd_id, _tid) && !_sys.doingDG())
// return;

_fe_problem.setCurrentBoundaryID(bnd_id);
_assembly[_tid]->reinit(elem, side);
unsigned int n_points = _assembly[_tid]->qRuleFace()->n_points();
_bnd_material_props.initStatefulProps(*_bnd_material_data[_tid], _materials[_tid].getFaceMaterials(_subdomain), n_points, *elem, side);
_fe_problem.setCurrentBoundaryID(Moose::INVALID_BOUNDARY_ID);
if (_fe_problem.needMaterialOnSide(bnd_id, _tid))
{
_fe_problem.setCurrentBoundaryID(bnd_id);
_assembly[_tid]->reinit(elem, side);
unsigned int n_points = _assembly[_tid]->qRuleFace()->n_points();
_bnd_material_props.initStatefulProps(*_bnd_material_data[_tid], _materials[_tid].getFaceMaterials(_subdomain), n_points, *elem, side);
_fe_problem.setCurrentBoundaryID(Moose::INVALID_BOUNDARY_ID);
}
}

void
ComputeMaterialsObjectThread::onInternalSide(const Elem *elem, unsigned int side)
{
if (!_sys.doingDG())
return;

_assembly[_tid]->reinit(elem, side);
unsigned int n_points = _assembly[_tid]->qRuleFace()->n_points();
_bnd_material_props.initStatefulProps(*_bnd_material_data[_tid], _materials[_tid].getFaceMaterials(_subdomain), n_points, *elem, side);
if (_need_internal_side_material)
{
_assembly[_tid]->reinit(elem, side);
unsigned int n_points = _assembly[_tid]->qRuleFace()->n_points();
_bnd_material_props.initStatefulProps(*_bnd_material_data[_tid], _materials[_tid].getFaceMaterials(_subdomain), n_points, *elem, side);
}
}

void
Expand Down
54 changes: 53 additions & 1 deletion framework/src/base/FEProblem.C
Expand Up @@ -206,6 +206,9 @@ FEProblem::FEProblem(const std::string & name, InputParameters parameters) :

_active_elemental_moose_variables.resize(n_threads);

_block_mat_side_cache.resize(n_threads);
_bnd_mat_side_cache.resize(n_threads);

_resurrector = new Resurrector(*this);

_eq.parameters.set<FEProblem *>("_fe_problem") = this;
Expand Down Expand Up @@ -1894,7 +1897,8 @@ FEProblem::addUserObject(std::string user_object_name, const std::string & name,
// Set a pointer to the correct material data; assume that it is a non-boundary material unless proven
// to be otherwise
MaterialData * mat_data = _material_data[tid];
if (parameters.have_parameter<std::vector<BoundaryName> >("boundary") && !parameters.have_parameter<bool>("block_restricted_nodal"))
if ((parameters.isParamValid("use_bnd_material") && parameters.get<bool>("use_bnd_material")) ||
(parameters.have_parameter<std::vector<BoundaryName> >("boundary") && !parameters.have_parameter<bool>("block_restricted_nodal")))
mat_data = _bnd_material_data[tid];

if (_displaced_problem != NULL && parameters.get<bool>("use_displaced_mesh"))
Expand Down Expand Up @@ -3743,3 +3747,51 @@ FEProblem::registerRandomInterface(RandomInterface & random_interface, const std
else
random_interface.setRandomDataPointer(_random_data_objects[name]);
}

bool
FEProblem::needMaterialOnSide(BoundaryID bnd_id, THREAD_ID tid)
{
if (_bnd_mat_side_cache[tid].find(bnd_id) == _bnd_mat_side_cache[tid].end())
{
_bnd_mat_side_cache[tid][bnd_id] = false;

if (_nl.needMaterialOnSide(bnd_id, tid) || _aux.needMaterialOnSide(bnd_id, tid))
_bnd_mat_side_cache[tid][bnd_id] = true;
else
{
for (unsigned int i=0; i < Moose::exec_types.size(); ++i)
if (!_user_objects(Moose::exec_types[i])[tid].sideUserObjects(bnd_id).empty() ||
!_user_objects(Moose::exec_types[i])[tid].sideUserObjects(Moose::ANY_BOUNDARY_ID).empty())
{
_bnd_mat_side_cache[tid][bnd_id] = true;
break;
}
}
}

return _bnd_mat_side_cache[tid][bnd_id];
}

bool
FEProblem::needMaterialOnSide(SubdomainID subdomain_id, THREAD_ID tid)
{
if (_block_mat_side_cache[tid].find(subdomain_id) == _block_mat_side_cache[tid].end())
{
_block_mat_side_cache[tid][subdomain_id] = false;

if (_nl.needMaterialOnSide(subdomain_id, tid))
_block_mat_side_cache[tid][subdomain_id] = true;
else
{
for (unsigned int i=0; i < Moose::exec_types.size(); ++i)
if (!_user_objects(Moose::exec_types[i])[tid].internalSideUserObjects(subdomain_id).empty() ||
!_user_objects(Moose::exec_types[i])[tid].internalSideUserObjects(Moose::ANY_BLOCK_ID).empty())
{
_block_mat_side_cache[tid][subdomain_id] = true;
break;
}
}
}

return _block_mat_side_cache[tid][subdomain_id];
}
12 changes: 12 additions & 0 deletions framework/src/base/NonlinearSystem.C
Expand Up @@ -2215,3 +2215,15 @@ NonlinearSystem::setPCSide(MooseEnum pcs)
else
mooseError("Unknown PC side specified.");
}

bool
NonlinearSystem::needMaterialOnSide(BoundaryID bnd_id, THREAD_ID tid) const
{
return !_bcs[tid].activeIntegrated(bnd_id).empty();
}

bool
NonlinearSystem::needMaterialOnSide(SubdomainID subdomain_id, THREAD_ID tid) const
{
return _doing_dg;
}

0 comments on commit 90525c6

Please sign in to comment.