void dft_PolyA11_Tpetra_Operator<Scalar,MatrixType>:: Check (bool verbose) const { RCP<VEC > x = rcp(new VEC(getDomainMap())); RCP<VEC > b = rcp(new VEC(getRangeMap())); x->randomize(); // Fill x with random numbers apply(*x, *b); // Forward operation applyInverse(*b, *b); // Reverse operation b->update(-STS::one(), *x, STS::one()); // Should be zero Scalar absResid = b->norm2(); Scalar normX = x->norm2(); Scalar resid = absResid / normX; if (verbose) { std::cout << "A11 self-check residual = " << resid << std::endl; } TEUCHOS_TEST_FOR_EXCEPTION(resid > 1.0E-12, std::runtime_error, "Bad residual.\n"); } //end Check
void dft_PolyA22_Tpetra_Operator<Scalar,MatrixType>:: Check (bool verbose) const { RCP<VEC > x = rcp(new VEC(getDomainMap())); RCP<VEC > b = rcp(new VEC(getRangeMap())); x->randomize(); // Fill x with random numbers apply(*x, *b); // Forward operation if (hasDensityOnCms_) { if (F_location_ == 1) //F in NE { // Inverse is not exact, so we must modify b2 first: RCP<MV> x1 = x->offsetViewNonConst(cmsMap_, 0); // Start x1 to view first numCmsElements elements of x RCP<MV> b2 = b->offsetViewNonConst(densityMap_, cmsMap_->getNodeNumElements()); // Start b2 to view last numDensity elements of b RCP<MV > DCx1 = rcp(new MV(*b2)); densityOnCmsMatrixOp_->apply(*x1, *DCx1); b2->update(-STS::one(), *DCx1, STS::one()); // b2 = b2 - DC*x1 } else { // Inverse is not exact, so we must modify b1 first: RCP<MV> x2 = x->offsetViewNonConst(cmsMap_, densityMap_->getNodeNumElements()); //Start x2 to view last numCms elements of x RCP<MV> b1 = b->offsetViewNonConst(densityMap_, 0); // Start b1 to view first numDensity elements of b RCP<MV > DCx2 = rcp(new MV(*b1)); densityOnCmsMatrixOp_->apply(*x2, *DCx2); b1->update(-STS::one(), *DCx2, STS::one()); // b1 = b1 - DC*x2 } } // Reverse operation applyInverse(*b, *b); b->update(-STS::one(), *x, STS::one()); // Should be zero Scalar resid = b->norm2(); if (verbose) { std::cout << "A22 self-check residual = " << resid << std::endl; } TEUCHOS_TEST_FOR_EXCEPTION(resid > 1.0E-12, std::runtime_error, "Bad residual.\n"); } //end Check
int invIteration(Epetra_CrsMatrix& A, double &lambda, bool verbose) { Ifpack_CrsRiluk * M; applyInverseSetup(A, M); Epetra_Vector q(A.RowMap()); Epetra_Vector z(A.RowMap()); Epetra_Vector resid(A.RowMap()); Epetra_Flops * counter = A.GetFlopCounter(); if (counter!=0) { q.SetFlopCounter(A); z.SetFlopCounter(A); resid.SetFlopCounter(A); } // Fill z with random Numbers z.Random(); // variable needed for iteration double normz, residual; int niters = 100; double tolerance = 1.0E-6; int ierr = 1; for (int iter = 0; iter < niters; iter++) { if (verbose) cout << endl << " ***** Performing step " << iter << " of inverse iteration ***** " << endl; z.Norm2(&normz); // Compute 2-norm of z q.Scale(1.0/normz, z); applyInverse(A, z, q, M, verbose); // Compute z such that Az = q q.Dot(z, &lambda); // Approximate maximum eigenvalue if (iter%10==0 || iter+1==niters) { resid.Update(1.0, z, -lambda, q, 0.0); // Compute A(inv)*q - lambda*q resid.Norm2(&residual); cout << endl << "***** Inverse Iteration Step " << iter+1 << endl << " Lambda = " << 1.0/lambda << endl << " Residual of A(inv)*q - lambda*q = " << residual << endl; } if (residual < tolerance) { ierr = 0; break; } } // lambda is the largest eigenvalue of A(inv). 1/lambda is smallest eigenvalue of A. lambda = 1.0/lambda; // Compute A*q - lambda*q explicitly A.Multiply(false, q, z); resid.Update(1.0, z, -lambda, q, 0.0); // Compute A*q - lambda*q resid.Norm2(&residual); cout << " Explicitly computed residual of A*q - lambda*q = " << residual << endl; applyInverseDestroy(M); return(ierr); }