10 #ifndef MUELU_MATRIXANALYSISFACTORY_DEF_HPP_
11 #define MUELU_MATRIXANALYSISFACTORY_DEF_HPP_
15 #include <Xpetra_Map.hpp>
16 #include <Xpetra_StridedMap.hpp>
22 #include "MueLu_Utilities.hpp"
26 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
29 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
32 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
38 return validParamList;
41 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
43 Input(fineLevel,
"A");
46 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
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) {
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) {
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;
104 A->getLocalDiagCopy(*diagAVec);
113 for (
size_t i = 0; i < diagAVec->getMap()->getLocalNumElements(); ++i) {
117 lnearlyzerosOnDiagonal++;
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);
151 A->getLocalRowView(row, indices, vals);
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]);
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;
191 GetOStream(
Runtime0) <<
"~~~~~~~~ Av with one vector ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (Level " << fineLevel.GetLevelID() <<
")" << std::endl;
193 ones->putScalar(one);
197 checkVectorEntries(res1, std::string(
"after applying the one vector to A"));
201 GetOStream(
Runtime0) <<
"~~~~~~~~ Av with random vector ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (Level " << fineLevel.GetLevelID() <<
")" << std::endl;
203 randvec->randomize();
207 checkVectorEntries(resrand, std::string(
"after applying random vector to A"));
212 GetOStream(
Runtime0) <<
"~~~~~~~~ Damped Jacobi sweep (one vector) ~~~~~~~~~~~~~~~~~~~~~~~ (Level " << fineLevel.GetLevelID() <<
")" << std::endl;
214 ones->putScalar(one);
218 checkVectorEntries(res1, std::string(
"after applying one vector to A"));
221 checkVectorEntries(invDiag, std::string(
"in invDiag"));
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;
239 checkVectorEntries(res1, std::string(
"after applying a random vector to A"));
242 checkVectorEntries(invDiag, std::string(
"in invDiag"));
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;
255 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
265 for (
size_t i = 0; i < vec->getMap()->getLocalNumElements(); ++i) {
266 if (vecData[i] == zero) {
277 if (gzeros > 0) GetOStream(
Runtime0) <<
"Found " << gzeros <<
" zeros " << info << std::endl;
278 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
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.
ParameterList & set(std::string const &name, T &&value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
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.