diff --git a/framework/include/actions/CreateDisplacedProblemAction.h b/framework/include/actions/CreateDisplacedProblemAction.h index 750261f73da9..4f9eb2eb2590 100644 --- a/framework/include/actions/CreateDisplacedProblemAction.h +++ b/framework/include/actions/CreateDisplacedProblemAction.h @@ -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 */ @@ -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); +}; diff --git a/framework/include/relationshipmanagers/ElementSideNeighborLayers.h b/framework/include/relationshipmanagers/ElementSideNeighborLayers.h index df40349a21c8..45724c9f5aeb 100644 --- a/framework/include/relationshipmanagers/ElementSideNeighborLayers.h +++ b/framework/include/relationshipmanagers/ElementSideNeighborLayers.h @@ -33,6 +33,8 @@ 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; @@ -40,4 +42,3 @@ class ElementSideNeighborLayers : public FunctorRelationshipManager /// applicable and necessary when using DistributedMesh. unsigned short _layers; }; - diff --git a/framework/include/relationshipmanagers/RelationshipManager.h b/framework/include/relationshipmanagers/RelationshipManager.h index 9d92e15c5d40..6e6c5898ec7f 100644 --- a/framework/include/relationshipmanagers/RelationshipManager.h +++ b/framework/include/relationshipmanagers/RelationshipManager.h @@ -38,8 +38,9 @@ class RelationshipManager : public MooseObject, public libMesh::GhostingFunctor */ void init() { + if (!_inited) + internalInit(); _inited = true; - internalInit(); } /** @@ -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 @@ -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. @@ -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; }; - diff --git a/framework/src/actions/AddDGKernelAction.C b/framework/src/actions/AddDGKernelAction.C index 055a1c5306b5..7239b7aae45b 100644 --- a/framework/src/actions/AddDGKernelAction.C +++ b/framework/src/actions/AddDGKernelAction.C @@ -12,7 +12,6 @@ #include "NonlinearSystem.h" registerMooseAction("MooseApp", AddDGKernelAction, "add_dg_kernel"); -registerMooseAction("MooseApp", AddDGKernelAction, "ready_to_init"); template <> InputParameters @@ -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); } diff --git a/framework/src/actions/AddInterfaceKernelAction.C b/framework/src/actions/AddInterfaceKernelAction.C index b7cf276f60d9..cbb84e768638 100644 --- a/framework/src/actions/AddInterfaceKernelAction.C +++ b/framework/src/actions/AddInterfaceKernelAction.C @@ -12,7 +12,6 @@ #include "NonlinearSystem.h" registerMooseAction("MooseApp", AddInterfaceKernelAction, "add_interface_kernel"); -registerMooseAction("MooseApp", AddInterfaceKernelAction, "ready_to_init"); template <> InputParameters @@ -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); } diff --git a/framework/src/actions/AddRelationshipManager.C b/framework/src/actions/AddRelationshipManager.C index f6c17ae8cf67..ad0a4ce7b14f 100644 --- a/framework/src/actions/AddRelationshipManager.C +++ b/framework/src/actions/AddRelationshipManager.C @@ -13,6 +13,7 @@ registerMooseAction("MooseApp", AddRelationshipManager, "attach_geometric_rm"); registerMooseAction("MooseApp", AddRelationshipManager, "attach_algebraic_rm"); +registerMooseAction("MooseApp", AddRelationshipManager, "attach_coupling_rm"); template <> InputParameters @@ -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) diff --git a/framework/src/actions/CreateDisplacedProblemAction.C b/framework/src/actions/CreateDisplacedProblemAction.C index c4ee81212c6e..2603ac40fc11 100644 --- a/framework/src/actions/CreateDisplacedProblemAction.C +++ b/framework/src/actions/CreateDisplacedProblemAction.C @@ -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 @@ -46,8 +47,10 @@ 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"); @@ -55,8 +58,7 @@ CreateDisplacedProblemAction::addProxyAlgebraicRelationshipManagers(SystemBase & rm_params.set("mesh") = &to.mesh(); rm_params.set("other_system") = &from.system(); rm_params.set("for_whom") = "DisplacedMesh"; - rm_params.set("rm_type") = - Moose::RelationshipManagerType::ALGEBRAIC; + rm_params.set("rm_type") = rm_type; rm_params.set("use_displaced_mesh") = to.subproblem().name() == "DisplacedProblem"; @@ -65,44 +67,35 @@ CreateDisplacedProblemAction::addProxyAlgebraicRelationshipManagers(SystemBase & auto rm_obj = _factory.create( "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("attach_geometric_early") = false; - rm_params.set("mesh") = &to.mesh(); - rm_params.set("other_system") = &from.system(); - rm_params.set("for_whom") = "DisplacedMesh"; - rm_params.set("rm_type") = - Moose::RelationshipManagerType::GEOMETRIC; - - rm_params.set("use_displaced_mesh") = to.subproblem().name() == "DisplacedProblem"; + addProxyRelationshipManagers(to, from, Moose::RelationshipManagerType::COUPLING, "coupling"); +} - if (rm_params.areAllRequiredParamsValid()) - { - auto rm_obj = _factory.create( - "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 @@ -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); diff --git a/framework/src/base/Moose.C b/framework/src/base/Moose.C index f9de452d479f..10506e1495da 100644 --- a/framework/src/base/Moose.C +++ b/framework/src/base/Moose.C @@ -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); @@ -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); @@ -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)" diff --git a/framework/src/base/MooseApp.C b/framework/src/base/MooseApp.C index 56f75bccc324..5df851da4bcf 100644 --- a/framework/src/base/MooseApp.C +++ b/framework/src/base/MooseApp.C @@ -1698,7 +1698,8 @@ MooseApp::addRelationshipManager(std::shared_ptr 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; @@ -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); + } } } } diff --git a/framework/src/dgkernels/DGKernelBase.C b/framework/src/dgkernels/DGKernelBase.C index 7d3da48fd3b5..73c171f34de5 100644 --- a/framework/src/dgkernels/DGKernelBase.C +++ b/framework/src/dgkernels/DGKernelBase.C @@ -59,7 +59,8 @@ validParams() // 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; diff --git a/framework/src/interfacekernels/InterfaceKernelBase.C b/framework/src/interfacekernels/InterfaceKernelBase.C index 6090a443cc4d..37e470cde0ef 100644 --- a/framework/src/interfacekernels/InterfaceKernelBase.C +++ b/framework/src/interfacekernels/InterfaceKernelBase.C @@ -68,7 +68,8 @@ validParams() // Need one layer of ghosting params.addRelationshipManager("ElementSideNeighborLayers", Moose::RelationshipManagerType::GEOMETRIC | - Moose::RelationshipManagerType::ALGEBRAIC); + Moose::RelationshipManagerType::ALGEBRAIC | + Moose::RelationshipManagerType::COUPLING); return params; } diff --git a/framework/src/relationshipmanagers/ElementSideNeighborLayers.C b/framework/src/relationshipmanagers/ElementSideNeighborLayers.C index 25d16e287307..12af582f9a74 100644 --- a/framework/src/relationshipmanagers/ElementSideNeighborLayers.C +++ b/framework/src/relationshipmanagers/ElementSideNeighborLayers.C @@ -86,3 +86,10 @@ ElementSideNeighborLayers::internalInit() _functor = std::move(functor); } + +void +ElementSideNeighborLayers::dofmap_reinit() +{ + if (_dof_map) + static_cast(_functor.get())->set_dof_coupling(_dof_map->_dof_coupling); +} diff --git a/framework/src/relationshipmanagers/ProxyRelationshipManager.C b/framework/src/relationshipmanagers/ProxyRelationshipManager.C index 78f9a90bab70..b8ff972e034c 100644 --- a/framework/src/relationshipmanagers/ProxyRelationshipManager.C +++ b/framework/src/relationshipmanagers/ProxyRelationshipManager.C @@ -57,7 +57,7 @@ ProxyRelationshipManager::operator()(const MeshBase::const_element_iterator & /* (*(*gf_it))(other_elements_begin, other_elements_end, p, other_coupled_elements); } - // If we're geometric - run all the algebraic ghosting functors from the other system + // If we're algebraic - run all the algebraic ghosting functors from the other system if (isType(Moose::RelationshipManagerType::ALGEBRAIC)) { auto gf_it = _other_system->get_dof_map().algebraic_ghosting_functors_begin(); diff --git a/framework/src/relationshipmanagers/RelationshipManager.C b/framework/src/relationshipmanagers/RelationshipManager.C index 6a3beaabf943..c2c42ba56510 100644 --- a/framework/src/relationshipmanagers/RelationshipManager.C +++ b/framework/src/relationshipmanagers/RelationshipManager.C @@ -67,6 +67,7 @@ RelationshipManager::RelationshipManager(const InputParameters & parameters) "mesh", "Mesh is null in RelationshipManager constructor. This could well be because No mesh file " "was supplied and no generation block was provided")), + _dof_map(nullptr), _attach_geometric_early(getParam("attach_geometric_early")), _rm_type(getParam("rm_type")), _use_displaced_mesh(getParam("use_displaced_mesh")) diff --git a/framework/src/systems/NonlinearSystem.C b/framework/src/systems/NonlinearSystem.C index 950cd4fb1664..dbc50819bb37 100644 --- a/framework/src/systems/NonlinearSystem.C +++ b/framework/src/systems/NonlinearSystem.C @@ -94,10 +94,6 @@ NonlinearSystem::NonlinearSystem(FEProblemBase & fe_problem, const std::string & _use_coloring_finite_difference(false), _computed_scaling(false) { - _sys.get_dof_map().add_coupling_functor( - _sys.get_dof_map().default_coupling(), - false); // The false keeps it from getting added to the mesh - nonlinearSolver()->residual_object = &_nl_residual_functor; nonlinearSolver()->jacobian = Moose::compute_jacobian; nonlinearSolver()->bounds = Moose::compute_bounds; diff --git a/framework/src/utils/Conversion.C b/framework/src/utils/Conversion.C index 70e5aa8c7e3d..6a8de3c7b9c0 100644 --- a/framework/src/utils/Conversion.C +++ b/framework/src/utils/Conversion.C @@ -363,6 +363,9 @@ stringify(const RelationshipManagerType & t) return "ALGEBRAIC"; if (t == (RelationshipManagerType::GEOMETRIC | RelationshipManagerType::ALGEBRAIC)) return "GEOMETRIC and ALGEBRAIC"; + if (t == (RelationshipManagerType::GEOMETRIC | RelationshipManagerType::ALGEBRAIC | + RelationshipManagerType::COUPLING)) + return "GEOMETRIC and ALGEBRAIC and COUPLING"; if (t == RelationshipManagerType::COUPLING) return "COUPLING";