Epetra_TSFOperator::Epetra_TSFOperator(const LinearOperator<double>& A, const LinearSolver<double>& solver) : A_(A), solver_(solver), useTranspose_(false), comm_(), domain_(), range_(), isNativeEpetra_(false), isCompoundEpetra_(false), label_(A.description()) { const EpetraMatrix* em = dynamic_cast<const EpetraMatrix*>(A.ptr().get()); const EpetraVectorSpace* ed = dynamic_cast<const EpetraVectorSpace*>(A.domain().ptr().get()); const EpetraVectorSpace* er = dynamic_cast<const EpetraVectorSpace*>(A.range().ptr().get()); if (em) { isNativeEpetra_ = true; const Epetra_CrsMatrix* crs = em->crsMatrix(); domain_ = rcp(new Epetra_Map(crs->OperatorDomainMap())); range_ = rcp(new Epetra_Map(crs->OperatorRangeMap())); useTranspose_ = crs->UseTranspose(); comm_ = rcp(crs->Comm().Clone()); } else if (er != 0 && ed != 0) { domain_ = ed->epetraMap(); range_ = er->epetraMap(); comm_ = rcp(domain_->Comm().Clone()); isCompoundEpetra_ = true; } else { TEST_FOR_EXCEPT(true); } }
virtual Preconditioner <Scalar> createPreconditioner(const LinearOperator<Scalar>& A) const { /* In order for ICC factorization to work, the operator A must * implement the ICCFactorizableOp interface. We cast A's pointer * to a ICCFactorizableOp ptr. If the cast fails, throw a spoke. */ const ICCFactorizableOp<Scalar>* fop = dynamic_cast<const ICCFactorizableOp<Scalar>*>(A.ptr().get()); TEUCHOS_TEST_FOR_EXCEPTION(fop==0, std::runtime_error, "ICCPreconditionerFactory attempted to " "create an ICC preconditioner for an operator type " "that does not implement the ICCFactorizableOp " "interface. The op is " << A.description()); /* Now we can delegate the construction of the ICC factors to * the factorizable op. */ Preconditioner<Scalar> P; fop->getICCPreconditioner(fillLevels_, overlapFill_, relaxationValue_, relativeThreshold_, absoluteThreshold_, P); /* Return the preconditioner */ return P; }
LinearOperator<double> createW() const { static LinearOperator<double> J = prob_.allocateJacobian(); TEST_FOR_EXCEPTION(J.ptr().get()==0, RuntimeError, "null Jacobian"); return J; }
void NLOp:: computeJacobianAndFunction(LinearOperator<double>& J, Vector<double>& resid) const { /* Set the vector underlying the discrete * function to the evaluation point*/ TEST_FOR_EXCEPTION(discreteU0_==0, RuntimeError, "null discrete function pointer in " "NLOp::jacobian()"); TEST_FOR_EXCEPTION(currentEvalPt().ptr().get()==0, RuntimeError, "null evaluation point in " "NLOp::jacobian()"); TEST_FOR_EXCEPTION(J.ptr().get()==0, RuntimeError, "null Jacobian pointer in " "NLOp::jacobian()"); TEST_FOR_EXCEPTION(resid.ptr().get()==0, RuntimeError, "null residual pointer in " "NLOp::jacobian()"); discreteU0_->setVector(currentEvalPt()); Array<Vector<double> > mv(1); mv[0] = resid; assembler_->assemble(J, mv); resid.acceptCopyOf(mv[0]); J_ = J; }
int main(int argc, char *argv[]) { int stat = 0; try { GlobalMPISession session(&argc, &argv); MPIComm::world().synchronize(); Out::os() << "go!" << std::endl; VectorType<double> type = new EpetraVectorType(); Array<int> domainBlockSizes = tuple(2,3,4); Array<int> rangeBlockSizes = tuple(2,2); Array<VectorSpace<double> > domainBlocks(domainBlockSizes.size()); Array<VectorSpace<double> > rangeBlocks(rangeBlockSizes.size()); for (int i=0; i<domainBlocks.size(); i++) { domainBlocks[i] = type.createEvenlyPartitionedSpace(MPIComm::world(), domainBlockSizes[i]); } for (int i=0; i<rangeBlocks.size(); i++) { rangeBlocks[i] = type.createEvenlyPartitionedSpace(MPIComm::world(), rangeBlockSizes[i]); } VectorSpace<double> domain = blockSpace(domainBlocks); VectorSpace<double> range = blockSpace(rangeBlocks); double blockDensity = 0.75; double onProcDensity = 0.5; double offProcDensity = 0.1; RandomBlockMatrixBuilder<double> builder(domain, range, blockDensity, onProcDensity, offProcDensity, type); LinearOperator<double> A = builder.getOp(); Out::os() << "A num block rows = " << A.numBlockRows() << std::endl; Out::os() << "A num block cols = " << A.numBlockCols() << std::endl; Vector<double> x = domain.createMember(); Out::os() << "randomizing trial vector" << std::endl; x.randomize(); Array<Vector<double> > xBlock(domain.numBlocks()); for (int i=0; i<xBlock.size(); i++) { xBlock[i] = x.getBlock(i); } Vector<double> xx = x.copy(); Out::os() << "------------------------------------------------------------" << std::endl; Out::os() << "computing A*x..." << std::endl; Vector<double> y0 = A * x; for (int i=0; i<y0.space().numBlocks(); i++) { Out::os() << "y0[" << i << "] = " << std::endl << y0.getBlock(i) << std::endl; } Vector<double> y1 = range.createMember(); Out::os() << "------------------------------------------------------------" << std::endl; Out::os() << "computing A*x block-by-block..." << std::endl; Array<Vector<double> > yBlock(range.numBlocks()); for (int i=0; i<yBlock.size(); i++) { yBlock[i] = range.getBlock(i).createMember(); yBlock[i].zero(); for (int j=0; j<xBlock.size(); j++) { LinearOperator<double> Aij = A.getBlock(i,j); if (Aij.ptr().get() != 0) { Out::os() << "A(" << i << ", " << j << ") = " << std::endl << Aij << std::endl; } else { Out::os() << "A(" << i << ", " << j << ") = 0 " << std::endl; } Out::os() << "x[" << j << "] = " << std::endl << xBlock[j] << std::endl; if (Aij.ptr().get()==0) continue; yBlock[i] = yBlock[i] + Aij * xBlock[j]; } y1.setBlock(i, yBlock[i]); } for (int i=0; i<y1.space().numBlocks(); i++) { Out::os() << "y1[" << i << "] = " << std::endl << y1.getBlock(i) << std::endl; } double err = (y1 - y0).norm2(); Out::os() << "error = " << err << std::endl; double tol = 1.0e-13; if (err < tol) { Out::os() << "block op test PASSED" << std::endl; } else { stat = -1; Out::os() << "block op test FAILED" << std::endl; } } catch(std::exception& e) { stat = -1; Out::os() << "Caught exception: " << e.what() << std::endl; } return stat; }
SolverState<double> BelosSolver::solve(const LinearOperator<double>& A, const Vector<double>& rhs, Vector<double>& soln) const { typedef Anasazi::SimpleMV MV; typedef LinearOperator<double> OP; typedef Belos::LinearProblem<double, MV, OP> LP; TEUCHOS_TEST_FOR_EXCEPT(!A.ptr().get()); TEUCHOS_TEST_FOR_EXCEPT(!rhs.ptr().get()); if (!soln.ptr().get()) { soln = rhs.copy(); /* KRL 8 Jun 2012: set x0 to zero to workaround bug in Belos */ soln.zero(); } if (rhs.norm2()==0.0) { soln.zero(); SolverStatusCode code = SolveConverged; SolverState<double> state(code, "Detected trivial solution", 0, 0.0); return state; } RCP<OP> APtr = rcp(new LinearOperator<double>(A)); RCP<MV> bPtr = rcp(new MV(1)); (*bPtr)[0] = rhs; RCP<MV> ansPtr = rcp(new MV(1)); (*ansPtr)[0] = soln; RCP<LP> prob = rcp(new LP(APtr, ansPtr, bPtr)); TEUCHOS_TEST_FOR_EXCEPT(!prob->setProblem()); if (pf_.ptr().get()) { Preconditioner<double> P = pf_.createPreconditioner(A); if (P.hasLeft()) { prob->setLeftPrec(rcp(new OP(P.left()))); } if (P.hasRight()) { prob->setRightPrec(rcp(new OP(P.right()))); } } if (!hasSolver_) { ParameterList plist = parameters(); RCP<ParameterList> belosList = rcp(&plist, false); std::string solverType = parameters().get<string>("Method"); if (solverType=="GMRES") { solver_=rcp(new Belos::BlockGmresSolMgr<double, MV, OP>(prob, belosList)); } else if (solverType=="CG") { solver_=rcp(new Belos::BlockCGSolMgr<double, MV, OP>(prob, belosList)); } else if (solverType=="TFQMR") { solver_=rcp(new Belos::TFQMRSolMgr<double, MV, OP>(prob, belosList)); } else if (solverType=="GCRODR") { solver_=rcp(new Belos::GCRODRSolMgr<double, MV, OP>(prob, belosList)); hasSolver_ = true; // only cache recycling solvers } else if (solverType=="RCG") { solver_=rcp(new Belos::RCGSolMgr<double, MV, OP>(prob, belosList)); hasSolver_ = true; // only cache recycling solvers } else { TEUCHOS_TEST_FOR_EXCEPT(!(solverType=="GMRES" || solverType=="CG")); } } else // reset problem { solver_->setProblem( prob ); } Belos::ReturnType rtn = solver_->solve(); int numIters = solver_->getNumIters(); double resid = solver_->achievedTol(); SolverStatusCode code = SolveFailedToConverge; if (rtn==Belos::Converged) code = SolveConverged; SolverState<double> state(code, "Belos solver completed", numIters, resid); return state; }
int main(int argc, char *argv[]) { int stat = 0; try { GlobalMPISession session(&argc, &argv); VectorType<double> vecType = new SerialVectorType(); VectorSpace<double> domain = vecType.createEvenlyPartitionedSpace(MPIComm::world(), 3); VectorSpace<double> range = vecType.createEvenlyPartitionedSpace(MPIComm::world(), 5); RCP<MatrixFactory<double> > mf = vecType.createMatrixFactory(domain, range); LinearOperator<double> A = mf->createMatrix(); RCP<DenseSerialMatrix> APtr = rcp_dynamic_cast<DenseSerialMatrix>(A.ptr()); APtr->setRow(0, tuple(1.0, 2.0, 3.0)); APtr->setRow(1, tuple(4.0, 5.0, 6.0)); APtr->setRow(2, tuple(7.0, 8.0, 9.0)); APtr->setRow(3, tuple(10.0, 11.0, 12.0)); APtr->setRow(4, tuple(13.0, 14.0, 15.0)); Out::os() << "A = " << std::endl; A.setVerb(10); Out::os() << A << std::endl; LinearOperator<double> U; LinearOperator<double> Vt; Vector<double> sigma; denseSVD(A, U, sigma, Vt); Out::os() << "U = " << std::endl; U.setVerb(10); Out::os() << U << std::endl; Out::os() << "sigma = " << std::endl; Out::os() << sigma << std::endl; Out::os() << "Vt = " << std::endl; Vt.setVerb(10); Out::os() << Vt << std::endl; int nSamples = 10; bool allOK = true; double tol = 1.0e-13; for (int i=0; i<nSamples; i++) { Out::os() << "Sample #" << i << " of " << nSamples << std::endl; Vector<double> x = domain.createMember(); x.randomize(); U.setVerb(0); Vt.setVerb(0); A.setVerb(0); LinearOperator<double> Sigma = diagonalOperator(sigma); Vector<double> z = (U * Sigma * Vt)*x - A*x; double ez = z.norm2(); Out::os() << "|| (U Sigma Vt - A)*x || = " << ez << std::endl; Vector<double> y = (U.transpose() * U)*x - x; double ey = y.norm2(); Out::os() << "|| (U^T U - I)*x || = " << ey << std::endl; Vector<double> w = (Vt * Vt.transpose())*x - x; double ew = w.norm2(); Out::os() << "|| (V^T*V - I)*x || = " << ew << std::endl; if (ew > tol || ez > tol || ey > tol) allOK = false; } if (allOK) { Out::os() << "SVD test PASSED" << std::endl; } else { Out::os() << "SVD test FAILED" << std::endl; stat = -1; } } catch(std::exception& e) { stat = -1; Out::os() << "Caught exception: " << e.what() << std::endl; } return stat; }
SolverState<double> BelosSolver::solve(const LinearOperator<double>& A, const Vector<double>& rhs, Vector<double>& soln) const { typedef Thyra::MultiVectorBase<double> MV; typedef Thyra::LinearOpBase<double> OP; typedef Belos::LinearProblem<double, MV, OP> LP; TEST_FOR_EXCEPT(!A.ptr().get()); TEST_FOR_EXCEPT(!rhs.ptr().get()); /* get Thyra objects */ RCP<OP> APtr = A.ptr(); RCP<MV> bPtr = rhs.ptr(); if (!soln.ptr().get()) soln = rhs.copy(); RCP<MV> ansPtr = soln.ptr(); RCP<LP> prob = rcp(new LP(APtr, ansPtr, bPtr)); TEST_FOR_EXCEPT(!prob->setProblem()); if (pf_.ptr().get()) { Preconditioner<double> P = pf_.createPreconditioner(A); if (P.hasLeft()) { prob->setLeftPrec(P.left().ptr()); } if (P.hasRight()) { prob->setRightPrec(P.right().ptr()); } } ParameterList plist = parameters(); RCP<ParameterList> belosList = rcp(&plist, false); RCP<Belos::SolverManager<double, MV, OP> > solver ; std::string solverType = parameters().get<string>("Method"); if (solverType=="GMRES") { solver=rcp(new Belos::BlockGmresSolMgr<double, MV, OP>(prob, belosList)); } else if (solverType=="CG") { solver=rcp(new Belos::BlockCGSolMgr<double, MV, OP>(prob, belosList)); } else { TEST_FOR_EXCEPT(!(solverType=="GMRES" || solverType=="CG")); } Belos::ReturnType rtn = solver->solve(); int numIters = solver->getNumIters(); double resid = -1.0; SolverStatusCode code = SolveFailedToConverge; if (rtn==Belos::Converged) code = SolveConverged; SolverState<double> state(code, "Belos solver completed", numIters, resid); return state; }