10 #ifndef PACKAGES_MUELU_SRC_GRAPH_MUELU_UNSMOOSHFACTORY_DEF_HPP_
11 #define PACKAGES_MUELU_SRC_GRAPH_MUELU_UNSMOOSHFACTORY_DEF_HPP_
19 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
22 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
25 validParamList->
set<
RCP<const FactoryBase> >(
"A", Teuchos::null,
"Generating factory for unamalgamated matrix. Row map of (unamalgamted) output prolongation operator should match row map of this A.");
26 validParamList->
set<
RCP<const FactoryBase> >(
"P", Teuchos::null,
"Generating factory of the (amalgamated) prolongator P");
27 validParamList->
set<
RCP<const FactoryBase> >(
"DofStatus", Teuchos::null,
"Generating factory for dofStatus array (usually the VariableDofLaplacdianFactory)");
29 validParamList->
set<
int>(
"maxDofPerNode", 1,
"Maximum number of DOFs per node");
30 validParamList->
set<
bool>(
"fineIsPadded",
false,
"true if finest level input matrix is padded");
32 return validParamList;
35 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
38 Input(fineLevel,
"A");
39 Input(coarseLevel,
"P");
44 Input(fineLevel,
"DofStatus");
47 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
55 RCP<Matrix> unamalgA = Get<RCP<Matrix> >(fineLevel,
"A");
56 RCP<Matrix> amalgP = Get<RCP<Matrix> >(coarseLevel,
"P");
59 int maxDofPerNode = pL.
get<
int>(
"maxDofPerNode");
60 bool fineIsPadded = pL.
get<
bool>(
"fineIsPadded");
66 if (fineLevel.GetLevelID() == 0) {
67 dofStatus = Get<Teuchos::Array<char> >(fineLevel,
"DofStatus");
72 bool bHasZeroDiagonal =
false;
76 for (decltype(dirOrNot.
size()) i = 0; i < dirOrNot.
size(); ++i) {
77 if (dirOrNot[i] ==
true) dofStatus[i] =
'p';
90 amalgPcrs->getAllValues(amalgRowPtr, amalgCols, amalgVals);
93 size_t paddedNrows = amalgP->getRowMap()->getLocalNumElements() * Teuchos::as<size_t>(maxDofPerNode);
101 if (fineIsPadded ==
true || fineLevel.GetLevelID() > 0) {
109 for (decltype(amalgRowPtr.size()) i = 0; i < amalgRowPtr.size() - 1; i++) {
111 size_t rowLength = amalgRowPtr[i + 1] - amalgRowPtr[i];
114 for (
int j = 0; j < maxDofPerNode; j++) {
115 newPRowPtr[i * maxDofPerNode + j] = cnt;
116 if (dofStatus[i * maxDofPerNode + j] ==
's') {
118 for (
size_t k = 0; k < rowLength; k++) {
119 newPCols[cnt] = amalgCols[k + amalgRowPtr[i]] * maxDofPerNode + j;
120 newPVals[cnt++] = amalgVals[k + amalgRowPtr[i]];
126 newPRowPtr[paddedNrows] = cnt;
127 rowCount = paddedNrows;
135 for (decltype(amalgRowPtr.size()) i = 0; i < amalgRowPtr.size() - 1; i++) {
137 size_t rowLength = amalgRowPtr[i + 1] - amalgRowPtr[i];
140 for (
int j = 0; j < maxDofPerNode; j++) {
143 if (dofStatus[i * maxDofPerNode + j] ==
's') {
144 newPRowPtr[rowCount++] = cnt;
146 for (
size_t k = 0; k < rowLength; k++) {
147 newPCols[cnt] = amalgCols[k + amalgRowPtr[i]] * maxDofPerNode + j;
148 newPVals[cnt++] = amalgVals[k + amalgRowPtr[i]];
151 if (dofStatus[i * maxDofPerNode + j] ==
'd') {
152 newPRowPtr[rowCount++] = cnt;
156 newPRowPtr[rowCount] = cnt;
162 std::vector<size_t> stridingInfo(1, maxDofPerNode);
164 GlobalOrdinal nCoarseDofs = amalgP->getDomainMap()->getLocalNumElements() * maxDofPerNode;
165 GlobalOrdinal indexBase = amalgP->getDomainMap()->getIndexBase();
166 RCP<const Map> coarseDomainMap = StridedMapFactory::Build(amalgP->getDomainMap()->lib(),
171 amalgP->getDomainMap()->getComm(),
175 size_t nColCoarseDofs = Teuchos::as<size_t>(amalgP->getColMap()->getLocalNumElements() * maxDofPerNode);
177 for (
size_t c = 0; c < amalgP->getColMap()->getLocalNumElements(); ++c) {
178 GlobalOrdinal gid = (amalgP->getColMap()->getGlobalElement(c) - indexBase) * maxDofPerNode + indexBase;
180 for (
int i = 0; i < maxDofPerNode; ++i) {
181 unsmooshColMapGIDs[c * maxDofPerNode + i] = gid + i;
184 Teuchos::RCP<Map> coarseColMap = MapFactory::Build(amalgP->getDomainMap()->lib(),
186 unsmooshColMapGIDs(),
188 amalgP->getDomainMap()->getComm());
193 maxDofPerNode * amalgP->getLocalMaxNumRowEntries());
194 for (
size_t i = 0; i < rowCount; i++) {
195 unamalgPCrs->insertLocalValues(i,
196 newPCols.view(newPRowPtr[i], newPRowPtr[i + 1] - newPRowPtr[i]),
197 newPVals.view(newPRowPtr[i], newPRowPtr[i + 1] - newPRowPtr[i]));
199 unamalgPCrs->fillComplete(coarseDomainMap, unamalgA->getRowMap());
203 Set(coarseLevel,
"P", unamalgP);
T & get(const std::string &name, T def_value)
Timer to be used in factories. Similar to Monitor but with additional timers.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
ParameterList & set(std::string const &name, T &&value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
void Build(Level &fineLevel, Level &coarseLevel) const
Build an object with this factory.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
MueLu::DefaultGlobalOrdinal GlobalOrdinal
void DeclareInput(Level &fineLevel, Level &coarseLevel) const
Input.
Class that holds all level-specific information.
UnsmooshFactory()
Constructor.
static Teuchos::ArrayRCP< const bool > DetectDirichletRowsExt(const Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > &A, bool &bHasZeroDiagonal, const Magnitude &tol=Teuchos::ScalarTraits< Scalar >::zero())
Detect Dirichlet rows (extended version)
int GetLevelID() const
Return level number.
Exception throws to report errors in the internal logical of the program.
RCP< const ParameterList > GetValidParameterList() const
Return a const parameter list of valid parameters that setParameterList() will accept.