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); } }
LinearOperator<double> epetraMatrixMatrixProduct( const LinearOperator<double>& A, const LinearOperator<double>& B) { /* Extract the underlying Epetra matrix for A. Type checking is done * ny rcp_dynamic_cast, so we need no error check here. */ RCP<const Epetra_CrsMatrix> A_crs = EpetraMatrix::getConcretePtr(A); /* Extract the underlying Epetra matrix for A. Type checking is done * ny rcp_dynamic_cast, so we need no error check here. */ RCP<const Epetra_CrsMatrix> B_crs = EpetraMatrix::getConcretePtr(B); bool transA = false; bool transB = false; /* Get the row map from A. We will need this to build the target matrix C */ const Epetra_Map* rowmap = transA ? &(A_crs->DomainMap()) : &(A_crs->RowMap()); /* make the target matrix */ RCP<Epetra_CrsMatrix> C = rcp(new Epetra_CrsMatrix(Copy, *rowmap, 1)); /* Carry out the multiplication */ int ierr = EpetraExt::MatrixMatrix::Multiply(*A_crs, transA, *B_crs, transB, *C); TEUCHOS_TEST_FOR_EXCEPTION(ierr != 0, RuntimeError, "EpetraExt Matrix-matrix multiply failed with error code ierr=" << ierr); /* Prepare an operator object for the scaled matrix */ RCP<LinearOperatorBase<double> > rtn = rcp(new EpetraMatrix(C, B.domain(), A.range())); return rtn; }
/** * Construct a InverseLTIOp that takes <t>numTimesteps</t> steps * with the operator \f$ A\f$. */ InverseLTIOp(int numTimesteps, const LinearOperator<Scalar>& A, const LinearOperator<Scalar>& At) : HomogeneouslyBlockedLinearOp<Scalar>( A.domain(), numTimesteps, A.range(), numTimesteps), A_(A), At_(At) {}
bool runit(const VectorType<double>& vecType, const LinearSolver<double>& solver) { typedef Teuchos::ScalarTraits<double> ST; /* create the range space */ int nLocalRows = 10; MatrixLaplacian1D builder(nLocalRows, vecType); LinearOperator<double> A = builder.getOp(); Out::root() << "matrix is " << std::endl; Out::os() << A << std::endl; Vector<double> x = A.domain().createMember(); x.randomize(); Out::root() << "input is " << std::endl; Out::os() << x << std::endl; Vector<double> y = A*x; Out::root() << "rhs is " << std::endl; Out::os() << y << std::endl; Vector<double> ans = A.range().createMember(); Out::root() << "slot for solution is " << std::endl; Out::os() << ans << std::endl; LinearOperator<double> AInv = inverse(A, solver); ans = AInv * y; Out::root() << "answer is " << std::endl; Out::os() << ans << std::endl; double err = (x-ans).norm2(); Out::root() << "error norm = " << err << std::endl; double tol = 1.0e-7; if (err <= tol) { Out::root() << "Poisson solve test PASSED" << std::endl; return true; } else { Out::root() << "Poisson solve test FAILED" << std::endl; return false; } }
LinearOperator<double> epetraLeftScale( const Vector<double>& d, const LinearOperator<double>& A) { /* Extract the underlying Epetra matrix. Type checking is done * ny rcp_dynamic_cast, so we need no error check here. */ RCP<const Epetra_CrsMatrix> A_crs = EpetraMatrix::getConcretePtr(A); /* Make a deep copy of A */ RCP<Epetra_CrsMatrix> mtxCopy = rcp(new Epetra_CrsMatrix(*A_crs)); /* Extract the underlying Epetra vector. Type checking is done * internally, so we need no error check here. */ const Epetra_Vector& epv = EpetraVector::getConcrete(d); /* Scale the copy */ mtxCopy->LeftScale(epv); RCP<LinearOperatorBase<double> > rtn = rcp(new EpetraMatrix(mtxCopy, A.domain(), A.range())); return rtn; }
int main(int argc, char *argv[]) { typedef Teuchos::ScalarTraits<double> ST; try { GlobalMPISession session(&argc, &argv); MPIComm::world().synchronize(); VectorType<double> type = new EpetraVectorType(); #ifdef HAVE_CONFIG_H ParameterXMLFileReader reader(Sundance::searchForFile("SolverParameters/userPrecParams.xml")); #else ParameterXMLFileReader reader("userPrecParams.xml"); #endif ParameterList solverParams = reader.getParameters(); ParameterList innerSolverParams = solverParams.sublist("Inner Solve"); ParameterList outerSolverParams = solverParams.sublist("Outer Solve"); /* create the range space */ int nLocalRows = solverParams.get<int>("nLocal"); MatrixLaplacian1D builder(nLocalRows, type); LinearOperator<double> A = builder.getOp(); Vector<double> x = A.domain().createMember(); int myRank = MPIComm::world().getRank(); int nProcs = MPIComm::world().getNProc(); Thyra::randomize(-ST::one(),+ST::one(),x.ptr().ptr()); #ifdef TRILINOS_6 if (myRank==0) x[0] = 0.0; if (myRank==nProcs-1) x[nProcs * nLocalRows - 1] = 0.0; // need to fix operator[] routine #else if (myRank==0) x.setElement(0, 0); if (myRank==nProcs-1) x.setElement(nProcs * nLocalRows - 1, 0.0); #endif cout << "x=" << std::endl; x.print(cout); Vector<double> y = A*x; cout << "y=" << std::endl; y.print(cout); Vector<double> ans = A.range().createMember(); LinearSolver<double> innerSolver = LinearSolverBuilder::createSolver(innerSolverParams); LinearSolver<double> outerSolver = LinearSolverBuilder::createSolver(outerSolverParams); /* call the setUserPrec() function to set the operator and solver * to be used for preconditioning */ outerSolver.setUserPrec(A, innerSolver); LinearOperator<double> AInv = inverse(A, outerSolver); ans = AInv * y; // SolverState<double> state = solver.solve(A, y, ans); // cout << state << std::endl; cout << "answer is " << std::endl; ans.print(cout); double err = (x-ans).norm2(); cout << "error norm = " << err << std::endl; double tol = 1.0e-8; if (err > tol) { cout << "User-defined preconditioner test FAILED" << std::endl; return 1; } else { cout << "User-defined preconditioner test PASSED" << std::endl; return 0; } } catch(std::exception& e) { cout << "Caught exception: " << e.what() << std::endl; return -1; } }
Preconditioner<double> PCDPreconditionerFactory:: createPreconditioner(const LinearOperator<double>& K) const { Tabs tab; LinearOperator<double> F = K.getBlock(0,0); // F.setName("F"); LinearOperator<double> FInv = inverse(F, FSolver_); // FInv.setName("FInv"); LinearOperator<double> Bt = K.getBlock(0,1); // Bt.setName("Bt"); LinearOperator<double> Fp = FpProb_.getOperator(); LinearOperator<double> Mp = MpProb_.getOperator(); // Mp.setName("Mp"); LinearOperator<double> MpInv = inverse(Mp, MpSolver_); // MpInv.setName("MpInv"); LinearOperator<double> Ap = ApProb_.getOperator(); // Ap.setName("Ap"); LinearOperator<double> ApInv = inverse(Ap, ApSolver_); // ApInv.setName("ApInv"); VectorSpace<double> pDomain = Bt.domain(); VectorSpace<double> uDomain = F.domain(); LinearOperator<double> Iu = identityOperator(uDomain); // Iu.setName("Iu"); LinearOperator<double> Ip = identityOperator(pDomain); // Ip.setName("Ip"); LinearOperator<double> XInv = MpInv * Fp * ApInv; VectorSpace<double> rowSpace = K.range(); VectorSpace<double> colSpace = K.domain(); LinearOperator<double> Q1 = makeBlockOperator(colSpace, rowSpace); // Q1.setName("Q1"); LinearOperator<double> Q2 = makeBlockOperator(colSpace, rowSpace); // Q2.setName("Q2"); LinearOperator<double> Q3 = makeBlockOperator(colSpace, rowSpace); //Q3.setName("Q3"); Q1.setBlock(0, 0, FInv); Q1.setBlock(1, 1, Ip); Q1.endBlockFill(); Q2.setBlock(0, 0, Iu); Q2.setBlock(0, 1, -1.0*Bt); Q2.setBlock(1, 1, Ip); Q2.endBlockFill(); Q3.setBlock(0, 0, Iu); Q3.setBlock(1, 1, -1.0*XInv); Q3.endBlockFill(); LinearOperator<double> P1 = Q2 * Q3; LinearOperator<double> PInv = Q1 * P1; return new GenericRightPreconditioner<double>(PInv); }