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(coarseLevel,
"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.
int GetLevelID() const
Return level number.
Exception throws to report errors in the internal logical of the program.