Skip to content

Commit

Permalink
Proof of concept for executeJacobian() method (idaholab#5913)
Browse files Browse the repository at this point in the history
  • Loading branch information
dschwen committed Nov 4, 2015
1 parent b1dddc0 commit eb9027a
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 10 deletions.
11 changes: 11 additions & 0 deletions framework/include/userobject/ElementUserObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,21 @@ class ElementUserObject :
*/
virtual void execute() = 0;

/**
* This function will be called with the shape functions for jvar initialized. It
* can be used to compute Jacobian contributions of the UserObject.
*/
virtual void executeJacobian(unsigned int /*jvar*/) {}

/**
* Must override.
*
* @param uo The UserObject to be joined into _this_ object. Take the data from the uo object and "add" it into the data for this object.
*/
virtual void threadJoin(const UserObject & uo) = 0;

bool requestedJacobian(unsigned int var) const;

protected:
MooseMesh & _mesh;

Expand All @@ -82,6 +90,9 @@ class ElementUserObject :
QBase * & _qrule;
const MooseArray<Real> & _JxW;
const MooseArray<Real> & _coord;

/// flag store to indicate if a jacobian w.r.t. a non-linear variable with a given number is requested
std::vector<bool> _requested_jacobian_flag;
};

#endif
33 changes: 24 additions & 9 deletions framework/src/base/ComputeUserObjectsThread.C
Original file line number Diff line number Diff line change
Expand Up @@ -167,14 +167,6 @@ ComputeUserObjectsThread::onElement(const Elem * elem)
_fe_problem.reinitElem(elem, _tid);
_fe_problem.reinitMaterials(_subdomain, _tid);

// Prepare shape functions for ShapeElementUserObjects
if (_fe_problem.currentlyComputingJacobian())
{
const std::vector<unsigned int> & user_object_shape_variables = _fe_problem.assembly(_tid).userObjectShapeVariables();
for (unsigned int i = 0; i < user_object_shape_variables.size(); ++i)
_fe_problem.prepareShapes(user_object_shape_variables[i], _tid);
}

//Global UserObjects
for (std::vector<ElementUserObject *>::const_iterator UserObject_it = _user_objects[_tid].elementUserObjects(Moose::ANY_BLOCK_ID, _group).begin();
UserObject_it != _user_objects[_tid].elementUserObjects(Moose::ANY_BLOCK_ID, _group).end();
Expand All @@ -186,6 +178,30 @@ ComputeUserObjectsThread::onElement(const Elem * elem)
++UserObject_it)
(*UserObject_it)->execute();

// UserObject Jacobians
if (_fe_problem.currentlyComputingJacobian())
{
// Prepare shape functions for ShapeElementUserObjects
const std::vector<unsigned int> & user_object_shape_variables = _fe_problem.assembly(_tid).userObjectShapeVariables();
for (unsigned int i = 0; i < user_object_shape_variables.size(); ++i)
{
unsigned int jvar = user_object_shape_variables[i];
_fe_problem.prepareShapes(jvar, _tid);

for (std::vector<ElementUserObject *>::const_iterator UserObject_it = _user_objects[_tid].elementUserObjects(Moose::ANY_BLOCK_ID, _group).begin();
UserObject_it != _user_objects[_tid].elementUserObjects(Moose::ANY_BLOCK_ID, _group).end();
++UserObject_it)
if ((*UserObject_it)->requestedJacobian(jvar))
(*UserObject_it)->executeJacobian(jvar);

for (std::vector<ElementUserObject *>::const_iterator UserObject_it = _user_objects[_tid].elementUserObjects(_subdomain, _group).begin();
UserObject_it != _user_objects[_tid].elementUserObjects(_subdomain, _group).end();
++UserObject_it)
if ((*UserObject_it)->requestedJacobian(jvar))
(*UserObject_it)->executeJacobian(jvar);
}
}

_fe_problem.swapBackMaterials(_tid);
}

Expand Down Expand Up @@ -213,7 +229,6 @@ ComputeUserObjectsThread::onBoundary(const Elem *elem, unsigned int side, Bounda
void
ComputeUserObjectsThread::onInternalSide(const Elem *elem, unsigned int side)
{

// Get vectors of object pointers
const std::vector<InternalSideUserObject *> & block_uo = _user_objects[_tid].internalSideUserObjects(_subdomain, _group);
const std::vector<InternalSideUserObject *> & global_uo = _user_objects[_tid].internalSideUserObjects(Moose::ANY_BLOCK_ID, _group);
Expand Down
5 changes: 5 additions & 0 deletions framework/src/userobject/ElementUserObject.C
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,8 @@ ElementUserObject::ElementUserObject(const InputParameters & parameters) :
addMooseVariableDependency(coupled_vars[i]);
}

bool
ElementUserObject::requestedJacobian(unsigned int var) const
{
return var < _requested_jacobian_flag.size() && _requested_jacobian_flag[var];
}
12 changes: 11 additions & 1 deletion framework/src/userobject/ShapeElementUserObject.C
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,15 @@ ShapeElementUserObject::ShapeElementUserObject(const InputParameters & parameter
{
// all coupled variables of this user object will get iniitialized shape functions
for (unsigned int i = 0; i < _coupled_moose_vars.size(); ++i)
_assembly.registerUserObjectShapeVariable(_coupled_moose_vars[i]->number());
{
MooseVariable * moose_var = _coupled_moose_vars[i];
if (moose_var->kind() == Moose::VAR_NONLINEAR)
{
_assembly.registerUserObjectShapeVariable(moose_var->number());

if (_requested_jacobian_flag.size() <= moose_var->number())
_requested_jacobian_flag.resize(moose_var->number() + 1, false);
_requested_jacobian_flag[moose_var->number()] = true;
}
}
}

0 comments on commit eb9027a

Please sign in to comment.