forked from idaholab/moose
/
CouplingFunctorCheckAction.C
144 lines (116 loc) · 4.74 KB
/
CouplingFunctorCheckAction.C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html
#include "CouplingFunctorCheckAction.h"
#include "MooseApp.h"
#include "FEProblemBase.h"
#include "DisplacedProblem.h"
#include "NonlinearSystemBase.h"
#include "InputParameters.h"
#include "RelationshipManager.h"
#include "TimedPrint.h"
#include "libmesh/system.h"
#include "libmesh/communicator.h"
registerMooseAction("MooseApp", CouplingFunctorCheckAction, "coupling_functor_check");
defineLegacyParams(CouplingFunctorCheckAction);
InputParameters
CouplingFunctorCheckAction::validParams()
{
return Action::validParams();
}
CouplingFunctorCheckAction::CouplingFunctorCheckAction(InputParameters parameters)
: Action(parameters)
{
_name = "coupling_functor_check";
}
void
redistributeDofs(System & system)
{
// Localize the vectors
system.re_update();
// Determine what dofs should be ghosted
system.get_dof_map().distribute_dofs(system.get_mesh());
// Recreate any constraints
system.reinit_constraints();
// Reinitialize the vectors with the new send_lists. I know the method name below is not perfectly
// indicative of that...
system.prolong_vectors();
}
void
redistributeDofs(SubProblem & problem)
{
redistributeDofs(problem.systemBaseNonlinear().system());
redistributeDofs(problem.systemBaseAuxiliary().system());
}
void
CouplingFunctorCheckAction::act()
{
// If we're doing Jacobian-free, then we have no matrix and we can just return
if (_problem->solverParams()._type == Moose::ST_JFNK)
return;
auto & nl = _problem->getNonlinearSystemBase();
auto & dgs = nl.getDGKernelWarehouse();
auto & iks = nl.getInterfaceKernelWarehouse();
auto size = _app.relationshipManagers().size();
// to reduce typing
auto algebraic = Moose::RelationshipManagerType::ALGEBRAIC;
auto coupling = Moose::RelationshipManagerType::COUPLING;
// If we have any DGKernels or InterfaceKernels we need one layer of sparsity
if (dgs.size() || iks.size())
{
// We are going to add the algebraic ghosting and coupling functors one at a time because then
// we can keep track of whether we need to redistribute the dofs or not
// Flag to indicate where we need to call dofmap_reinit() on our ghosting functors. If
// DofMap::reinit gets called then we can toggle this to false
bool need_ghosting_reinit = true;
// Add the algebraic ghosting functors if we are running in parallel
if (_communicator.size() > 1)
{
addRelationshipManagers(algebraic, RelationshipManager::oneLayerGhosting(algebraic));
if (size != _app.relationshipManagers().size())
{
// If you didn't do the ghosting with your own actions, you're going to pay the price now.
// We have to reinit all the DofMaps so we can be sure that we've ghosted the necessary
// vector entries
TIME_SECTION(
"reinitVectorsAlgebraic", 5, "Reiniting Vectors Because of Algebraic Ghosting");
// Reassign the size because we're going to call addRelationshipManagers again for COUPLING
size = _app.relationshipManagers().size();
// Attach the algebraic ghosting functors to the DofMaps
_app.attachRelationshipManagers(algebraic);
redistributeDofs(*_problem);
if (auto displaced_problem = _problem->getDisplacedProblem())
redistributeDofs(*displaced_problem);
// DofMap::reinit calls through to the ghosting functors dofmap_reinit method, so we're
// covered
need_ghosting_reinit = false;
}
}
// Add the coupling functor. This plays a role regardless of whether we are running serially or
// in parallel
addRelationshipManagers(coupling, RelationshipManager::oneLayerGhosting(coupling));
if (size != _app.relationshipManagers().size())
{
TIME_SECTION("addRelationshipManagers", 5, "Adding Relationship Managers"));
_app.attachRelationshipManagers(coupling);
if (need_ghosting_reinit)
// Make sure that coupling matrices are attached to the coupling functors
_app.dofMapReinitForRMs();
// Reinit the libMesh (Implicit)System. This re-computes the sparsity pattern and then
// applies it to the ImplicitSystem's matrices. Note that does NOT make a call to
// DofMap::reinit, hence we have to call GhostingFunctor::dofmap_reinit ourselves in the
// call above
{
TIME_SECTION("nlSystemReinitCoupling",
5,
"Reinitializing Nonlinear System Due To Coupling Functors");
nl.system().reinit();
}
}
}
}