47 #ifndef MUELU_MATRIXANALYSISFACTORY_DEF_HPP_
48 #define MUELU_MATRIXANALYSISFACTORY_DEF_HPP_
52 #include <Xpetra_Map.hpp>
53 #include <Xpetra_StridedMap.hpp>
59 #include "MueLu_Utilities.hpp"
63 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
66 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
69 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
75 return validParamList;
78 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
80 Input(fineLevel,
"A");
83 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
94 GetOStream(
Runtime0) <<
"~~~~~~~~ GENERAL INFORMATION ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (Level " << fineLevel.GetLevelID() <<
")" << std::endl;
95 GetOStream(
Runtime0) <<
"A is a " << A->getRangeMap()->getGlobalNumElements() <<
" x " << A->getDomainMap()->getGlobalNumElements() <<
" matrix." << std::endl;
97 if (A->IsView(
"stridedMaps") && Teuchos::rcp_dynamic_cast<
const StridedMap>(A->getRowMap(
"stridedMaps")) != Teuchos::null) {
101 std::vector<size_t> stridingInfo = strRowMap->getStridingData();
102 LO dofsPerNode = Teuchos::as<LocalOrdinal>(stridingInfo[blockid]);
103 GetOStream(
Runtime0) <<
"Strided row: " << dofsPerNode <<
" dofs per node. Strided block id = " << blockid << std::endl;
105 GetOStream(
Runtime0) <<
"Row: " << strRowMap->getFixedBlockSize() <<
" dofs per node" << std::endl;
109 if (A->IsView(
"stridedMaps") && Teuchos::rcp_dynamic_cast<
const StridedMap>(A->getColMap(
"stridedMaps")) != Teuchos::null) {
113 std::vector<size_t> stridingInfo = strDomMap->getStridingData();
114 LO dofsPerNode = Teuchos::as<LocalOrdinal>(stridingInfo[blockid]);
115 GetOStream(
Runtime0) <<
"Strided column: " << dofsPerNode <<
" dofs per node. Strided block id = " << blockid << std::endl;
117 GetOStream(
Runtime0) <<
"Column: " << strDomMap->getFixedBlockSize() <<
" dofs per node" << std::endl;
121 GetOStream(
Runtime0) <<
"A is distributed over " << comm->getSize() <<
" processors" << std::endl;
124 std::vector<LO> lelePerProc(comm->getSize(), 0);
125 std::vector<LO> gelePerProc(comm->getSize(), 0);
126 lelePerProc[comm->getRank()] = A->getLocalNumEntries();
127 Teuchos::reduceAll(*comm,
Teuchos::REDUCE_MAX, comm->getSize(), &lelePerProc[0], &gelePerProc[0]);
128 if (comm->getRank() == 0) {
129 for (
int i = 0; i < comm->getSize(); i++) {
130 if (gelePerProc[i] == 0) {
131 GetOStream(
Runtime0) <<
"Proc " << i <<
" is empty." << std::endl;
139 GetOStream(
Runtime0) <<
"~~~~~~~~ MATRIX DIAGONAL ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (Level " << fineLevel.GetLevelID() <<
")" << std::endl;
141 A->getLocalDiagCopy(*diagAVec);
150 for (
size_t i = 0; i < diagAVec->getMap()->getLocalNumElements(); ++i) {
154 lnearlyzerosOnDiagonal++;
162 MueLu_sumAll(comm, lnearlyzerosOnDiagonal, gnearlyzerosOnDiagonal);
165 if (gzerosOnDiagonal > 0) GetOStream(
Runtime0) <<
"Found " << gzerosOnDiagonal <<
" zeros on diagonal of A" << std::endl;
166 if (gnearlyzerosOnDiagonal > 0) GetOStream(
Runtime0) <<
"Found " << gnearlyzerosOnDiagonal <<
" entries with absolute value < 1.0e-6 on diagonal of A" << std::endl;
167 if (gnansOnDiagonal > 0) GetOStream(
Runtime0) <<
"Found " << gnansOnDiagonal <<
" entries with NAN or INF on diagonal of A" << std::endl;
172 GetOStream(
Runtime0) <<
"~~~~~~~~ DIAGONAL DOMINANCE ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (Level " << fineLevel.GetLevelID() <<
")" << std::endl;
179 double worstRatio = 99999999.9;
180 for (
size_t row = 0; row < A->getRowMap()->getLocalNumElements(); row++) {
183 size_t nnz = A->getNumEntriesInLocalRow(row);
188 A->getLocalRowView(row, indices, vals);
194 double normdiag = 0.0;
195 for (
size_t j = 0; j < Teuchos::as<size_t>(indices.
size()); j++) {
196 GO gcol = A->getColMap()->getGlobalElement(indices[j]);
203 if (normdiag >= norm1)
204 lnumWeakDiagDomRows++;
205 else if (normdiag > norm1)
206 lnumStrictDiagDomRows++;
209 if (normdiag / norm1 < worstRatio) worstRatio = normdiag / norm1;
213 MueLu_sumAll(comm, lnumWeakDiagDomRows, gnumWeakDiagDomRows);
214 MueLu_sumAll(comm, lnumStrictDiagDomRows, gnumStrictDiagDomRows);
216 GetOStream(
Runtime0) <<
"A has " << gnumWeakDiagDomRows <<
"/" << A->getRangeMap()->getGlobalNumElements() <<
" weakly diagonal dominant rows. (" << Teuchos::as<Scalar>(gnumWeakDiagDomRows / A->getRangeMap()->getGlobalNumElements() * 100) <<
"%)" << std::endl;
217 GetOStream(
Runtime0) <<
"A has " << gnumStrictDiagDomRows <<
"/" << A->getRangeMap()->getGlobalNumElements() <<
" strictly diagonal dominant rows. (" << Teuchos::as<Scalar>(gnumStrictDiagDomRows / A->getRangeMap()->getGlobalNumElements() * 100) <<
"%)" << std::endl;
220 Teuchos::reduceAll(*comm,
Teuchos::REDUCE_MIN, comm->getSize(), &worstRatio, &gworstRatio);
221 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;
228 GetOStream(
Runtime0) <<
"~~~~~~~~ Av with one vector ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (Level " << fineLevel.GetLevelID() <<
")" << std::endl;
230 ones->putScalar(one);
234 checkVectorEntries(res1, std::string(
"after applying the one vector to A"));
238 GetOStream(
Runtime0) <<
"~~~~~~~~ Av with random vector ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (Level " << fineLevel.GetLevelID() <<
")" << std::endl;
240 randvec->randomize();
244 checkVectorEntries(resrand, std::string(
"after applying random vector to A"));
249 GetOStream(
Runtime0) <<
"~~~~~~~~ Damped Jacobi sweep (one vector) ~~~~~~~~~~~~~~~~~~~~~~~ (Level " << fineLevel.GetLevelID() <<
")" << std::endl;
251 ones->putScalar(one);
255 checkVectorEntries(res1, std::string(
"after applying one vector to A"));
258 checkVectorEntries(invDiag, std::string(
"in invDiag"));
261 res2->elementWiseMultiply(0.8, *invDiag, *res1, 0.0);
262 checkVectorEntries(res2, std::string(
"after scaling Av with invDiag (with v the one vector)"));
263 res2->update(1.0, *ones, -1.0);
265 checkVectorEntries(res2, std::string(
"after applying one damped Jacobi sweep (with one vector)"));
270 GetOStream(
Runtime0) <<
"~~~~~~~~ Damped Jacobi sweep (random vector) ~~~~~~~~~~~~~~~~~~~~ (Level " << fineLevel.GetLevelID() <<
")" << std::endl;
276 checkVectorEntries(res1, std::string(
"after applying a random vector to A"));
279 checkVectorEntries(invDiag, std::string(
"in invDiag"));
282 res2->elementWiseMultiply(0.8, *invDiag, *res1, 0.0);
283 checkVectorEntries(res2, std::string(
"after scaling Av with invDiag (with v a random vector)"));
284 res2->update(1.0, *ones, -1.0);
286 checkVectorEntries(res2, std::string(
"after applying one damped Jacobi sweep (with v a random vector)"));
289 GetOStream(
Runtime0) <<
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (Level " << fineLevel.GetLevelID() <<
")" << std::endl;
292 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
302 for (
size_t i = 0; i < vec->getMap()->getLocalNumElements(); ++i) {
303 if (vecData[i] == zero) {
314 if (gzeros > 0) GetOStream(
Runtime0) <<
"Found " << gzeros <<
" zeros " << info << std::endl;
315 if (gnans > 0) GetOStream(
Runtime0) <<
"Found " << gnans <<
" entries " << info << std::endl;
virtual ~MatrixAnalysisFactory()
Destructor.
#define MueLu_sumAll(rcpComm, in, out)
void Build(Level &fineLevel, Level &coarseLevel) const
Build an object with this factory.
MueLu::DefaultLocalOrdinal LocalOrdinal
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
MatrixAnalysisFactory()
Constructor.
Timer to be used in factories. Similar to Monitor but with additional timers.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
One-liner description of what is happening.
void checkVectorEntries(const Teuchos::RCP< Vector > &vec, std::string info) const
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
MueLu::DefaultGlobalOrdinal GlobalOrdinal
Class that holds all level-specific information.
RCP< const ParameterList > GetValidParameterList() const
Return a const parameter list of valid parameters that setParameterList() will accept.
static RCP< Vector > GetMatrixDiagonalInverse(const Matrix &A, Magnitude tol=Teuchos::ScalarTraits< Scalar >::eps()*100, Scalar valReplacement=Teuchos::ScalarTraits< Scalar >::zero(), const bool doLumped=false)
Extract Matrix Diagonal.
static magnitudeType magnitude(T a)
void DeclareInput(Level &fineLevel, Level &coarseLevel) const
Specifies the data that this class needs, and the factories that generate that data.
Exception throws to report errors in the internal logical of the program.