47 #ifndef MUELU_SMOOVECCOALESCEDROPFACTORY_DEF_HPP
48 #define MUELU_SMOOVECCOALESCEDROPFACTORY_DEF_HPP
50 #include <Xpetra_CrsGraphFactory.hpp>
51 #include <Xpetra_CrsGraph.hpp>
52 #include <Xpetra_ImportFactory.hpp>
53 #include <Xpetra_MapFactory.hpp>
54 #include <Xpetra_Map.hpp>
55 #include <Xpetra_Matrix.hpp>
56 #include <Xpetra_MultiVectorFactory.hpp>
57 #include <Xpetra_MultiVector.hpp>
58 #include <Xpetra_StridedMap.hpp>
59 #include <Xpetra_VectorFactory.hpp>
60 #include <Xpetra_Vector.hpp>
64 #include "MueLu_AmalgamationFactory.hpp"
65 #include "MueLu_AmalgamationInfo.hpp"
68 #include "MueLu_Graph.hpp"
70 #include "MueLu_LWGraph.hpp"
73 #include "MueLu_PreDropFunctionBaseClass.hpp"
74 #include "MueLu_PreDropFunctionConstVal.hpp"
75 #include "MueLu_Utilities.hpp"
76 #include "MueLu_TopSmootherFactory.hpp"
78 #include "MueLu_SmootherFactory.hpp"
81 #include <Xpetra_IO.hpp>
96 #define poly0thOrderCoef 0
97 #define poly1stOrderCoef 1
98 #define poly2ndOrderCoef 2
99 #define poly3rdOrderCoef 3
100 #define poly4thOrderCoef 4
104 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
108 #define SET_VALID_ENTRY(name) validParamList->setEntry(name, MasterList::getEntry(name))
113 rcp(
new validatorType(Teuchos::tuple<std::string>(
"unsupported vector smoothing"),
"aggregation: drop scheme")));
118 #undef SET_VALID_ENTRY
124 return validParamList;
127 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
130 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
132 Input(currentLevel,
"A");
134 Input(currentLevel,
"PreSmoother");
136 else if (currentLevel.
IsAvailable(
"PostSmoother")) {
137 Input(currentLevel,
"PostSmoother");
141 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
148 if (predrop_ != Teuchos::null)
149 GetOStream(
Parameters0) << predrop_->description();
151 RCP<Matrix> A = Get< RCP<Matrix> >(currentLevel,
"A");
155 LO nPDEs = A->GetFixedBlockSize();
161 testVecs = Xpetra::IO<SC,LO,GO,Node>::ReadMultiVector(
"TpetraTVecs.mm", A->getRowMap());
163 size_t numRandom= as<size_t>(pL.get<
int>(
"aggregation: number of random vectors"));
164 testVecs = MultiVectorFactory::Build(A->getRowMap(), numRandom,
true);
167 testVecs->randomize();
168 for (
size_t kk = 0; kk < testVecs->getNumVectors(); kk++ ) {
172 nearNull = MultiVectorFactory::Build(A->getRowMap(), nPDEs,
true);
175 for (
size_t kk = 0; kk < nearNull->getNumVectors(); kk++ ) {
183 zeroVec_TVecs = MultiVectorFactory::Build(A->getRowMap(), testVecs->getNumVectors(),
true);
184 zeroVec_Null = MultiVectorFactory::Build(A->getRowMap(), nPDEs,
true);
188 size_t nInvokeSmoother=as<size_t>(pL.get<
int>(
"aggregation: number of times to pre or post smooth"));
189 if (currentLevel.IsAvailable(
"PreSmoother")) {
191 for (
size_t ii = 0; ii < nInvokeSmoother; ii++) preSmoo->
Apply(*testVecs,*zeroVec_TVecs,
false);
192 for (
size_t ii = 0; ii < nInvokeSmoother; ii++) preSmoo->
Apply(*nearNull,*zeroVec_Null,
false);
194 else if (currentLevel.IsAvailable(
"PostSmoother")) {
196 for (
size_t ii = 0; ii < nInvokeSmoother; ii++) postSmoo->
Apply(*testVecs,*zeroVec_TVecs,
false);
197 for (
size_t ii = 0; ii < nInvokeSmoother; ii++) postSmoo->
Apply(*nearNull, *zeroVec_Null,
false);
211 if(pL.isParameter(
"aggregation: penalty parameters") && pL.get<
Teuchos::Array<double> >(
"aggregation: penalty parameters").size() > 0) {
216 for (
size_t i = 0; i < as<size_t>(inputPolyCoef.
size()) ; i++) penaltyPolyCoef[i] = as<Scalar>(inputPolyCoef[i]);
222 badGuysCoalesceDrop(*A, penaltyPolyCoef, nPDEs, *testVecs, *nearNull, filteredGraph);
228 FILE* fp = fopen(
"codeOutput",
"w");
233 for (
size_t j = 0; j < as<size_t>(inds.
size()); j++) {
234 fprintf(fp,
"%d %d 1.00e+00\n",(
int) i+1,(
int) inds[j]+1);
241 Set<bool>(currentLevel,
"Filtering", (threshold != STS::zero()));
242 Set(currentLevel,
"Graph", filteredGraph);
243 Set(currentLevel,
"DofsPerNode", 1);
247 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
286 GO numMyNnz = Teuchos::as<GO>(Amat.getNodeNumEntries());
287 size_t nLoc = Amat.getRowMap()->getNodeNumElements();
289 size_t nBlks = nLoc/nPDEs;
290 if (nBlks*nPDEs != nLoc )
301 LO maxNzPerRow = 200;
324 for (LO i = 0; i < maxNzPerRow; i++)
331 LO nzTotal = 0, numBCols = 0, row = -1, Nbcols, bcol;
335 for (LO i = 0; i < as<LO>(nBlks); i++) {
336 newRowPtr[i+1] = newRowPtr[i];
337 for (LO j = 0; j < nPDEs; j++) {
343 Amat.getLocalRowView(row, indices, vals);
345 if (indices.
size() > maxNzPerRow) {
346 LO oldSize = maxNzPerRow;
347 maxNzPerRow = indices.
size() + 100;
348 penalties.
resize(as<size_t>(maxNzPerRow),0.0);
349 for (LO k = oldSize; k < maxNzPerRow; k++)
356 badGuysDropfunc(row, indices, vals, testVecs, nPDEs, penalties, nearNull, bcols,keepOrNot,Nbcols,nLoc);
357 for (LO k=0; k < Nbcols; k++) {
362 if (alreadyOnBColList[bcol] ==
false) {
363 bColList[numBCols++] = bcol;
364 alreadyOnBColList[bcol] =
true;
368 if (keepOrNot[k] ==
false) keepStatus[bcol] =
false;
376 if ( numBCols < 2) boundaryNodes[i] =
true;
377 for (LO j=0; j < numBCols; j++) {
379 if (keepStatus[bcol] ==
true) {
380 newCols[nzTotal] = bColList[j];
382 nzTotal = nzTotal + 1;
384 keepStatus[bcol] =
true;
385 alreadyOnBColList[bcol] =
false;
394 for (LO i = 0; i < nzTotal; i++) finalCols[i] = newCols[i];
401 LO nAmalgNodesOnProc = rowMap->getNodeNumElements()/nPDEs;
404 for (
size_t i = 0; i < as<size_t>(nAmalgNodesOnProc); i++ ) {
405 GO gid = rowMap->getGlobalElement(i*nPDEs);
407 nodalGIDs[i] = as<GO>(floor(temp));
409 GO nAmalgNodesGlobal = rowMap->getGlobalNumElements();
410 GO nBlkGlobal = nAmalgNodesGlobal/nPDEs;
411 if (nBlkGlobal*nPDEs != nAmalgNodesGlobal)
415 nodalGIDs(),0,rowMap->getComm());
417 filteredGraph =
rcp(
new LWGraph(newRowPtr, finalCols, AmalgRowMap, AmalgRowMap,
"thresholded graph of A"));
418 filteredGraph->SetBoundaryNodeMap(boundaryNodes);
422 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
423 void SmooVecCoalesceDropFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::badGuysDropfunc(LO row,
const Teuchos::ArrayView<const LocalOrdinal>& cols,
const Teuchos::ArrayView<const Scalar>& vals,
const MultiVector& testVecs, LO nPDEs,
Teuchos::ArrayRCP<Scalar> & penalties,
const MultiVector& nearNull,
Teuchos::ArrayRCP<LO>& Bcols,
Teuchos::ArrayRCP<bool>& keepOrNot, LO &Nbcols, LO nLoc)
const {
425 LO nLeng = cols.
size();
428 LO blkRow = as<LO>(floor(temp));
444 for (LO i = 0; i < nLeng; i++) keepOrNot[i] =
false;
448 LO rowDof = row - blkRow*nPDEs;
451 for (LO i = 0; i < nLeng; i++) {
452 if ((cols[i] < nLoc ) && (vals[i] != 0.0)) {
454 LO colDof = cols[i] - (as<LO>(floor( temp )))*nPDEs;
455 if (colDof == rowDof) {
456 Bcols[ Nbcols] = (cols[i] - colDof)/nPDEs;
457 subNull[Nbcols] = oneNull[cols[i]];
459 if (cols[i] != row) {
461 Scalar targetRatio = subNull[Nbcols]/oneNull[row];
463 for (
size_t kk = 0; kk < testVecs.getNumVectors(); kk++ ) {
465 actualRatio = curVec[cols[i]]/curVec[row];
467 badGuy[Nbcols] = actualRatio;
473 badGuy[ Nbcols] = 1.;
474 keepOrNot[Nbcols] =
true;
485 Bcols[ Nbcols] = (row - rowDof)/nPDEs;
486 subNull[ Nbcols] = 1.;
487 badGuy[ Nbcols] = 1.;
488 keepOrNot[Nbcols] =
true;
493 Scalar currentRP = oneNull[row]*oneNull[row];
494 Scalar currentRTimesBadGuy= oneNull[row]*badGuy[diagInd];
495 Scalar currentScore = penalties[0];
506 LO nKeep = 1, flag = 1, minId;
507 Scalar minFit, minFitRP = 0., minFitRTimesBadGuy = 0.;
508 Scalar newRP, newRTimesBadGuy;
517 for (LO i=0; i < Nbcols; i++) {
518 if (keepOrNot[i] ==
false) {
520 newRP = currentRP + subNull[i]*subNull[i];
521 newRTimesBadGuy= currentRTimesBadGuy + subNull[i]*badGuy[i];
522 Scalar ratio = newRTimesBadGuy/newRP;
525 for (LO k=0; k < Nbcols; k++) {
526 if (keepOrNot[k] ==
true) {
527 Scalar diff = badGuy[k] - ratio*subNull[k];
528 newFit = newFit + diff*diff;
535 minFitRTimesBadGuy= newRTimesBadGuy;
537 keepOrNot[i] =
false;
540 if (minId == -1) flag = 0;
542 minFit = sqrt(minFit);
543 Scalar newScore = penalties[nKeep] + minFit;
546 keepOrNot[minId]=
true;
547 currentScore = newScore;
548 currentRP = minFitRP;
549 currentRTimesBadGuy= minFitRTimesBadGuy;
558 #endif // MUELU_SMOOVECCOALESCEDROPFACTORY_DEF_HPP
void setValidator(RCP< const ParameterEntryValidator > const &validator)
virtual size_t GetNodeNumVertices() const =0
Return number of vertices owned by the calling node.
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
virtual size_t GetNodeNumEdges() const =0
Return number of edges owned by the calling node.
Timer to be used in factories. Similar to Monitor but with additional timers.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
RCP< const ParameterList > GetValidParameterList() const
Return a const parameter list of valid parameters that setParameterList() will accept.
void badGuysCoalesceDrop(const Matrix &Amat, Teuchos::ArrayRCP< Scalar > &dropParams, LO nPDEs, const MultiVector &smoothedTVecs, const MultiVector &smoothedNull, RCP< GraphBase > &filteredGraph) const
Methods to support compatible-relaxation style dropping.
void resize(const size_type n, const T &val=T())
void Build(Level ¤tLevel) const
Build an object with this factory.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
MueLu::DefaultScalar Scalar
Class that holds all level-specific information.
#define SET_VALID_ENTRY(name)
SmooVecCoalesceDropFactory()
Constructor.
void DeclareInput(Level ¤tLevel) const
Input.
static magnitudeType magnitude(T a)
void badGuysDropfunc(LO row, const Teuchos::ArrayView< const LocalOrdinal > &indices, const Teuchos::ArrayView< const Scalar > &vals, const MultiVector &smoothedTVecs, LO nPDEs, Teuchos::ArrayRCP< Scalar > &penalties, const MultiVector &smoothedNull, Teuchos::ArrayRCP< LO > &Bcols, Teuchos::ArrayRCP< bool > &keepOrNot, LO &Nbcols, LO nLoc) const
Lightweight MueLu representation of a compressed row storage graph.
Exception throws to report errors in the internal logical of the program.
ParameterEntry & getEntry(const std::string &name)
virtual void Apply(MultiVector &x, const MultiVector &rhs, bool InitialGuessIsZero=false) const =0
Apply smoother.
virtual Teuchos::ArrayView< const LocalOrdinal > getNeighborVertices(LocalOrdinal v) const =0
Return the list of vertices adjacent to the vertex 'v'.
bool IsAvailable(const std::string &ename, const FactoryBase *factory=NoFactory::get()) const
Test whether a need's value has been saved.