50 typedef Teuchos::ScalarTraits<SC> STS;
52 const ParameterList &pL = GetParameterList();
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");
65 Teuchos::Array<char> dofStatus;
67 dofStatus = Get<Teuchos::Array<char> >(fineLevel,
"DofStatus");
70 dofStatus = Teuchos::Array<char>(unamalgA->getRowMap()->getLocalNumElements() ,
's');
72 bool bHasZeroDiagonal =
false;
75 TEUCHOS_TEST_FOR_EXCEPTION(dirOrNot.size() != dofStatus.size(),
MueLu::Exceptions::RuntimeError,
"MueLu::UnsmooshFactory::Build: inconsistent number of coarse DBC array and dofStatus array. dirOrNot.size() = " << dirOrNot.size() <<
" dofStatus.size() = " << dofStatus.size());
76 for (
decltype(dirOrNot.size()) i = 0; i < dirOrNot.size(); ++i) {
77 if (dirOrNot[i] ==
true) dofStatus[i] =
'p';
85 Teuchos::ArrayRCP<const size_t> amalgRowPtr(amalgP->getLocalNumRows());
86 Teuchos::ArrayRCP<const LocalOrdinal> amalgCols(amalgP->getLocalNumEntries());
87 Teuchos::ArrayRCP<const Scalar> amalgVals(amalgP->getLocalNumEntries());
88 Teuchos::RCP<CrsMatrix> amalgPcrs = toCrsMatrix(amalgP);
89 amalgPcrs->getAllValues(amalgRowPtr, amalgCols, amalgVals);
92 size_t paddedNrows = amalgP->getRowMap()->getLocalNumElements() * Teuchos::as<size_t>(maxDofPerNode);
95 Teuchos::ArrayRCP<size_t> newPRowPtr(paddedNrows + 1);
96 Teuchos::ArrayRCP<LocalOrdinal> newPCols(amalgP->getLocalNumEntries() * maxDofPerNode);
97 Teuchos::ArrayRCP<Scalar> newPVals(amalgP->getLocalNumEntries() * maxDofPerNode);
100 if (fineIsPadded ==
true || fineLevel.
GetLevelID() > 0) {
108 for (
decltype(amalgRowPtr.size()) i = 0; i < amalgRowPtr.size() - 1; i++) {
110 size_t rowLength = amalgRowPtr[i + 1] - amalgRowPtr[i];
113 for (
int j = 0; j < maxDofPerNode; j++) {
114 newPRowPtr[i * maxDofPerNode + j] = cnt;
115 if (dofStatus[i * maxDofPerNode + j] ==
's') {
117 for (
size_t k = 0; k < rowLength; k++) {
118 newPCols[cnt] = amalgCols[k + amalgRowPtr[i]] * maxDofPerNode + j;
119 newPVals[cnt++] = amalgVals[k + amalgRowPtr[i]];
125 newPRowPtr[paddedNrows] = cnt;
126 rowCount = paddedNrows;
134 for (
decltype(amalgRowPtr.size()) i = 0; i < amalgRowPtr.size() - 1; i++) {
136 size_t rowLength = amalgRowPtr[i + 1] - amalgRowPtr[i];
139 for (
int j = 0; j < maxDofPerNode; j++) {
142 if (dofStatus[i * maxDofPerNode + j] ==
's') {
143 newPRowPtr[rowCount++] = cnt;
145 for (
size_t k = 0; k < rowLength; k++) {
146 newPCols[cnt] = amalgCols[k + amalgRowPtr[i]] * maxDofPerNode + j;
147 newPVals[cnt++] = amalgVals[k + amalgRowPtr[i]];
150 if (dofStatus[i * maxDofPerNode + j] ==
'd') {
151 newPRowPtr[rowCount++] = cnt;
155 newPRowPtr[rowCount] = cnt;
161 std::vector<size_t> stridingInfo(1, maxDofPerNode);
163 GlobalOrdinal nCoarseDofs = amalgP->getDomainMap()->getLocalNumElements() * maxDofPerNode;
164 GlobalOrdinal indexBase = amalgP->getDomainMap()->getIndexBase();
165 RCP<const Map> coarseDomainMap = StridedMapFactory::Build(amalgP->getDomainMap()->lib(),
166 Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
170 amalgP->getDomainMap()->getComm(),
174 size_t nColCoarseDofs = Teuchos::as<size_t>(amalgP->getColMap()->getLocalNumElements() * maxDofPerNode);
175 Teuchos::Array<GlobalOrdinal> unsmooshColMapGIDs(nColCoarseDofs);
176 for (
size_t c = 0; c < amalgP->getColMap()->getLocalNumElements(); ++c) {
177 GlobalOrdinal gid = (amalgP->getColMap()->getGlobalElement(c) - indexBase) * maxDofPerNode + indexBase;
179 for (
int i = 0; i < maxDofPerNode; ++i) {
180 unsmooshColMapGIDs[c * maxDofPerNode + i] = gid + i;
183 Teuchos::RCP<Map> coarseColMap = MapFactory::Build(amalgP->getDomainMap()->lib(),
184 Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
185 unsmooshColMapGIDs(),
187 amalgP->getDomainMap()->getComm());
190 Teuchos::RCP<CrsMatrix> unamalgPCrs = CrsMatrixFactory::Build(unamalgA->getRowMap(),
192 maxDofPerNode * amalgP->getLocalMaxNumRowEntries());
193 for (
size_t i = 0; i < rowCount; i++) {
194 unamalgPCrs->insertLocalValues(i,
195 newPCols.view(newPRowPtr[i], newPRowPtr[i + 1] - newPRowPtr[i]),
196 newPVals.view(newPRowPtr[i], newPRowPtr[i + 1] - newPRowPtr[i]));
198 unamalgPCrs->fillComplete(coarseDomainMap, unamalgA->getRowMap());
200 Teuchos::RCP<Matrix> unamalgP = Teuchos::rcp(
new CrsMatrixWrap(unamalgPCrs));
202 Set(coarseLevel,
"P", unamalgP);