50 Teuchos::RCP<Matrix> A = Get<Teuchos::RCP<Matrix> >(coarseLevel,
"A");
51 Teuchos::RCP<const Teuchos::Comm<int> > comm = A->getRangeMap()->getComm();
57 GetOStream(
Runtime0) <<
"~~~~~~~~ GENERAL INFORMATION ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (Level " << fineLevel.
GetLevelID() <<
")" << std::endl;
58 GetOStream(
Runtime0) <<
"A is a " << A->getRangeMap()->getGlobalNumElements() <<
" x " << A->getDomainMap()->getGlobalNumElements() <<
" matrix." << std::endl;
60 if (A->IsView(
"stridedMaps") && Teuchos::rcp_dynamic_cast<const StridedMap>(A->getRowMap(
"stridedMaps")) != Teuchos::null) {
61 Teuchos::RCP<const StridedMap> strRowMap = Teuchos::rcp_dynamic_cast<const StridedMap>(A->getRowMap(
"stridedMaps"));
64 std::vector<size_t> stridingInfo = strRowMap->getStridingData();
65 LO dofsPerNode = Teuchos::as<LocalOrdinal>(stridingInfo[blockid]);
66 GetOStream(
Runtime0) <<
"Strided row: " << dofsPerNode <<
" dofs per node. Strided block id = " << blockid << std::endl;
68 GetOStream(
Runtime0) <<
"Row: " << strRowMap->getFixedBlockSize() <<
" dofs per node" << std::endl;
72 if (A->IsView(
"stridedMaps") && Teuchos::rcp_dynamic_cast<const StridedMap>(A->getColMap(
"stridedMaps")) != Teuchos::null) {
73 Teuchos::RCP<const StridedMap> strDomMap = Teuchos::rcp_dynamic_cast<const StridedMap>(A->getColMap(
"stridedMaps"));
76 std::vector<size_t> stridingInfo = strDomMap->getStridingData();
77 LO dofsPerNode = Teuchos::as<LocalOrdinal>(stridingInfo[blockid]);
78 GetOStream(
Runtime0) <<
"Strided column: " << dofsPerNode <<
" dofs per node. Strided block id = " << blockid << std::endl;
80 GetOStream(
Runtime0) <<
"Column: " << strDomMap->getFixedBlockSize() <<
" dofs per node" << std::endl;
84 GetOStream(
Runtime0) <<
"A is distributed over " << comm->getSize() <<
" processors" << std::endl;
87 std::vector<LO> lelePerProc(comm->getSize(), 0);
88 std::vector<LO> gelePerProc(comm->getSize(), 0);
89 lelePerProc[comm->getRank()] = A->getLocalNumEntries();
90 Teuchos::reduceAll(*comm, Teuchos::REDUCE_MAX, comm->getSize(), &lelePerProc[0], &gelePerProc[0]);
91 if (comm->getRank() == 0) {
92 for (
int i = 0; i < comm->getSize(); i++) {
93 if (gelePerProc[i] == 0) {
94 GetOStream(
Runtime0) <<
"Proc " << i <<
" is empty." << std::endl;
102 GetOStream(
Runtime0) <<
"~~~~~~~~ MATRIX DIAGONAL ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (Level " << fineLevel.
GetLevelID() <<
")" << std::endl;
103 Teuchos::RCP<Vector> diagAVec = VectorFactory::Build(A->getRowMap(),
true);
104 A->getLocalDiagCopy(*diagAVec);
105 Teuchos::ArrayRCP<const Scalar> diagAVecData = diagAVec->getData(0);
113 for (
size_t i = 0; i < diagAVec->getMap()->getLocalNumElements(); ++i) {
114 if (diagAVecData[i] == Teuchos::ScalarTraits<Scalar>::zero()) {
116 }
else if (Teuchos::ScalarTraits<Scalar>::magnitude(diagAVecData[i]) < 1e-6) {
117 lnearlyzerosOnDiagonal++;
118 }
else if (Teuchos::ScalarTraits<Scalar>::isnaninf(diagAVecData[i])) {
125 MueLu_sumAll(comm, lnearlyzerosOnDiagonal, gnearlyzerosOnDiagonal);
128 if (gzerosOnDiagonal > 0) GetOStream(
Runtime0) <<
"Found " << gzerosOnDiagonal <<
" zeros on diagonal of A" << std::endl;
129 if (gnearlyzerosOnDiagonal > 0) GetOStream(
Runtime0) <<
"Found " << gnearlyzerosOnDiagonal <<
" entries with absolute value < 1.0e-6 on diagonal of A" << std::endl;
130 if (gnansOnDiagonal > 0) GetOStream(
Runtime0) <<
"Found " << gnansOnDiagonal <<
" entries with NAN or INF on diagonal of A" << std::endl;
135 GetOStream(
Runtime0) <<
"~~~~~~~~ DIAGONAL DOMINANCE ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (Level " << fineLevel.
GetLevelID() <<
")" << std::endl;
142 double worstRatio = 99999999.9;
143 for (
size_t row = 0; row < A->getRowMap()->getLocalNumElements(); row++) {
146 size_t nnz = A->getNumEntriesInLocalRow(row);
149 Teuchos::ArrayView<const LocalOrdinal> indices;
150 Teuchos::ArrayView<const Scalar> vals;
151 A->getLocalRowView(row, indices, vals);
153 TEUCHOS_TEST_FOR_EXCEPTION(Teuchos::as<size_t>(indices.size()) != nnz,
Exceptions::RuntimeError,
"MueLu::MatrixAnalysisFactory::Build: number of nonzeros not equal to number of indices? Error.");
157 double normdiag = 0.0;
158 for (
size_t j = 0; j < Teuchos::as<size_t>(indices.size()); j++) {
159 GO gcol = A->getColMap()->getGlobalElement(indices[j]);
161 normdiag = Teuchos::as<double>(Teuchos::ScalarTraits<Scalar>::magnitude(vals[j]));
163 norm1 += Teuchos::as<double>(Teuchos::ScalarTraits<Scalar>::magnitude(vals[j]));
166 if (normdiag >= norm1)
167 lnumWeakDiagDomRows++;
168 else if (normdiag > norm1)
169 lnumStrictDiagDomRows++;
172 if (normdiag / norm1 < worstRatio) worstRatio = normdiag / norm1;
176 MueLu_sumAll(comm, lnumWeakDiagDomRows, gnumWeakDiagDomRows);
177 MueLu_sumAll(comm, lnumStrictDiagDomRows, gnumStrictDiagDomRows);
179 GetOStream(
Runtime0) <<
"A has " << gnumWeakDiagDomRows <<
"/" << A->getRangeMap()->getGlobalNumElements() <<
" weakly diagonal dominant rows. (" << Teuchos::as<Scalar>(gnumWeakDiagDomRows / A->getRangeMap()->getGlobalNumElements() * 100) <<
"%)" << std::endl;
180 GetOStream(
Runtime0) <<
"A has " << gnumStrictDiagDomRows <<
"/" << A->getRangeMap()->getGlobalNumElements() <<
" strictly diagonal dominant rows. (" << Teuchos::as<Scalar>(gnumStrictDiagDomRows / A->getRangeMap()->getGlobalNumElements() * 100) <<
"%)" << std::endl;
183 Teuchos::reduceAll(*comm, Teuchos::REDUCE_MIN, comm->getSize(), &worstRatio, &gworstRatio);
184 GetOStream(
Runtime0) <<
"The minimum of the ratio of diagonal element/ sum of off-diagonal elements is " << gworstRatio <<
". Values about 1.0 are ok." << std::endl;
187 SC one = Teuchos::ScalarTraits<Scalar>::one(), zero = Teuchos::ScalarTraits<Scalar>::zero();
191 GetOStream(
Runtime0) <<
"~~~~~~~~ Av with one vector ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (Level " << fineLevel.
GetLevelID() <<
")" << std::endl;
192 Teuchos::RCP<Vector> ones = VectorFactory::Build(A->getDomainMap(), 1);
193 ones->putScalar(one);
195 Teuchos::RCP<Vector> res1 = VectorFactory::Build(A->getRangeMap(),
false);
196 A->apply(*ones, *res1, Teuchos::NO_TRANS, one, zero);
197 checkVectorEntries(res1, std::string(
"after applying the one vector to A"));
201 GetOStream(
Runtime0) <<
"~~~~~~~~ Av with random vector ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (Level " << fineLevel.
GetLevelID() <<
")" << std::endl;
202 Teuchos::RCP<Vector> randvec = VectorFactory::Build(A->getDomainMap(), 1);
203 randvec->randomize();
205 Teuchos::RCP<Vector> resrand = VectorFactory::Build(A->getRangeMap(),
false);
206 A->apply(*randvec, *resrand, Teuchos::NO_TRANS, one, zero);
207 checkVectorEntries(resrand, std::string(
"after applying random vector to A"));
212 GetOStream(
Runtime0) <<
"~~~~~~~~ Damped Jacobi sweep (one vector) ~~~~~~~~~~~~~~~~~~~~~~~ (Level " << fineLevel.
GetLevelID() <<
")" << std::endl;
213 Teuchos::RCP<Vector> ones = VectorFactory::Build(A->getDomainMap(), 1);
214 ones->putScalar(one);
216 Teuchos::RCP<Vector> res1 = VectorFactory::Build(A->getRangeMap(),
false);
217 A->apply(*ones, *res1, Teuchos::NO_TRANS, one, zero);
218 checkVectorEntries(res1, std::string(
"after applying one vector to A"));
221 checkVectorEntries(invDiag, std::string(
"in invDiag"));
223 Teuchos::RCP<Vector> res2 = VectorFactory::Build(A->getRangeMap(),
false);
224 res2->elementWiseMultiply(0.8, *invDiag, *res1, 0.0);
225 checkVectorEntries(res2, std::string(
"after scaling Av with invDiag (with v the one vector)"));
226 res2->update(1.0, *ones, -1.0);
228 checkVectorEntries(res2, std::string(
"after applying one damped Jacobi sweep (with one vector)"));
233 GetOStream(
Runtime0) <<
"~~~~~~~~ Damped Jacobi sweep (random vector) ~~~~~~~~~~~~~~~~~~~~ (Level " << fineLevel.
GetLevelID() <<
")" << std::endl;
234 Teuchos::RCP<Vector> ones = VectorFactory::Build(A->getDomainMap(), 1);
237 Teuchos::RCP<Vector> res1 = VectorFactory::Build(A->getRangeMap(),
false);
238 A->apply(*ones, *res1, Teuchos::NO_TRANS, one, zero);
239 checkVectorEntries(res1, std::string(
"after applying a random vector to A"));
242 checkVectorEntries(invDiag, std::string(
"in invDiag"));
244 Teuchos::RCP<Vector> res2 = VectorFactory::Build(A->getRangeMap(),
false);
245 res2->elementWiseMultiply(0.8, *invDiag, *res1, 0.0);
246 checkVectorEntries(res2, std::string(
"after scaling Av with invDiag (with v a random vector)"));
247 res2->update(1.0, *ones, -1.0);
249 checkVectorEntries(res2, std::string(
"after applying one damped Jacobi sweep (with v a random vector)"));
252 GetOStream(
Runtime0) <<
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (Level " << fineLevel.
GetLevelID() <<
")" << std::endl;