Skip to content

Commit

Permalink
Add support for coupling functor relationship managers
Browse files Browse the repository at this point in the history
  • Loading branch information
lindsayad committed Jul 17, 2019
1 parent 7c981d7 commit a0b1c7a
Show file tree
Hide file tree
Showing 15 changed files with 127 additions and 72 deletions.
19 changes: 18 additions & 1 deletion framework/include/actions/CreateDisplacedProblemAction.h
Expand Up @@ -28,6 +28,11 @@ class CreateDisplacedProblemAction : public Action
virtual void act() override;

protected:
/**
* Sets up a ProxyRelationshipManager that copies coupling functor ghosting from->to
*/
void addProxyCouplingRelationshipManagers(SystemBase & to, SystemBase & from);

/**
* Sets up a ProxyRelationshipManager that copies algebraic ghosting from->to
*/
Expand All @@ -37,5 +42,17 @@ class CreateDisplacedProblemAction : public Action
* Sets up a ProxyRelationshipManager that copies geometric ghosting from->to
*/
void addProxyGeometricRelationshipManagers(SystemBase & to, SystemBase & from);
};

private:
/**
* Generic adder of ProxyRelationshipManagers
* @param to The system to add RelationshipManagers for
* @param from The system to copy RelationshipManagers over from
* @param rm_type The Moose::RelationshipManagerType, e.g. GEOMETRIC, ALGEBRAIC, or COUPLING
* @param type A string form of the type, e.g. "geometric", "algebraic", or "coupling"
*/
void addProxyRelationshipManagers(SystemBase & to,
SystemBase & from,
Moose::RelationshipManagerType rm_type,
std::string type);
};
Expand Up @@ -33,11 +33,12 @@ class ElementSideNeighborLayers : public FunctorRelationshipManager
virtual std::string getInfo() const override;
virtual bool operator==(const RelationshipManager & rhs) const override;

void dofmap_reinit() override;

protected:
virtual void internalInit() override;

/// Size of the halo or stencil of elements available in each local processors partition. Only
/// applicable and necessary when using DistributedMesh.
unsigned short _layers;
};

13 changes: 11 additions & 2 deletions framework/include/relationshipmanagers/RelationshipManager.h
Expand Up @@ -38,8 +38,9 @@ class RelationshipManager : public MooseObject, public libMesh::GhostingFunctor
*/
void init()
{
if (!_inited)
internalInit();
_inited = true;
internalInit();
}

/**
Expand Down Expand Up @@ -97,6 +98,11 @@ class RelationshipManager : public MooseObject, public libMesh::GhostingFunctor
*/
bool useDisplacedMesh() const { return _use_displaced_mesh; }

/**
* Set the dof map
*/
void setDofMap(const DofMap & dof_map) { _dof_map = &dof_map; }

protected:
/**
* Called before this RM is attached. Only called once
Expand All @@ -109,6 +115,10 @@ class RelationshipManager : public MooseObject, public libMesh::GhostingFunctor
/// Reference to the Mesh object
MooseMesh & _mesh;

/// Pointer to DofMap (may be null if this is geometric only). This is useful for setting coupling
/// matrices in call-backs from DofMap::reinit
const DofMap * _dof_map;

/// Boolean indicating whether this RM can be attached early (e.g. all parameters are known
/// without the need for inspecting things like variables or other parts of the system that
/// are not available.
Expand All @@ -124,4 +134,3 @@ class RelationshipManager : public MooseObject, public libMesh::GhostingFunctor
/// Which system this should go to (undisplaced or displaced)
const bool _use_displaced_mesh;
};

4 changes: 0 additions & 4 deletions framework/src/actions/AddDGKernelAction.C
Expand Up @@ -12,7 +12,6 @@
#include "NonlinearSystem.h"

registerMooseAction("MooseApp", AddDGKernelAction, "add_dg_kernel");
registerMooseAction("MooseApp", AddDGKernelAction, "ready_to_init");

template <>
InputParameters
Expand All @@ -37,7 +36,4 @@ AddDGKernelAction::act()
else
_problem->addDGKernel(_type, _name, _moose_object_pars);
}

if (_current_task == "ready_to_init")
_problem->getNonlinearSystemBase().dofMap().set_implicit_neighbor_dofs(true);
}
4 changes: 0 additions & 4 deletions framework/src/actions/AddInterfaceKernelAction.C
Expand Up @@ -12,7 +12,6 @@
#include "NonlinearSystem.h"

registerMooseAction("MooseApp", AddInterfaceKernelAction, "add_interface_kernel");
registerMooseAction("MooseApp", AddInterfaceKernelAction, "ready_to_init");

template <>
InputParameters
Expand All @@ -29,9 +28,6 @@ AddInterfaceKernelAction::AddInterfaceKernelAction(InputParameters params)
void
AddInterfaceKernelAction::act()
{
if (_current_task == "ready_to_init")
_problem->getNonlinearSystem().dofMap().set_implicit_neighbor_dofs(true);

if (_current_task == "add_interface_kernel")
_problem->addInterfaceKernel(_type, _name, _moose_object_pars);
}
11 changes: 8 additions & 3 deletions framework/src/actions/AddRelationshipManager.C
Expand Up @@ -13,6 +13,7 @@

registerMooseAction("MooseApp", AddRelationshipManager, "attach_geometric_rm");
registerMooseAction("MooseApp", AddRelationshipManager, "attach_algebraic_rm");
registerMooseAction("MooseApp", AddRelationshipManager, "attach_coupling_rm");

template <>
InputParameters
Expand All @@ -26,9 +27,13 @@ AddRelationshipManager::AddRelationshipManager(InputParameters params) : Action(
void
AddRelationshipManager::act()
{
Moose::RelationshipManagerType rm_type =
(_current_task == "attach_geometric_rm" ? Moose::RelationshipManagerType::GEOMETRIC
: Moose::RelationshipManagerType::ALGEBRAIC);
Moose::RelationshipManagerType rm_type;
if (_current_task == "attach_geometric_rm")
rm_type = Moose::RelationshipManagerType::GEOMETRIC;
else if (_current_task == "attach_algebraic_rm")
rm_type = Moose::RelationshipManagerType::ALGEBRAIC;
else
rm_type = Moose::RelationshipManagerType::COUPLING;

const auto & all_action_ptrs = _awh.allActionBlocks();
for (const auto & action_ptr : all_action_ptrs)
Expand Down
58 changes: 27 additions & 31 deletions framework/src/actions/CreateDisplacedProblemAction.C
Expand Up @@ -18,6 +18,7 @@
registerMooseAction("MooseApp", CreateDisplacedProblemAction, "init_displaced_problem");
registerMooseAction("MooseApp", CreateDisplacedProblemAction, "add_geometric_rm");
registerMooseAction("MooseApp", CreateDisplacedProblemAction, "add_algebraic_rm");
registerMooseAction("MooseApp", CreateDisplacedProblemAction, "add_coupling_rm");

template <>
InputParameters
Expand Down Expand Up @@ -46,17 +47,18 @@ CreateDisplacedProblemAction::CreateDisplacedProblemAction(InputParameters param
}

void
CreateDisplacedProblemAction::addProxyAlgebraicRelationshipManagers(SystemBase & to,
SystemBase & from)
CreateDisplacedProblemAction::addProxyRelationshipManagers(SystemBase & to,
SystemBase & from,
Moose::RelationshipManagerType rm_type,
std::string type)
{
auto rm_params = _factory.getValidParams("ProxyRelationshipManager");

rm_params.set<bool>("attach_geometric_early") = false;
rm_params.set<MooseMesh *>("mesh") = &to.mesh();
rm_params.set<System *>("other_system") = &from.system();
rm_params.set<std::string>("for_whom") = "DisplacedMesh";
rm_params.set<Moose::RelationshipManagerType>("rm_type") =
Moose::RelationshipManagerType::ALGEBRAIC;
rm_params.set<Moose::RelationshipManagerType>("rm_type") = rm_type;

rm_params.set<bool>("use_displaced_mesh") = to.subproblem().name() == "DisplacedProblem";

Expand All @@ -65,44 +67,35 @@ CreateDisplacedProblemAction::addProxyAlgebraicRelationshipManagers(SystemBase &
auto rm_obj = _factory.create<RelationshipManager>(
"ProxyRelationshipManager",
to.subproblem().name() + "<-" + from.subproblem().name() + "_" + from.system().name() +
"_algebraic_proxy",
"_" + type + "_proxy",
rm_params);

if (!_app.addRelationshipManager(rm_obj))
_factory.releaseSharedObjects(*rm_obj);
}
else
mooseError("Invalid initialization of ElementSideNeighborLayers");
mooseError("Invalid initialization of ProxyRelationshipManager");
}

void
CreateDisplacedProblemAction::addProxyGeometricRelationshipManagers(SystemBase & to,
SystemBase & from)
CreateDisplacedProblemAction::addProxyCouplingRelationshipManagers(SystemBase & to,
SystemBase & from)
{
auto rm_params = _factory.getValidParams("ProxyRelationshipManager");

rm_params.set<bool>("attach_geometric_early") = false;
rm_params.set<MooseMesh *>("mesh") = &to.mesh();
rm_params.set<System *>("other_system") = &from.system();
rm_params.set<std::string>("for_whom") = "DisplacedMesh";
rm_params.set<Moose::RelationshipManagerType>("rm_type") =
Moose::RelationshipManagerType::GEOMETRIC;

rm_params.set<bool>("use_displaced_mesh") = to.subproblem().name() == "DisplacedProblem";
addProxyRelationshipManagers(to, from, Moose::RelationshipManagerType::COUPLING, "coupling");
}

if (rm_params.areAllRequiredParamsValid())
{
auto rm_obj = _factory.create<RelationshipManager>(
"ProxyRelationshipManager",
to.subproblem().name() + "<-" + from.subproblem().name() + "_" + from.system().name() +
"_geometric_proxy",
rm_params);
void
CreateDisplacedProblemAction::addProxyAlgebraicRelationshipManagers(SystemBase & to,
SystemBase & from)
{
addProxyRelationshipManagers(to, from, Moose::RelationshipManagerType::ALGEBRAIC, "algebraic");
}

if (!_app.addRelationshipManager(rm_obj))
_factory.releaseSharedObjects(*rm_obj);
}
else
mooseError("Invalid initialization of ElementSideNeighborLayers");
void
CreateDisplacedProblemAction::addProxyGeometricRelationshipManagers(SystemBase & to,
SystemBase & from)
{
addProxyRelationshipManagers(to, from, Moose::RelationshipManagerType::GEOMETRIC, "geometric");
}

void
Expand Down Expand Up @@ -149,10 +142,13 @@ CreateDisplacedProblemAction::act()
// get added to both systems on the receiving side
addProxyAlgebraicRelationshipManagers(undisplaced_nl, displaced_nl);
addProxyAlgebraicRelationshipManagers(displaced_nl, undisplaced_nl);

addProxyAlgebraicRelationshipManagers(undisplaced_aux, displaced_aux);
addProxyAlgebraicRelationshipManagers(displaced_aux, undisplaced_aux);

// There should be no need for couping in the aux system, so only do the non-linears
addProxyCouplingRelationshipManagers(undisplaced_nl, displaced_nl);
addProxyCouplingRelationshipManagers(displaced_nl, undisplaced_nl);

addProxyGeometricRelationshipManagers(undisplaced_nl, displaced_nl);
addProxyGeometricRelationshipManagers(displaced_nl, undisplaced_nl);

Expand Down
7 changes: 4 additions & 3 deletions framework/src/base/Moose.C
Expand Up @@ -199,6 +199,8 @@ addActionTypes(Syntax & syntax)

registerTask("add_algebraic_rm", false);
registerTask("attach_algebraic_rm", true);
registerTask("add_coupling_rm", false);
registerTask("attach_coupling_rm", true);
registerTask("init_problem", true);
registerTask("check_copy_nodal_vars", true);
registerTask("copy_nodal_vars", true);
Expand All @@ -225,9 +227,6 @@ addActionTypes(Syntax & syntax)
registerTask("setup_function_complete", false);
registerTask("setup_variable_complete", false);
registerTask("ready_to_init", true);
appendMooseObjectTask("ready_to_init", InterfaceKernel);
appendMooseObjectTask("ready_to_init", VectorInterfaceKernel);
appendMooseObjectTask("ready_to_init", DGKernel);

// Output related actions
registerTask("add_output_aux_variables", true);
Expand Down Expand Up @@ -306,7 +305,9 @@ addActionTypes(Syntax & syntax)
"(add_material)"
"(add_output_aux_variables)"
"(add_algebraic_rm)"
"(add_coupling_rm)"
"(attach_algebraic_rm)"
"(attach_coupling_rm)"
"(init_problem)"
"(delete_remote_elements_post_equation_systems_init)"
"(add_output)"
Expand Down
61 changes: 41 additions & 20 deletions framework/src/base/MooseApp.C
Expand Up @@ -1698,7 +1698,8 @@ MooseApp::addRelationshipManager(std::shared_ptr<RelationshipManager> relationsh
// ReplicatedMesh unless we are splitting the mesh.
if (!_action_warehouse.mesh()->isDistributedMesh() && !_split_mesh &&
(relationship_manager->isType(Moose::RelationshipManagerType::GEOMETRIC) &&
!relationship_manager->isType(Moose::RelationshipManagerType::ALGEBRAIC)))
!(relationship_manager->isType(Moose::RelationshipManagerType::ALGEBRAIC) ||
relationship_manager->isType(Moose::RelationshipManagerType::COUPLING))))
return false;

bool add = true;
Expand Down Expand Up @@ -1754,38 +1755,58 @@ MooseApp::attachRelationshipManagers(Moose::RelationshipManagerType rm_type)
mesh->getMesh().add_ghosting_functor(*rm);
}

if (rm_type == Moose::RelationshipManagerType::ALGEBRAIC)
if (rm_type != Moose::RelationshipManagerType::GEOMETRIC)
{
// Now we've built the problem, so we can use it
auto & problem = _executioner->feProblem();

// Ensure that the relationship manager is initialized
rm->init();

// If it's also Geometric but didn't get attached early - then let's attach it now
if (rm->isType(Moose::RelationshipManagerType::GEOMETRIC) && !rm->attachGeometricEarly())
{
// Now that the Problem is built we'll get the mesh from there
auto & problem = _executioner->feProblem();
auto & mesh = problem.mesh();

rm->init();

if (rm->useDisplacedMesh() && _action_warehouse.displacedMesh())
_action_warehouse.displacedMesh()->getMesh().add_ghosting_functor(*rm);
else
mesh.getMesh().add_ghosting_functor(*rm);
problem.mesh().getMesh().add_ghosting_functor(*rm);
}

auto & problem = _executioner->feProblem();

// If it is not at all GEOMETRIC then it hasn't been inited
if (!rm->isType(Moose::RelationshipManagerType::GEOMETRIC))
rm->init();

if (rm->useDisplacedMesh() && problem.getDisplacedProblem())
{
problem.getDisplacedProblem()->nlSys().dofMap().add_algebraic_ghosting_functor(*rm);
problem.getDisplacedProblem()->auxSys().dofMap().add_algebraic_ghosting_functor(*rm);
if (rm_type == Moose::RelationshipManagerType::COUPLING)
{
auto & dof_map = problem.getDisplacedProblem()->nlSys().dofMap();
dof_map.add_coupling_functor(*rm);
rm->setDofMap(dof_map);
}
else // algebraic
{
// If we added this relationship manager as a coupling functor, there's no need to
// duplicate it as an algebraic ghosting functor
if (!rm->isType(Moose::RelationshipManagerType::COUPLING))
problem.getDisplacedProblem()->nlSys().dofMap().add_algebraic_ghosting_functor(*rm);

problem.getDisplacedProblem()->auxSys().dofMap().add_algebraic_ghosting_functor(*rm);
}
}
else
else // undisplaced
{
problem.getNonlinearSystemBase().dofMap().add_algebraic_ghosting_functor(*rm);
problem.getAuxiliarySystem().dofMap().add_algebraic_ghosting_functor(*rm);
if (rm_type == Moose::RelationshipManagerType::COUPLING)
{
auto & dof_map = problem.getNonlinearSystemBase().dofMap();
dof_map.add_coupling_functor(*rm);
rm->setDofMap(dof_map);
}
else // algebraic
{
// If we added this relationship manager as a coupling functor, there's no need to
// duplicate it as an algebraic ghosting functor
if (!rm->isType(Moose::RelationshipManagerType::COUPLING))
problem.getNonlinearSystemBase().dofMap().add_algebraic_ghosting_functor(*rm);

problem.getAuxiliarySystem().dofMap().add_algebraic_ghosting_functor(*rm);
}
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion framework/src/dgkernels/DGKernelBase.C
Expand Up @@ -59,7 +59,8 @@ validParams<DGKernelBase>()
// DG Kernels always need one layer of ghosting
params.addRelationshipManager("ElementSideNeighborLayers",
Moose::RelationshipManagerType::GEOMETRIC |
Moose::RelationshipManagerType::ALGEBRAIC);
Moose::RelationshipManagerType::ALGEBRAIC |
Moose::RelationshipManagerType::COUPLING);
params.registerBase("DGKernel");

return params;
Expand Down
3 changes: 2 additions & 1 deletion framework/src/interfacekernels/InterfaceKernelBase.C
Expand Up @@ -68,7 +68,8 @@ validParams<InterfaceKernelBase>()
// Need one layer of ghosting
params.addRelationshipManager("ElementSideNeighborLayers",
Moose::RelationshipManagerType::GEOMETRIC |
Moose::RelationshipManagerType::ALGEBRAIC);
Moose::RelationshipManagerType::ALGEBRAIC |
Moose::RelationshipManagerType::COUPLING);

return params;
}
Expand Down
Expand Up @@ -86,3 +86,10 @@ ElementSideNeighborLayers::internalInit()

_functor = std::move(functor);
}

void
ElementSideNeighborLayers::dofmap_reinit()
{
if (_dof_map)
static_cast<DefaultCoupling *>(_functor.get())->set_dof_coupling(_dof_map->_dof_coupling);
}

0 comments on commit a0b1c7a

Please sign in to comment.