47 #ifndef MUELU_MATRIXANALYSISFACTORY_DEF_HPP_
48 #define MUELU_MATRIXANALYSISFACTORY_DEF_HPP_
59 #include "MueLu_Utilities.hpp"
63 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
67 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
70 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
76 return validParamList;
79 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
81 Input(fineLevel,
"A");
84 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
95 GetOStream(
Runtime0) <<
"~~~~~~~~ GENERAL INFORMATION ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (Level " << fineLevel.GetLevelID() <<
")" << std::endl;
96 GetOStream(
Runtime0) <<
"A is a " << A->getRangeMap()->getGlobalNumElements() <<
" x " << A->getDomainMap()->getGlobalNumElements() <<
" matrix." << std::endl;
98 if (A->IsView(
"stridedMaps") && Teuchos::rcp_dynamic_cast<
const StridedMap>(A->getRowMap(
"stridedMaps")) != Teuchos::null) {
100 LocalOrdinal blockid = strRowMap->getStridedBlockId();
102 std::vector<size_t> stridingInfo = strRowMap->getStridingData();
103 LO dofsPerNode = Teuchos::as<LocalOrdinal>(stridingInfo[blockid]);
104 GetOStream(
Runtime0) <<
"Strided row: " << dofsPerNode <<
" dofs per node. Strided block id = " << blockid << std::endl;
106 GetOStream(
Runtime0) <<
"Row: " << strRowMap->getFixedBlockSize() <<
" dofs per node" << std::endl;
110 if (A->IsView(
"stridedMaps") && Teuchos::rcp_dynamic_cast<
const StridedMap>(A->getColMap(
"stridedMaps")) != Teuchos::null) {
112 LocalOrdinal blockid = strDomMap->getStridedBlockId();
114 std::vector<size_t> stridingInfo = strDomMap->getStridingData();
115 LO dofsPerNode = Teuchos::as<LocalOrdinal>(stridingInfo[blockid]);
116 GetOStream(
Runtime0) <<
"Strided column: " << dofsPerNode <<
" dofs per node. Strided block id = " << blockid << std::endl;
118 GetOStream(
Runtime0) <<
"Column: " << strDomMap->getFixedBlockSize() <<
" dofs per node" << std::endl;
123 GetOStream(
Runtime0) <<
"A is distributed over " << comm->getSize() <<
" processors" << std::endl;
126 std::vector<LO> lelePerProc(comm->getSize(),0);
127 std::vector<LO> gelePerProc(comm->getSize(),0);
128 lelePerProc[comm->getRank()] = A->getNodeNumEntries ();
130 if(comm->getRank() == 0) {
131 for(
int i=0; i<comm->getSize(); i++) {
132 if(gelePerProc[i] == 0) {
133 GetOStream(
Runtime0) <<
"Proc " << i <<
" is empty." << std::endl;
141 GetOStream(
Runtime0) <<
"~~~~~~~~ MATRIX DIAGONAL ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (Level " << fineLevel.GetLevelID() <<
")" << std::endl;
143 A->getLocalDiagCopy(*diagAVec);
145 GlobalOrdinal lzerosOnDiagonal = 0;
146 GlobalOrdinal gzerosOnDiagonal = 0;
147 GlobalOrdinal lnearlyzerosOnDiagonal = 0;
148 GlobalOrdinal gnearlyzerosOnDiagonal = 0;
149 GlobalOrdinal lnansOnDiagonal = 0;
150 GlobalOrdinal gnansOnDiagonal = 0;
152 for(
size_t i = 0; i<diagAVec->getMap()->getNodeNumElements(); ++i) {
156 lnearlyzerosOnDiagonal++;
164 MueLu_sumAll(comm, lnearlyzerosOnDiagonal, gnearlyzerosOnDiagonal);
167 if(gzerosOnDiagonal > 0) GetOStream(
Runtime0) <<
"Found " << gzerosOnDiagonal <<
" zeros on diagonal of A" << std::endl;
168 if(gnearlyzerosOnDiagonal > 0) GetOStream(
Runtime0) <<
"Found " << gnearlyzerosOnDiagonal <<
" entries with absolute value < 1.0e-6 on diagonal of A" << std::endl;
169 if(gnansOnDiagonal > 0) GetOStream(
Runtime0) <<
"Found " << gnansOnDiagonal <<
" entries with NAN or INF on diagonal of A" << std::endl;
174 GetOStream(
Runtime0) <<
"~~~~~~~~ DIAGONAL DOMINANCE ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (Level " << fineLevel.GetLevelID() <<
")" << std::endl;
177 GlobalOrdinal lnumWeakDiagDomRows = 0;
178 GlobalOrdinal gnumWeakDiagDomRows = 0;
179 GlobalOrdinal lnumStrictDiagDomRows = 0;
180 GlobalOrdinal gnumStrictDiagDomRows = 0;
181 double worstRatio = 99999999.9;
182 for (
size_t row = 0; row < A->getRowMap()->getNodeNumElements(); row++) {
183 GlobalOrdinal grow = A->getRowMap()->getGlobalElement(row);
185 size_t nnz = A->getNumEntriesInLocalRow(row);
190 A->getLocalRowView(row, indices, vals);
196 double normdiag = 0.0;
197 for (
size_t j = 0; j < Teuchos::as<size_t>(indices.
size()); j++) {
198 GO gcol = A->getColMap()->getGlobalElement(indices[j]);
203 if (normdiag >= norm1) lnumWeakDiagDomRows++;
204 else if (normdiag > norm1) lnumStrictDiagDomRows++;
207 if (normdiag / norm1 < worstRatio) worstRatio = normdiag / norm1;
211 MueLu_sumAll(comm, lnumWeakDiagDomRows, gnumWeakDiagDomRows);
212 MueLu_sumAll(comm, lnumStrictDiagDomRows, gnumStrictDiagDomRows);
214 GetOStream(
Runtime0) <<
"A has " << gnumWeakDiagDomRows <<
"/" << A->getRangeMap()->getGlobalNumElements() <<
" weakly diagonal dominant rows. (" << Teuchos::as<Scalar>(gnumWeakDiagDomRows/A->getRangeMap()->getGlobalNumElements()*100) <<
"%)" << std::endl;
215 GetOStream(
Runtime0) <<
"A has " << gnumStrictDiagDomRows <<
"/" << A->getRangeMap()->getGlobalNumElements() <<
" strictly diagonal dominant rows. (" << Teuchos::as<Scalar>(gnumStrictDiagDomRows/A->getRangeMap()->getGlobalNumElements()*100) <<
"%)" << std::endl;
219 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;
227 GetOStream(
Runtime0) <<
"~~~~~~~~ Av with one vector ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (Level " << fineLevel.GetLevelID() <<
")" << std::endl;
229 ones->putScalar(one);
233 checkVectorEntries(res1,std::string(
"after applying the one vector to A"));
237 GetOStream(
Runtime0) <<
"~~~~~~~~ Av with random vector ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (Level " << fineLevel.GetLevelID() <<
")" << std::endl;
239 randvec->randomize();
243 checkVectorEntries(resrand,std::string(
"after applying random vector to A"));
248 GetOStream(
Runtime0) <<
"~~~~~~~~ Damped Jacobi sweep (one vector) ~~~~~~~~~~~~~~~~~~~~~~~ (Level " << fineLevel.GetLevelID() <<
")" << std::endl;
250 ones->putScalar(one);
254 checkVectorEntries(res1,std::string(
"after applying one vector to A"));
257 checkVectorEntries(invDiag,std::string(
"in invDiag"));
260 res2->elementWiseMultiply (0.8, *invDiag, *res1, 0.0);
261 checkVectorEntries(res2,std::string(
"after scaling Av with invDiag (with v the one vector)"));
262 res2->update(1.0, *ones, -1.0);
264 checkVectorEntries(res2,std::string(
"after applying one damped Jacobi sweep (with one vector)"));
269 GetOStream(
Runtime0) <<
"~~~~~~~~ Damped Jacobi sweep (random vector) ~~~~~~~~~~~~~~~~~~~~ (Level " << fineLevel.GetLevelID() <<
")" << std::endl;
275 checkVectorEntries(res1,std::string(
"after applying a random vector to A"));
278 checkVectorEntries(invDiag,std::string(
"in invDiag"));
281 res2->elementWiseMultiply (0.8, *invDiag, *res1, 0.0);
282 checkVectorEntries(res2,std::string(
"after scaling Av with invDiag (with v a random vector)"));
283 res2->update(1.0, *ones, -1.0);
285 checkVectorEntries(res2,std::string(
"after applying one damped Jacobi sweep (with v a random vector)"));
288 GetOStream(
Runtime0) <<
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (Level " << fineLevel.GetLevelID() <<
")" << std::endl;
291 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
301 for(
size_t i = 0; i<vec->getMap()->getNodeNumElements(); ++i) {
302 if(vecData[i] == zero) {
313 if(gzeros > 0) GetOStream(
Runtime0) <<
"Found " << gzeros <<
" zeros " << info << std::endl;
314 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.
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.
static RCP< Xpetra::Vector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > GetMatrixDiagonalInverse(const Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > &A, Magnitude tol=Teuchos::ScalarTraits< Scalar >::eps()*100)
void checkVectorEntries(const Teuchos::RCP< Vector > &vec, std::string info) const
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Class that holds all level-specific information.
RCP< const ParameterList > GetValidParameterList() const
Return a const parameter list of valid parameters that setParameterList() will accept.
TEUCHOS_DEPRECATED void reduceAll(const Comm< Ordinal > &comm, const EReductionType reductType, const Packet &send, Packet *globalReduct)
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.