138 typedef Teuchos::ScalarTraits<SC> STS;
147 LO nPDEs = A->GetFixedBlockSize();
149 RCP< MultiVector > testVecs;
150 RCP< MultiVector > nearNull;
153 testVecs = Xpetra::IO<SC,LO,GO,Node>::ReadMultiVector(
"TpetraTVecs.mm", A->getRowMap());
155 size_t numRandom= as<size_t>(pL.get<
int>(
"aggregation: number of random vectors"));
156 testVecs = MultiVectorFactory::Build(A->getRowMap(), numRandom,
true);
159 testVecs->randomize();
160 for (
size_t kk = 0; kk < testVecs->getNumVectors(); kk++ ) {
161 Teuchos::ArrayRCP< Scalar > curVec = testVecs->getDataNonConst(kk);
162 for (
size_t ii = kk; ii < as<size_t>(A->getRowMap()->getLocalNumElements()); ii++ ) curVec[ii] = Teuchos::ScalarTraits<SC>::magnitude(curVec[ii]);
164 nearNull = MultiVectorFactory::Build(A->getRowMap(), nPDEs,
true);
167 for (
size_t kk = 0; kk < nearNull->getNumVectors(); kk++ ) {
168 Teuchos::ArrayRCP< Scalar > curVec = nearNull->getDataNonConst(kk);
169 for (
size_t ii = kk; ii < as<size_t>(A->getRowMap()->getLocalNumElements()); ii += nearNull->getNumVectors() ) curVec[ii] = Teuchos::ScalarTraits<Scalar>::one();
172 RCP< MultiVector > zeroVec_TVecs;
173 RCP< MultiVector > zeroVec_Null;
175 zeroVec_TVecs = MultiVectorFactory::Build(A->getRowMap(), testVecs->getNumVectors(),
true);
176 zeroVec_Null = MultiVectorFactory::Build(A->getRowMap(), nPDEs,
true);
177 zeroVec_TVecs->putScalar(Teuchos::ScalarTraits<Scalar>::zero());
178 zeroVec_Null->putScalar( Teuchos::ScalarTraits<Scalar>::zero());
180 size_t nInvokeSmoother=as<size_t>(pL.get<
int>(
"aggregation: number of times to pre or post smooth"));
182 RCP<SmootherBase> preSmoo = currentLevel.
Get< RCP<SmootherBase> >(
"PreSmoother");
183 for (
size_t ii = 0; ii < nInvokeSmoother; ii++) preSmoo->Apply(*testVecs,*zeroVec_TVecs,
false);
184 for (
size_t ii = 0; ii < nInvokeSmoother; ii++) preSmoo->Apply(*nearNull,*zeroVec_Null,
false);
186 else if (currentLevel.
IsAvailable(
"PostSmoother")) {
187 RCP<SmootherBase> postSmoo = currentLevel.
Get< RCP<SmootherBase> >(
"PostSmoother");
188 for (
size_t ii = 0; ii < nInvokeSmoother; ii++) postSmoo->Apply(*testVecs,*zeroVec_TVecs,
false);
189 for (
size_t ii = 0; ii < nInvokeSmoother; ii++) postSmoo->Apply(*nearNull, *zeroVec_Null,
false);
194 Teuchos::ArrayRCP<Scalar> penaltyPolyCoef(5);
195 Teuchos::ArrayView<const double> inputPolyCoef;
203 if(pL.isParameter(
"aggregation: penalty parameters") && pL.get<Teuchos::Array<double> >(
"aggregation: penalty parameters").size() > 0) {
204 if (pL.get<Teuchos::Array<double> >(
"aggregation: penalty parameters").size() > penaltyPolyCoef.size())
205 TEUCHOS_TEST_FOR_EXCEPTION(
true,
Exceptions::RuntimeError,
"Number of penalty parameters must be " << penaltyPolyCoef.size() <<
" or less");
206 inputPolyCoef = pL.get<Teuchos::Array<double> >(
"aggregation: penalty parameters")();
208 for (
size_t i = 0; i < as<size_t>(inputPolyCoef.size()) ; i++) penaltyPolyCoef[i] = as<Scalar>(inputPolyCoef[i]);
209 for (
size_t i = as<size_t>(inputPolyCoef.size()); i < as<size_t>(penaltyPolyCoef.size()); i++) penaltyPolyCoef[i] = Teuchos::ScalarTraits<Scalar>::zero();
213 RCP<GraphBase> filteredGraph;
220 FILE* fp = fopen(
"codeOutput",
"w");
221 fprintf(fp,
"%d %d %d\n",(
int) filteredGraph->GetNodeNumVertices(),(
int) filteredGraph->GetNodeNumVertices(),
222 (
int) filteredGraph->GetNodeNumEdges());
223 for (
size_t i = 0; i < filteredGraph->GetNodeNumVertices(); i++) {
224 ArrayView<const LO> inds = filteredGraph->getNeighborVertices(as<LO>(i));
225 for (
size_t j = 0; j < as<size_t>(inds.size()); j++) {
226 fprintf(fp,
"%d %d 1.00e+00\n",(
int) i+1,(
int) inds[j]+1);
233 Set<bool>(currentLevel,
"Filtering", (threshold != STS::zero()));
234 Set(currentLevel,
"Graph", filteredGraph);
235 Set(currentLevel,
"DofsPerNode", 1);
278 GO numMyNnz = Teuchos::as<GO>(Amat.getLocalNumEntries());
279 size_t nLoc = Amat.getRowMap()->getLocalNumElements();
281 size_t nBlks = nLoc/nPDEs;
282 if (nBlks*nPDEs != nLoc )
285 Teuchos::ArrayRCP<LO> newRowPtr(nBlks+1);
286 Teuchos::ArrayRCP<LO> newCols(numMyNnz);
288 Teuchos::ArrayRCP<LO> bcols(nBlks);
289 Teuchos::ArrayRCP<bool> keepOrNot(nBlks);
293 LO maxNzPerRow = 200;
294 Teuchos::ArrayRCP<Scalar> penalties(maxNzPerRow);
297 Teuchos::ArrayRCP<bool> keepStatus(nBlks,
true);
298 Teuchos::ArrayRCP<LO> bColList(nBlks);
308 Teuchos::ArrayRCP<bool> alreadyOnBColList(nBlks,
false);
313 Teuchos::ArrayRCP<bool> boundaryNodes(nBlks,
false);
316 for (LO i = 0; i < maxNzPerRow; i++)
323 LO nzTotal = 0, numBCols = 0, row = -1, Nbcols, bcol;
327 for (LO i = 0; i < as<LO>(nBlks); i++) {
328 newRowPtr[i+1] = newRowPtr[i];
329 for (LO j = 0; j < nPDEs; j++) {
332 Teuchos::ArrayView<const LocalOrdinal> indices;
333 Teuchos::ArrayView<const Scalar> vals;
335 Amat.getLocalRowView(row, indices, vals);
337 if (indices.size() > maxNzPerRow) {
338 LO oldSize = maxNzPerRow;
339 maxNzPerRow = indices.size() + 100;
340 penalties.resize(as<size_t>(maxNzPerRow),0.0);
341 for (LO k = oldSize; k < maxNzPerRow; k++)
348 badGuysDropfunc(row, indices, vals, testVecs, nPDEs, penalties, nearNull, bcols,keepOrNot,Nbcols,nLoc);
349 for (LO k=0; k < Nbcols; k++) {
354 if (alreadyOnBColList[bcol] ==
false) {
355 bColList[numBCols++] = bcol;
356 alreadyOnBColList[bcol] =
true;
360 if (keepOrNot[k] ==
false) keepStatus[bcol] =
false;
368 if ( numBCols < 2) boundaryNodes[i] =
true;
369 for (LO j=0; j < numBCols; j++) {
371 if (keepStatus[bcol] ==
true) {
372 newCols[nzTotal] = bColList[j];
374 nzTotal = nzTotal + 1;
376 keepStatus[bcol] =
true;
377 alreadyOnBColList[bcol] =
false;
385 Teuchos::ArrayRCP<LO> finalCols(nzTotal);
386 for (LO i = 0; i < nzTotal; i++) finalCols[i] = newCols[i];
391 RCP<const Map> rowMap = Amat.getRowMap();
393 LO nAmalgNodesOnProc = rowMap->getLocalNumElements()/nPDEs;
394 Teuchos::Array<GO> nodalGIDs(nAmalgNodesOnProc);
395 typename Teuchos::ScalarTraits<Scalar>::coordinateType temp;
396 for (
size_t i = 0; i < as<size_t>(nAmalgNodesOnProc); i++ ) {
397 GO gid = rowMap->getGlobalElement(i*nPDEs);
398 temp = ((
typename Teuchos::ScalarTraits<Scalar>::coordinateType) (gid))/((
typename Teuchos::ScalarTraits<Scalar>::coordinateType) (nPDEs));
399 nodalGIDs[i] = as<GO>(floor(temp));
401 GO nAmalgNodesGlobal = rowMap->getGlobalNumElements();
402 GO nBlkGlobal = nAmalgNodesGlobal/nPDEs;
403 if (nBlkGlobal*nPDEs != nAmalgNodesGlobal)
406 Teuchos::RCP<Map> AmalgRowMap = MapFactory::Build(rowMap->lib(), nBlkGlobal,
407 nodalGIDs(),0,rowMap->getComm());
409 filteredGraph = rcp(
new LWGraph(newRowPtr, finalCols, AmalgRowMap, AmalgRowMap,
"thresholded graph of A"));
410 filteredGraph->SetBoundaryNodeMap(boundaryNodes);
415 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 {
416 using TST=Teuchos::ScalarTraits<Scalar>;
418 LO nLeng = cols.size();
419 typename TST::coordinateType temp;
420 temp = ((
typename TST::coordinateType) (row))/((
typename TST::coordinateType) (nPDEs));
421 LO blkRow = as<LO>(floor(temp));
422 Teuchos::ArrayRCP<Scalar> badGuy( nLeng, 0.0);
423 Teuchos::ArrayRCP<Scalar> subNull(nLeng, 0.0);
437 for (LO i = 0; i < nLeng; i++) keepOrNot[i] =
false;
441 LO rowDof = row - blkRow*nPDEs;
442 Teuchos::ArrayRCP< const Scalar > oneNull = nearNull.getData( as<size_t>(rowDof));
444 for (LO i = 0; i < nLeng; i++) {
445 if ((cols[i] < nLoc ) && (TST::magnitude(vals[i]) != 0.0)) {
446 temp = ((
typename TST::coordinateType) (cols[i]))/((
typename TST::coordinateType) (nPDEs));
447 LO colDof = cols[i] - (as<LO>(floor( temp )))*nPDEs;
448 if (colDof == rowDof) {
449 Bcols[ Nbcols] = (cols[i] - colDof)/nPDEs;
450 subNull[Nbcols] = oneNull[cols[i]];
452 if (cols[i] != row) {
453 Scalar worstRatio = -TST::one();
454 Scalar targetRatio = subNull[Nbcols]/oneNull[row];
456 for (
size_t kk = 0; kk < testVecs.getNumVectors(); kk++ ) {
457 Teuchos::ArrayRCP< const Scalar > curVec = testVecs.getData(kk);
458 actualRatio = curVec[cols[i]]/curVec[row];
459 if (TST::magnitude(actualRatio - targetRatio) > TST::magnitude(worstRatio)) {
460 badGuy[Nbcols] = actualRatio;
461 worstRatio = Teuchos::ScalarTraits<SC>::magnitude(actualRatio - targetRatio);
466 badGuy[ Nbcols] = 1.;
467 keepOrNot[Nbcols] =
true;
478 Bcols[ Nbcols] = (row - rowDof)/nPDEs;
479 subNull[ Nbcols] = 1.;
480 badGuy[ Nbcols] = 1.;
481 keepOrNot[Nbcols] =
true;
486 Scalar currentRP = oneNull[row]*oneNull[row];
487 Scalar currentRTimesBadGuy= oneNull[row]*badGuy[diagInd];
488 Scalar currentScore = penalties[0];
499 LO nKeep = 1, flag = 1, minId;
500 Scalar minFit, minFitRP = 0., minFitRTimesBadGuy = 0.;
501 Scalar newRP, newRTimesBadGuy;
510 for (LO i=0; i < Nbcols; i++) {
511 if (keepOrNot[i] ==
false) {
513 newRP = currentRP + subNull[i]*subNull[i];
514 newRTimesBadGuy= currentRTimesBadGuy + subNull[i]*badGuy[i];
515 Scalar ratio = newRTimesBadGuy/newRP;
518 for (LO k=0; k < Nbcols; k++) {
519 if (keepOrNot[k] ==
true) {
520 Scalar diff = badGuy[k] - ratio*subNull[k];
521 newFit = newFit + diff*diff;
524 if (Teuchos::ScalarTraits<SC>::magnitude(newFit) < Teuchos::ScalarTraits<SC>::magnitude(minFit)) {
528 minFitRTimesBadGuy= newRTimesBadGuy;
530 keepOrNot[i] =
false;
533 if (minId == -1) flag = 0;
535 minFit = sqrt(minFit);
536 Scalar newScore = penalties[nKeep] + minFit;
537 if (Teuchos::ScalarTraits<SC>::magnitude(newScore) < Teuchos::ScalarTraits<SC>::magnitude(currentScore)) {
539 keepOrNot[minId]=
true;
540 currentScore = newScore;
541 currentRP = minFitRP;
542 currentRTimesBadGuy= minFitRTimesBadGuy;