61 SC SC_ZERO = Teuchos::ScalarTraits<SC>::zero();
63 size_t nDofsPerNode = 1;
64 if (A->IsView(
"stridedMaps")) {
65 Teuchos::RCP<const Map> permRowMapStrided = A->getRowMap(
"stridedMaps");
66 nDofsPerNode = Teuchos::rcp_dynamic_cast<const StridedMap>(permRowMapStrided)->getFixedBlockSize();
69 RCP<const Teuchos::Comm<int> > comm = A->getRowMap()->getComm();
72 std::vector<std::pair<GlobalOrdinal, GlobalOrdinal> > RowColPairs;
75 if (permWidth_ != nDofsPerNode)
76 BuildPermutations(nDofsPerNode);
79 LocalOrdinal lonDofsPerNode = Teuchos::as<LocalOrdinal>(nDofsPerNode);
80 Teuchos::ArrayView<const LocalOrdinal> indices;
81 Teuchos::ArrayView<const Scalar> vals;
82 Teuchos::SerialDenseMatrix<LocalOrdinal, Scalar> subBlockMatrix(nDofsPerNode, nDofsPerNode,
true);
83 std::vector<GlobalOrdinal> growIds(nDofsPerNode);
87 LocalOrdinal numLocalNodes = A->getRowMap()->getLocalNumElements() / nDofsPerNode;
88 for (
LocalOrdinal node = 0; node < numLocalNodes; ++node) {
90 subBlockMatrix.putScalar();
95 for (
LocalOrdinal lrdof = 0; lrdof < lonDofsPerNode; ++lrdof) {
97 growIds[lrdof] = grow;
100 A->getLocalRowView(A->getRowMap()->getLocalElement(grow), indices, vals);
103 typedef typename Teuchos::ScalarTraits<Scalar>::magnitudeType MT;
105 for (
size_t j = 0; j < Teuchos::as<size_t>(indices.size()); j++) {
106 if (Teuchos::ScalarTraits<Scalar>::magnitude(vals[j]) > maxVal) {
107 maxVal = Teuchos::ScalarTraits<Scalar>::magnitude(vals[j]);
113 for (
size_t j = 0; j < Teuchos::as<size_t>(indices.size()); j++) {
114 GlobalOrdinal gcol = A->getColMap()->getGlobalElement(indices[j]);
116 if (grnodeid == gcnodeid) {
117 if (maxVal != Teuchos::ScalarTraits<MT>::zero()) {
118 subBlockMatrix(lrdof, gcol % nDofsPerNode) = vals[j] / maxVal;
120 subBlockMatrix(lrdof, gcol % nDofsPerNode) = vals[j];
121 std::cout <<
"maxVal never should be zero!!!!" << std::endl;
140 std::vector<Scalar> performance_vector = std::vector<Scalar>(result_permvecs_.size());
141 for (
size_t t = 0; t < result_permvecs_.size(); t++) {
142 std::vector<int> vv = result_permvecs_[t];
144 for (
size_t j = 0; j < vv.size(); j++) {
145 value = value * subBlockMatrix(j, vv[j]);
147 performance_vector[t] = value;
160 typedef typename Teuchos::ScalarTraits<Scalar>::magnitudeType MT;
161 MT maxVal = Teuchos::ScalarTraits<MT>::zero();
162 size_t maxPerformancePermutationIdx = 0;
163 for (
size_t j = 0; j < Teuchos::as<size_t>(performance_vector.size()); j++) {
164 if (Teuchos::ScalarTraits<Scalar>::magnitude(performance_vector[j]) > maxVal) {
165 maxVal = Teuchos::ScalarTraits<Scalar>::magnitude(performance_vector[j]);
166 maxPerformancePermutationIdx = j;
171 std::vector<int> bestPerformancePermutation = result_permvecs_[maxPerformancePermutationIdx];
172 for (
size_t t = 0; t < nDofsPerNode; t++) {
173 RowColPairs.push_back(std::make_pair(growIds[t], growIds[bestPerformancePermutation[t]]));
179 Teuchos::RCP<Vector> Pperm = VectorFactory::Build(A->getRowMap());
180 Teuchos::RCP<Vector> Qperm = VectorFactory::Build(A->getDomainMap());
182 Pperm->putScalar(SC_ZERO);
183 Qperm->putScalar(SC_ZERO);
185 Teuchos::ArrayRCP<Scalar> PpermData = Pperm->getDataNonConst(0);
186 Teuchos::ArrayRCP<Scalar> QpermData = Qperm->getDataNonConst(0);
188 typename std::vector<std::pair<GlobalOrdinal, GlobalOrdinal> >::iterator p = RowColPairs.begin();
189 while (p != RowColPairs.end()) {
194 LocalOrdinal ljk = A->getDomainMap()->getLocalElement(jk);
196 Pperm->replaceLocalValue(lik, ik);
197 Qperm->replaceLocalValue(ljk, ik);
199 p = RowColPairs.erase(p);
202 if (RowColPairs.size() > 0) GetOStream(
Warnings0) <<
"MueLu::LocalPermutationStrategy: There are Row/col pairs left!" << std::endl;
208 Teuchos::RCP<CrsMatrixWrap> permPTmatrix = Teuchos::rcp(
new CrsMatrixWrap(A->getRowMap(), 1));
209 Teuchos::RCP<CrsMatrixWrap> permQTmatrix = Teuchos::rcp(
new CrsMatrixWrap(A->getRowMap(), 1));
211 for (
size_t row = 0; row < A->getLocalNumRows(); row++) {
212 Teuchos::ArrayRCP<GlobalOrdinal> indoutP(1, Teuchos::as<GO>(Teuchos::ScalarTraits<Scalar>::real(PpermData[row])));
213 Teuchos::ArrayRCP<GlobalOrdinal> indoutQ(1, Teuchos::as<GO>(Teuchos::ScalarTraits<Scalar>::real(QpermData[row])));
214 Teuchos::ArrayRCP<Scalar> valout(1, Teuchos::ScalarTraits<Scalar>::one());
215 permPTmatrix->insertGlobalValues(A->getRowMap()->getGlobalElement(row), indoutP.view(0, indoutP.size()), valout.view(0, valout.size()));
216 permQTmatrix->insertGlobalValues(A->getRowMap()->getGlobalElement(row), indoutQ.view(0, indoutQ.size()), valout.view(0, valout.size()));
219 permPTmatrix->fillComplete();
220 permQTmatrix->fillComplete();
234 Teuchos::RCP<Matrix> ApermQt = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*A,
false, *permQTmatrix,
false, GetOStream(
Statistics2),
true,
true);
235 Teuchos::RCP<Matrix> permPApermQt = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*permPmatrix,
false, *ApermQt,
false, GetOStream(
Statistics2),
true,
true);
244 Teuchos::RCP<Vector> diagVec = VectorFactory::Build(permPApermQt->getRowMap(),
true);
245 Teuchos::RCP<Vector> invDiagVec = VectorFactory::Build(permPApermQt->getRowMap(),
true);
246 Teuchos::ArrayRCP<Scalar> invDiagVecData = invDiagVec->getDataNonConst(0);
248 LO lCntZeroDiagonals = 0;
249 permPApermQt->getLocalDiagCopy(*diagVec);
250 Teuchos::ArrayRCP<const Scalar> diagVecData = diagVec->getData(0);
251 for (
size_t i = 0; i < diagVec->getMap()->getLocalNumElements(); ++i) {
252 if (diagVecData[i] != SC_ZERO)
253 invDiagVecData[i] = Teuchos::ScalarTraits<Scalar>::one() / diagVecData[i];
255 invDiagVecData[i] = Teuchos::ScalarTraits<Scalar>::one();
262 GO gCntZeroDiagonals = 0;
263 GO glCntZeroDiagonals = Teuchos::as<GlobalOrdinal>(lCntZeroDiagonals);
264 MueLu_sumAll(comm,glCntZeroDiagonals,gCntZeroDiagonals);
265 GetOStream(
Statistics0) <<
"MueLu::LocalPermutationStrategy: found " << gCntZeroDiagonals <<
" zeros on diagonal" << std::endl;
268 Teuchos::RCP<CrsMatrixWrap> diagScalingOp = Teuchos::rcp(
new CrsMatrixWrap(permPApermQt->getRowMap(), 1));
270 for (
size_t row = 0; row < A->getLocalNumRows(); row++) {
271 Teuchos::ArrayRCP<GlobalOrdinal> indout(1, permPApermQt->getRowMap()->getGlobalElement(row));
272 Teuchos::ArrayRCP<Scalar> valout(1, invDiagVecData[row]);
273 diagScalingOp->insertGlobalValues(A->getRowMap()->getGlobalElement(row), indout.view(0, indout.size()), valout.view(0, valout.size()));
275 diagScalingOp->fillComplete();
277 Teuchos::RCP<Matrix> scaledA = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*diagScalingOp,
false, *permPApermQt,
false, GetOStream(
Statistics2),
true,
true);
278 currentLevel.
Set(
"A", Teuchos::rcp_dynamic_cast<Matrix>(scaledA), genFactory);
280 currentLevel.
Set(
"permA", Teuchos::rcp_dynamic_cast<Matrix>(permPApermQt), genFactory);
281 currentLevel.
Set(
"permP", Teuchos::rcp_dynamic_cast<Matrix>(permPmatrix), genFactory);
282 currentLevel.
Set(
"permQT", Teuchos::rcp_dynamic_cast<Matrix>(permQTmatrix), genFactory);
283 currentLevel.
Set(
"permScaling", Teuchos::rcp_dynamic_cast<Matrix>(diagScalingOp), genFactory);
287 Teuchos::RCP<Vector> diagPVec = VectorFactory::Build(permPmatrix->getRowMap(),
true);
288 permPmatrix->getLocalDiagCopy(*diagPVec);
289 Teuchos::ArrayRCP<const Scalar> diagPVecData = diagPVec->getData(0);
292 for (
size_t i = 0; i < diagPVec->getMap()->getLocalNumElements(); ++i) {
293 if (diagPVecData[i] == SC_ZERO) {
294 lNumRowPermutations++;
299 MueLu_sumAll(diagPVec->getMap()->getComm(), lNumRowPermutations, gNumRowPermutations);
303 Teuchos::RCP<Vector> diagQTVec = VectorFactory::Build(permQTmatrix->getRowMap(),
true);
304 permQTmatrix->getLocalDiagCopy(*diagQTVec);
305 Teuchos::ArrayRCP<const Scalar> diagQTVecData = diagQTVec->getData(0);
308 for (
size_t i = 0; i < diagQTVec->getMap()->getLocalNumElements(); ++i) {
309 if (diagQTVecData[i] == SC_ZERO) {
310 lNumColPermutations++;
315 MueLu_sumAll(diagQTVec->getMap()->getComm(), lNumColPermutations, gNumColPermutations);
317 currentLevel.
Set(
"#RowPermutations", gNumRowPermutations, genFactory );
318 currentLevel.
Set(
"#ColPermutations", gNumColPermutations, genFactory );
319 currentLevel.
Set(
"#WideRangeRowPermutations", 0, genFactory );
320 currentLevel.
Set(
"#WideRangeColPermutations", 0, genFactory );
322 GetOStream(
Statistics0) <<
"#Row permutations/max possible permutations: " << gNumRowPermutations <<
"/" << diagPVec->getMap()->getGlobalNumElements() << std::endl;
323 GetOStream(
Statistics0) <<
"#Column permutations/max possible permutations: " << gNumColPermutations <<
"/" << diagQTVec->getMap()->getGlobalNumElements() << std::endl;