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; }
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; }
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); } }
/** * 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) {}
LinearOperator<double> createW() const { static LinearOperator<double> J = prob_.allocateJacobian(); TEST_FOR_EXCEPTION(J.ptr().get()==0, RuntimeError, "null Jacobian"); return J; }
//============================================================================ KrylovSolverStatus CGNR_Solver:: solve(const LinearOperator &A, const double *rhs, double *result, const LinearOperator *preconditioner, bool use_given_initial_guess) { const int m=A.m, n=A.n; assert(preconditioner==0 || (preconditioner->m==n && preconditioner->n==n)); if((int)s.size()!=n){ r.resize(n); z.resize(n); s.resize(n); u.resize(m); } // convergence tolerance A.apply_transpose(rhs, &r[0]); // form A^T*rhs in r double tol=tolerance_factor*BLAS::abs_max(r); // initial guess if(use_given_initial_guess){ A.apply_and_subtract(result, rhs, &u[0]); A.apply_transpose(u, r); }else{ BLAS::set_zero(n, result); } // check instant convergence iteration=0; residual_norm=BLAS::abs_max(r); if(residual_norm==0) return status=KRYLOV_CONVERGED; // set up CG double rho; if(preconditioner) preconditioner->apply(r, z); else BLAS::copy(r, z); rho=BLAS::dot(r, z); if(rho<=0 || rho!=rho) return status=KRYLOV_BREAKDOWN; BLAS::copy(z, s); // and iterate for(iteration=1; iteration<max_iterations; ++iteration){ double alpha; A.apply(s, u); A.apply_transpose(u, z); double sz=BLAS::dot(u, u); if(sz<=0 || sz!=sz) return status=KRYLOV_BREAKDOWN; alpha=rho/sz; BLAS::add_scaled(n, alpha, &s[0], result); BLAS::add_scaled(-alpha, z, r); residual_norm=BLAS::abs_max(r); if(residual_norm<=tol) return status=KRYLOV_CONVERGED; if(preconditioner) preconditioner->apply(r, z); else BLAS::copy(r, z); double rho_new=BLAS::dot(r, z); if(rho_new<=0 || rho_new!=rho_new) return status=KRYLOV_BREAKDOWN; double beta=rho_new/rho; BLAS::add_scaled(beta, s, z); s.swap(z); // s=beta*s+z rho=rho_new; if ( iteration % 5000 == 0 ) { std::cout << "CGNR_Solver --- residual_norm: " << residual_norm << std::endl; } } return status=KRYLOV_EXCEEDED_MAX_ITERATIONS; }
//============================================================================ KrylovSolverStatus MINRES_CR_Solver:: solve(const LinearOperator &A, const double *rhs, double *result, const LinearOperator *preconditioner, bool use_given_initial_guess) { const int n=A.m; assert(A.n==n); assert(preconditioner==0 || (preconditioner->m==n && preconditioner->n==n)); if((int)s.size()!=n){ r.resize(n); z.resize(n); q.resize(n); s.resize(n); t.resize(n); } // convergence tolerance double tol=tolerance_factor*BLAS::abs_max(n, rhs); // initial guess if(use_given_initial_guess){ A.apply_and_subtract(result, rhs, &r[0]); }else{ BLAS::set_zero(n, result); BLAS::copy(n, rhs, &r[0]); } // check instant convergence iteration=0; residual_norm=BLAS::abs_max(r); if(residual_norm==0) return status=KRYLOV_CONVERGED; // set up CR double rho; if(preconditioner) preconditioner->apply(r, z); else BLAS::copy(r, s); A.apply(s, t); rho=BLAS::dot(r, t); if(rho==0 || rho!=rho) return status=KRYLOV_BREAKDOWN; // and iterate for(iteration=1; iteration<max_iterations; ++iteration){ double alpha; double tt=BLAS::dot(t, t); if(tt==0 || tt!=tt) return status=KRYLOV_BREAKDOWN; alpha=rho/tt; BLAS::add_scaled(n, alpha, &s[0], result); BLAS::add_scaled(-alpha, t, r); residual_norm=BLAS::abs_max(r); if(residual_norm<=tol) return KRYLOV_CONVERGED; if(preconditioner) preconditioner->apply(r, z); else BLAS::copy(r, z); A.apply(z, q); double rho_new=BLAS::dot(r, q); if(rho_new==0 || rho_new!=rho_new) return KRYLOV_BREAKDOWN; double beta=rho_new/rho; BLAS::add_scaled(beta, s, z); s.swap(z); // s=beta*s+z BLAS::add_scaled(beta, t, q); t.swap(q); // t=beta*t+q rho=rho_new; } return KRYLOV_EXCEEDED_MAX_ITERATIONS; }
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; } }
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; }
LinearOperator<double> PartitionedMatrixFactory::createMatrix() const { RCP<LinearOpBase<double> > op = rcp(new TSFExtended::LoadableBlockOperator<double>(domain_, lowestLocalCol_, isBCCol_, remoteBCCols_, range_, lowestLocalRow_, isBCRow_)); LinearOperator<double> A = op; LinearOperator<double> A_ii = blockFactory_[0][0]->createMatrix(); LinearOperator<double> A_ib = blockFactory_[0][1]->createMatrix(); LinearOperator<double> A_bb = blockFactory_[1][1]->createMatrix(); A.setBlock(0,0,A_ii); A.setBlock(0,1,A_ib); A.setBlock(1,1,A_bb); A.endBlockFill(); return A; }
void TestOpGradient::testCall() { const size_t n = 40; const double tol = 1e-8; LinearOperator * op = new OpGradient(n); _ASSERT_EQ(n, op->dimensionIn().first); _ASSERT_EQ(n - 1, op->dimensionOut().first); _ASSERT_NOT(op->isSelfAdjoint()); Matrix x(n, 1); Matrix y(n - 1, 1); for (size_t i = 0; i < n; i++) { x.set(i, 0, i + 1); } for (size_t i = 0; i < n - 1; i++) { y.set(i, 0, 3 * i + 1); } Matrix Tx = op->call(x); Matrix Tstar_y = op->callAdjoint(y); Matrix err = y * Tx; Matrix temp = x*Tstar_y; Matrix::add(err, -1.0, temp, 1.0); _ASSERT(std::abs(err.get(0, 0)) < tol); delete op; }
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; }
void constructPreconditionerAndSolve(LinearOperator& linearOperator, Vector& x, Vector& istlb, const POrComm& parallelInformation_arg, Dune::InverseOperatorResult& result) const { // Construct scalar product. typedef Dune::ScalarProductChooser<Vector, POrComm, category> ScalarProductChooser; typedef std::unique_ptr<typename ScalarProductChooser::ScalarProduct> SPPointer; SPPointer sp(ScalarProductChooser::construct(parallelInformation_arg)); // Communicate if parallel. parallelInformation_arg.copyOwnerToAll(istlb, istlb); #if ! HAVE_UMFPACK if( parameters_.linear_solver_use_amg_ ) { typedef ISTLUtility::CPRSelector< Matrix, Vector, Vector, POrComm> CPRSelectorType; typedef typename CPRSelectorType::AMG AMG; typedef typename CPRSelectorType::Operator MatrixOperator; std::unique_ptr< AMG > amg; std::unique_ptr< MatrixOperator > opA; if( ! std::is_same< LinearOperator, MatrixOperator > :: value ) { // create new operator in case linear operator and matrix operator differ opA.reset( CPRSelectorType::makeOperator( linearOperator.getmat(), parallelInformation_arg ) ); } const double relax = 1.0; // Construct preconditioner. constructAMGPrecond( linearOperator, parallelInformation_arg, amg, opA, relax ); // Solve. solve(linearOperator, x, istlb, *sp, *amg, result); } else #endif { // Construct preconditioner. auto precond = constructPrecond(linearOperator, parallelInformation_arg); // Solve. solve(linearOperator, x, istlb, *sp, *precond, result); } }
::Spacy::Real LinearOperator::operator()( const LinearOperator& dx ) const { return Real( get() * dx.get() ); }
template <class Scalar> inline SolverState<Scalar> BlockTriangularSolver<Scalar> ::solve(const LinearOperator<Scalar>& op, const Vector<Scalar>& rhs, Vector<Scalar>& soln) const { int nRows = op.numBlockRows(); int nCols = op.numBlockCols(); soln = op.domain().createMember(); // bool converged = false; TEST_FOR_EXCEPTION(nRows != rhs.space().numBlocks(), std::runtime_error, "number of rows in operator " << op << " not equal to number of blocks on RHS " << rhs); TEST_FOR_EXCEPTION(nRows != nCols, std::runtime_error, "nonsquare block structure in block triangular " "solver: nRows=" << nRows << " nCols=" << nCols); bool isUpper = false; bool isLower = false; for (int r=0; r<nRows; r++) { for (int c=0; c<nCols; c++) { if (op.getBlock(r,c).ptr().get() == 0 || dynamic_cast<const SimpleZeroOp<Scalar>* >(op.getBlock(r,c).ptr().get())) { TEST_FOR_EXCEPTION(r==c, std::runtime_error, "zero diagonal block (" << r << ", " << c << " detected in block " "triangular solver. Operator is " << op); continue; } else { if (r < c) isUpper = true; if (c < r) isLower = true; } } } TEST_FOR_EXCEPTION(isUpper && isLower, std::runtime_error, "block triangular solver detected non-triangular operator " << op); bool oneSolverFitsAll = false; if ((int) solvers_.size() == 1 && nRows != 1) { oneSolverFitsAll = true; } for (int i=0; i<nRows; i++) { int r = i; if (isUpper) r = nRows - 1 - i; Vector<Scalar> rhs_r = rhs.getBlock(r); for (int j=0; j<i; j++) { int c = j; if (isUpper) c = nCols - 1 - j; if (op.getBlock(r,c).ptr().get() != 0) { rhs_r = rhs_r - op.getBlock(r,c) * soln.getBlock(c); } } SolverState<Scalar> state; Vector<Scalar> soln_r; if (oneSolverFitsAll) { state = solvers_[0].solve(op.getBlock(r,r), rhs_r, soln_r); } else { state = solvers_[r].solve(op.getBlock(r,r), rhs_r, soln_r); } if (nRows > 1) soln.setBlock(r, soln_r); else soln = soln_r; if (state.finalState() != SolveConverged) { return state; } } return SolverState<Scalar>(SolveConverged, "block solves converged", 0, ScalarTraits<Scalar>::zero()); }
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; }
int main(int argc, char *argv[]) { typedef Teuchos::ScalarTraits<double> ST; try { GlobalMPISession session(&argc, &argv); MPIComm::world().synchronize(); VectorType<double> type = new EpetraVectorType(); /* create the range space */ int nLocalRows = 10; MatrixLaplacian1D builder(nLocalRows, type); LinearOperator<double> A = builder.getOp(); int nBlocks = 3; Array<Vector<double> > x(nBlocks); Array<VectorSpace<double> > space(nBlocks); for (int i=0; i<nBlocks; i++) { space[i] = A.domain(); x[i] = A.domain().createMember(); Thyra::randomize(-ST::one(),+ST::one(),x[i].ptr().ptr()); } VectorSpace<double> blockSpace = productSpace(space); LinearOperator<double> bigA = makeBlockOperator(blockSpace, blockSpace); Vector<double> bigRHS = blockSpace.createMember(); Vector<double> bigX = blockSpace.createMember(); for (int i=0; i<nBlocks; i++) { bigX.setBlock(i, x[i]); for (int j=i; j<nBlocks; j++) { MatrixLaplacian1D builder(nLocalRows, type); LinearOperator<double> Aij = builder.getOp(); bigA.setBlock(i,j,Aij); } } bigA.endBlockFill(); bigRHS = bigA * bigX; Vector<double> bigSoln = blockSpace.createMember(); #ifdef HAVE_CONFIG_H ParameterXMLFileReader reader(Sundance::searchForFile("SolverParameters/poissonParams.xml")); #else ParameterXMLFileReader reader("poissonParams.xml"); #endif ParameterList solverParams = reader.getParameters(); LinearSolver<double> solver = LinearSolverBuilder::createSolver(solverParams); LinearSolver<double> blockSolver = new BlockTriangularSolver<double>(solver); SolverState<double> state = blockSolver.solve(bigA, bigRHS, bigSoln); std::cerr << state << std::endl; double err = (bigSoln - bigX).norm2(); std::cerr << "error norm = " << err << std::endl; double tol = 1.0e-8; if (err > tol) { std::cerr << "Poisson solve test FAILED" << std::endl; return 1; } else { std::cerr << "Poisson solve test PASSED" << std::endl; return 0; } } catch(std::exception& e) { std::cerr << "Caught exception: " << e.what() << std::endl; return -1; } return 0; }
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; }
int main(int argc, char *argv[]) { typedef Teuchos::ScalarTraits<double> ST; try { GlobalMPISession session(&argc, &argv); MPIComm::world().synchronize(); VectorType<double> type = new EpetraVectorType(); ParameterXMLFileReader reader("anasazi-ml.xml"); ParameterList solverParams = reader.getParameters().sublist("Eigensolver"); /* create the range space */ int nLocalRows = 40; MatrixLaplacian1D builder(nLocalRows, type); typedef Anasazi::MultiVec<double> MV; typedef Anasazi::Operator<double> OP; LinearOperator<double> A = builder.getOp(); LinearOperator<double> M; Teuchos::RCP<Anasazi::OutputManager<double> > MyOM = Teuchos::rcp( new Anasazi::BasicOutputManager<double>() ); MyOM->setVerbosity(Anasazi::Warnings); int nv = 1; RCP<const Array<Vector<double> > > initMV = rcp(new Array<Vector<double> >(nv)); RCP<Array<Vector<double> > > nc = rcp_const_cast<Array<Vector<double> > >(initMV); for (int i=0; i<nv; i++) { (*nc)[i] = A.domain().createMember(); (*nc)[i].randomize(); } #ifdef BLARF bool mvPass = Anasazi::TestMultiVecTraits<double,Array<Vector<double> > >(MyOM,initMV); if (mvPass) Out::os() << "******* MV unit test PASSED ******* " << endl; else Out::os() << "******* MV unit test FAILED ******* " << endl; RCP<const LinearOperator<double> > APtr = rcp(&A, false); bool opPass = Anasazi::TestOperatorTraits<double, Array<Vector<double> >, LinearOperator<double> >(MyOM, initMV, APtr); if (opPass) Out::os() << "******* OP unit test PASSED ******* " << endl; else Out::os() << "******* OP unit test FAILED ******* " << endl; #endif Eigensolver<double> solver = new AnasaziEigensolver<double>(solverParams); Array<Vector<double> > ev; Array<std::complex<double> > ew; solver.solve(A, M, ev, ew); Out::os() << "Eigenvalues are " << ew << endl; const double pi = 4.0*atan(1.0); double err = 0.0; for (int i=0; i<ev.size(); i++) { double x = (i+1)*pi; err += ::fabs(ew[i].real()-x*x)/x/x; } err = err / ew.size(); Out::os() << "error = " << err << endl; if (err < 0.01) { cout << "Belos poisson solve test PASSED" << std::endl; return 0; } else { cout << "Belos poisson solve test FAILED" << std::endl; return 1; } } catch(std::exception& e) { cout << "Caught exception: " << e.what() << std::endl; return -1; } }
inline bool LinearCombinationTester<Scalar> ::selfModifyingOpTests() const { bool pass = true; RandomSparseMatrixBuilder<double> ABuilder(nLocalRows_, nLocalRows_, onProcDensity_, offProcDensity_, vecType_); RandomSparseMatrixBuilder<double> BBuilder(nLocalRows_, nLocalRows_, onProcDensity_, offProcDensity_, vecType_); RandomSparseMatrixBuilder<double> CBuilder(nLocalRows_, nLocalRows_, onProcDensity_, offProcDensity_, vecType_); LinearOperator<double> A = ABuilder.getOp(); LinearOperator<double> B = BBuilder.getOp(); LinearOperator<double> C = CBuilder.getOp(); VectorSpace<Scalar> vs = A.domain(); A = identityOperator(vs); B = identityOperator(vs); C = identityOperator(vs); Vector<Scalar> x = A.domain().createMember(); Vector<Scalar> y = A.domain().createMember(); Vector<Scalar> z = A.domain().createMember(); this->randomizeVec(x); this->randomizeVec(y); this->randomizeVec(z); Vector<Scalar> a = x.copy(); Vector<Scalar> b = y.copy(); Vector<Scalar> c = z.copy(); Out::os() << "starting linear combination tests" << std::endl; x = 2.0*A*x; Scalar err = (x - 2.0*A*a).norm2(); if (!this->checkTest(spec_, err, "x=2.0*A*x")) pass = false; a = x.copy(); x = x + y; err = (x - (a + y)).norm2(); if (!this->checkTest(spec_, err, "x=x+y")) pass = false; a = x.copy(); x = y + x; err = (x - (y + a)).norm2(); if (!this->checkTest(spec_, err, "x=y+x")) pass = false; a = x.copy(); x = A*x + B*y; err = (x - (A*a + B*y)).norm2(); if (!this->checkTest(spec_, err, "x=A*x+B*y")) pass = false; a = x.copy(); x = B*y + A*x; err = (x - (B*y + A*a)).norm2(); if (!this->checkTest(spec_, err, "x=B*y+A*x")) pass = false; a = x.copy(); x = A*x + (B*y + C*x); err = (x - (A*a + (B*y + C*a))).norm2(); if (!this->checkTest(spec_, err, "x=A*x + (B*y + C*x)")) pass = false; a = x.copy(); x = (A*x + B*y) + C*x; err = (x - ((A*a + B*y) + C*a)).norm2(); if (!this->checkTest(spec_, err, "x=(A*x + B*y) + C*x")) pass = false; /* test assignment of OpTimesLC into empty and non-empty vectors */ Vector<Scalar> u; u = 2.0*A*B*x; err = (u - 2.0*A*B*x).norm2(); if (!this->checkTest(spec_, err, "(empty) u=2*A*B*x")) pass = false; u = 2.0*A*B*x; err = (u - 2.0*A*B*x).norm2(); if (!this->checkTest(spec_, err, "(non-empty) u=2*A*B*x")) pass = false; /* test assignment of LC2 into empty and non-empty vectors */ Vector<Scalar> v; v = 2.0*x + 3.0*y; err = (v - (2.0*x + 3.0*y)).norm2(); if (!this->checkTest(spec_, err, "(empty) v=2*x + 3*y")) pass = false; v = 2.0*x + 3.0*y; err = (v - (2.0*x + 3.0*y)).norm2(); if (!this->checkTest(spec_, err, "(non-empty) v=2*x + 3*y")) pass = false; /* test assignment of LC3 into empty and non-empty vectors */ Vector<Scalar> w; w = 2.0*x + 3.0*y + 5.0*z; err = (w - (2.0*x + 3.0*y + 5.0*z)).norm2(); if (!this->checkTest(spec_, err, "(empty) w=2*x + 3*y + 5*z")) pass = false; w = 2.0*x + 3.0*y + 5.0*z; err = (w - (2.0*x + 3.0*y + 5.0*z)).norm2(); if (!this->checkTest(spec_, err, "(non-empty) w=2*x + 3*y + 5*z")) pass = false; /* test assignment of LC4 into empty and non-empty vectors */ Vector<Scalar> w2; w2 = 2.0*x + 3.0*y + 5.0*z + 7.0*u; err = (w2 - (2.0*x + 3.0*y + 5.0*z + 7.0*u)).norm2(); if (!this->checkTest(spec_, err, "(empty) w2=2*x + 3*y + 5*z + 7*u")) pass = false; w2 = 2.0*x + 3.0*y + 5.0*z + 7.0*u; err = (w2 - (2.0*x + 3.0*y + 5.0*z + 7.0*u)).norm2(); if (!this->checkTest(spec_, err, "(non-empty) w2=2*x + 3*y + 5*z + 7*u")) pass = false; /* test assignment of LC3 into one of the operands */ x = 2.0*x + 3.0*y + 5.0*z; err = (w - x).norm2(); // Note: w contains 2x + 3y + 5z if (!this->checkTest(spec_, err, "x=2*x + 3*y + 5*z")) pass = false; return pass; }
inline bool LinearCombinationTester<Scalar> ::nonModifyingOpTests() const { bool pass = true; RandomSparseMatrixBuilder<double> ABuilder(nLocalRows_, nLocalRows_, onProcDensity_, offProcDensity_, vecType_); RandomSparseMatrixBuilder<double> BBuilder(nLocalRows_, nLocalRows_, onProcDensity_, offProcDensity_, vecType_); RandomSparseMatrixBuilder<double> CBuilder(nLocalRows_, nLocalRows_, onProcDensity_, offProcDensity_, vecType_); LinearOperator<double> A = ABuilder.getOp(); LinearOperator<Scalar> B = BBuilder.getOp(); LinearOperator<Scalar> C = CBuilder.getOp(); Vector<Scalar> x = A.domain().createMember(); Vector<Scalar> y = A.domain().createMember(); Vector<Scalar> z = A.domain().createMember(); this->randomizeVec(x); this->randomizeVec(y); this->randomizeVec(z); TESTER(x*2.0, 2.0*x); TESTER(2.0*(x + y), 2.0*x + 2.0*y); TESTER(2.0*(x - y), 2.0*x - 2.0*y); TESTER((2.0*x + y) - y, 2.0*x); TESTER(-1.0*y + (2.0*x + y), 2.0*x); TESTER((x + y)*2.0, 2.0*x + 2.0*y); TESTER((x - y)*2.0, 2.0*x - 2.0*y); TESTER(2.0*(x - y), -2.0*(y - x)); TESTER(0.25*(2.0*(x + y) - 2.0*(x - y)), y); TESTER((2.0*A)*x, 2.0*(A*x)); TESTER(2.0*(A*x), (A*x)*2.0); TESTER(A*(B*x), (A*B)*x); TESTER(2.0*A*(B*x), A*(B*(2.0*x))); TESTER(3.0*(2.0*A)*x, 6.0*(A*x)); TESTER(y + A*x, A*x + y); TESTER(z + (A*x + B*y), (B*y + A*x) + z); TESTER(z - (A*x + B*y), -1.0*((B*y + A*x) - z)); TESTER(C*z + (A*x + B*y), (B*y + A*x) + C*z); TESTER(C*z - (A*x + B*y), -1.0*((B*y + A*x) - C*z)); TESTER(2.0*z + (A*x + B*y), (B*y + A*x) + 2.0*z); TESTER(2.0*z - (A*x + B*y), -1.0*((B*y + A*x) - 2.0*z)); TESTER(A*x - y, -1.0*(y - A*x)); TESTER(A*x + B*y, B*y + A*x); TESTER(A*x - B*y - A*x + B*y +z, z); TESTER(2.0*(A*x + y), 2.0*A*x + 2.0*y); TESTER(2.0*(A*x + B*y), A*x + B*y + A*x + B*y); TESTER(2.0*(y + A*x), 2.0*y + 2.0*(A*x)); TESTER(x + 2.0*A*y, x + 2.0*(A*y)); TESTER(2.0*A*y + x, 2.0*(A*y) + x); TESTER(2.0*A*(3.0*B)*y, 6.0*(A*B*y)); TESTER(2.0*A*(3.0*B)*y, 6.0*(A*(B*y))); TESTER(2.0*A*(3.0*B + 2.0*A)*x, 6.0*A*B*x + 4.0*A*A*x ); TESTER(2.0*(A*x + B*y), 2.0*A*x + 2.0*B*y); TESTER(2.0*(A*x - B*y), 2.0*A*x - 2.0*B*y); TESTER(2.0*(A*x + B*y + z), 2.0*A*x + 2.0*B*y + 2.0*z); TESTER(2.0*(A*x + 3.0*B*y), 2.0*A*x + 6.0*B*y); TESTER(2.0*(A*x + 3.0*(z + B*y)), 2.0*A*x + 6.0*B*y + 6.0*z); TESTER(2.0*(z + A*x + B*y + z), 2.0*A*x + 2.0*B*y + 4.0*z); TESTER(2.0*(3.0*(z + A*x) + B*y), 6.0*z + 6.0*A*x + 2.0*B*y); TESTER(2.0*(3.0*(z + A*x) + 4.0*(B*y + z)), 6.0*z + 6.0*A*x + 8.0*B*y + 8.0*z); TESTER((A*x + B*y) + (A*y + B*x), (A + B)*x + (A+B)*y); TESTER((A*x + B*y) - (A*y + B*x), A*x - A*y + B*y - B*x); TESTER((A*x + B*y) + 2.0*(A*y + B*x), A*(x + 2.0*y) + B*(2.0*x + y)); TESTER((A*x + B*y) - 2.0*(A*y + B*x), A*(x - 2.0*y) + B*(y - 2.0*x)); return pass; }
void run( Vector<Real> &x, LinearOperator<Real> &A, const Vector<Real> &b, LinearOperator<Real> &M, int &iter, int &flag ) { using Teuchos::RCP; flag = 0; Real zero = 0.0; Real one = 1.0; if ( !isInitialized_ ) { r_ = b.clone(); w_ = b.clone(); z_ = x.clone(); isInitialized_ = true; } Real itol = std::sqrt(ROL_EPSILON<Real>()); // Compute initial residual if(useInitialGuess_) { A.apply(*r_,x,itol); r_->scale(-1.0); r_->plus(b); // r = b-Ax } else { x.zero(); r_->set(b); } Real temp = 0; std::vector<RCP<Vector<Real > > > V; std::vector<RCP<Vector<Real > > > Z; (*res_)[0] = r_->norm(); Real rtol = std::min(absTol_,relTol_*(*res_)[0]); V.push_back(b.clone()); (V[0])->set(*r_); (V[0])->scale(one/(*res_)[0]); (*s_)(0) = (*res_)[0]; for( iter=0; iter<maxit_; ++iter ) { // std::cout << (*res_)[iter] << std::endl; if( useInexact_ ) { itol = rtol/(maxit_*(*res_)[iter]); } Z.push_back(x.clone()); // Apply right preconditioner M.applyInverse(*(Z[iter]),*(V[iter]),itol); // Apply operator A.apply(*w_,*(Z[iter]),itol); // Evaluate coefficients and orthogonalize using Gram-Schmidt for( int k=0; k<=iter; ++k ) { (*H_)(k,iter) = w_->dot(*(V[k])); w_->axpy( -(*H_)(k,iter), *(V[k]) ); } (*H_)(iter+1,iter) = w_->norm(); V.push_back( b.clone() ); (V[iter+1])->set(*w_); (V[iter+1])->scale(one/((*H_)(iter+1,iter))); // Apply Givens rotations for( int k=0; k<=iter-1; ++k ) { temp = (*cs_)(k)*(*H_)(k,iter) + (*sn_)(k)*(*H_)(k+1,iter); (*H_)(k+1,iter) = -(*sn_)(k)*(*H_)(k,iter) + (*cs_)(k)*(*H_)(k+1,iter); (*H_)(k,iter) = temp; } // Form i-th rotation matrix if( (*H_)(iter+1,iter) == zero ) { (*cs_)(iter) = one; (*sn_)(iter) = zero; } else if ( std::abs((*H_)(iter+1,iter)) > std::abs((*H_)(iter,iter)) ) { temp = (*H_)(iter,iter) / (*H_)(iter+1,iter); (*sn_)(iter) = one / std::sqrt( one + temp*temp ); (*cs_)(iter) = temp*(*sn_)(iter); } else { temp = (*H_)(iter+1,iter) / (*H_)(iter,iter); (*cs_)(iter) = one / std::sqrt( one + temp*temp ); (*sn_)(iter) = temp*(*cs_)(iter); } // Approximate residual norm temp = (*cs_)(iter)*(*s_)(iter); (*s_)(iter+1) = -(*sn_)(iter)*(*s_)(iter); (*s_)(iter) = temp; (*H_)(iter,iter) = (*cs_)(iter)*(*H_)(iter,iter) + (*sn_)(iter)*(*H_)(iter+1,iter); (*H_)(iter+1,iter) = zero; (*res_)[iter+1] = std::abs((*s_)(iter+1)); // Update solution approximation. const char uplo = 'U'; const char trans = 'N'; const char diag = 'N'; const char normin = 'N'; Real scaling = zero; int info = 0; *y_ = *s_; lapack_.LATRS(uplo, trans, diag, normin, iter+1, H_->values(), maxit_+1, y_->values(), &scaling, cnorm_->values(), &info); z_->zero(); for( int k=0; k<=iter;++k ) { z_->axpy((*y_)(k),*(Z[k])); } if( (*res_)[iter+1] <= rtol ) { // Update solution vector x.plus(*z_); break; } if(iter == maxit_) { flag = 1; } } // loop over iter }
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[]) { 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; } }
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; }
bool DuffingFloquet() { int np = MPIComm::world().getNProc(); TEUCHOS_TEST_FOR_EXCEPT(np != 1); const double pi = 4.0*atan(1.0); /* We will do our linear algebra using Epetra */ VectorType<double> vecType = new EpetraVectorType(); /* Create a periodic mesh */ int nx = 128; MeshType meshType = new PeriodicMeshType1D(); MeshSource mesher = new PeriodicLineMesher(0.0, 2.0*pi, nx, meshType); Mesh mesh = mesher.getMesh(); /* Create a cell filter that will identify the maximal cells * in the interior of the domain */ CellFilter interior = new MaximalCellFilter(); CellFilter pts = new DimensionalCellFilter(0); CellFilter left = pts.subset(new CoordinateValueCellPredicate(0,0.0)); CellFilter right = pts.subset(new CoordinateValueCellPredicate(0,2.0*pi)); /* Create unknown and test functions, discretized using first-order * Lagrange interpolants */ Expr u1 = new UnknownFunction(new Lagrange(1), "u1"); Expr u2 = new UnknownFunction(new Lagrange(1), "u2"); Expr v1 = new TestFunction(new Lagrange(1), "v1"); Expr v2 = new TestFunction(new Lagrange(1), "v2"); /* Create differential operator and coordinate function */ Expr dx = new Derivative(0); Expr x = new CoordExpr(0); /* We need a quadrature rule for doing the integrations */ QuadratureFamily quad = new GaussianQuadrature(4); double F0 = 0.5; double gamma = 2.0/3.0; double a0 = 1.0; double w0 = 1.0; double eps = 0.5; Expr u1Guess = -0.75*cos(x) + 0.237*sin(x); Expr u2Guess = 0.237*cos(x) + 0.75*sin(x); DiscreteSpace discSpace(mesh, List(new Lagrange(1), new Lagrange(1)), vecType); L2Projector proj(discSpace, List(u1Guess, u2Guess)); Expr u0 = proj.project(); Expr rhs1 = u2; Expr rhs2 = -w0*w0*u1 - gamma*u2 - eps*w0*w0*pow(u1,3.0)/a0/a0 + F0*w0*w0*sin(x); /* Define the weak form */ Expr eqn = Integral(interior, v1*(dx*u1 - rhs1) + v2*(dx*u2 - rhs2), quad); Expr dummyBC ; NonlinearProblem prob(mesh, eqn, dummyBC, List(v1,v2), List(u1,u2), u0, vecType); ParameterXMLFileReader reader("nox.xml"); ParameterList solverParams = reader.getParameters(); Out::root() << "finding periodic solution" << endl; NOXSolver solver(solverParams); prob.solve(solver); /* unfold the solution onto a non-periodic mesh */ Expr uP = unfoldPeriodicDiscreteFunction(u0, "u_p"); Out::root() << "uP=" << uP << endl; Mesh unfoldedMesh = DiscreteFunction::discFunc(uP)->mesh(); DiscreteSpace unfDiscSpace = DiscreteFunction::discFunc(uP)->discreteSpace(); FieldWriter writer = new MatlabWriter("Floquet.dat"); writer.addMesh(unfoldedMesh); writer.addField("u_p[0]", new ExprFieldWrapper(uP[0])); writer.addField("u_p[1]", new ExprFieldWrapper(uP[1])); Array<Expr> a(2); a[0] = new Sundance::Parameter(0.0, "a1"); a[1] = new Sundance::Parameter(0.0, "a2"); Expr bc = EssentialBC(left, v1*(u1-uP[0]-a[0]) + v2*(u2-uP[1]-a[1]), quad); NonlinearProblem unfProb(unfoldedMesh, eqn, bc, List(v1,v2), List(u1,u2), uP, vecType); unfProb.setEvalPoint(uP); LinearOperator<double> J = unfProb.allocateJacobian(); Vector<double> b = J.domain().createMember(); LinearSolver<double> linSolver = LinearSolverBuilder::createSolver("amesos.xml"); SerialDenseMatrix<int, double> F(a.size(), a.size()); for (int i=0; i<a.size(); i++) { Out::root() << "doing perturbed orbit #" << i << endl; for (int j=0; j<a.size(); j++) { if (i==j) a[j].setParameterValue(1.0); else a[j].setParameterValue(0.0); } unfProb.computeJacobianAndFunction(J, b); Vector<double> w = b.copy(); linSolver.solve(J, b, w); Expr w_i = new DiscreteFunction(unfDiscSpace, w); for (int j=0; j<a.size(); j++) { Out::root() << "postprocessing" << i << endl; writer.addField("w[" + Teuchos::toString(i) + ", " + Teuchos::toString(j) + "]", new ExprFieldWrapper(w_i[j])); Expr g = Integral(right, w_i[j], quad); F(j,i) = evaluateIntegral(unfoldedMesh, g); } } writer.write(); Out::root() << "Floquet matrix = " << endl << F << endl; Out::root() << "doing eigenvalue analysis" << endl; Array<double> ew_r(a.size()); Array<double> ew_i(a.size()); int lWork = 6*a.size(); Array<double> work(lWork); int info = 0; LAPACK<int, double> lapack; lapack.GEEV('N','N', a.size(), F.values(), a.size(), &(ew_r[0]), &(ew_i[0]), 0, 1, 0, 1, &(work[0]), lWork, &info); TEUCHOS_TEST_FOR_EXCEPTION(info != 0, std::runtime_error, "LAPACK GEEV returned error code =" << info); Array<double> ew(a.size()); for (int i=0; i<a.size(); i++) { ew[i] = sqrt(ew_r[i]*ew_r[i]+ew_i[i]*ew_i[i]); Out::root() << setw(5) << i << setw(16) << ew_r[i] << setw(16) << ew_i[i] << setw(16) << ew[i] << endl; } double err = ::fabs(ew[0] - 0.123); return SundanceGlobal::checkTest(err, 0.001); }
int main(int argc, char *argv[]) { int stat = 0; try { GlobalMPISession session(&argc, &argv); /* create a distributed vector space for the multivector's vectors */ VectorType<double> rowType = new EpetraVectorType(); int nLocalRows = 2; VectorSpace<double> space = rowType.createEvenlyPartitionedSpace(MPIComm::world(), nLocalRows); /* create a replicated vector space for the small space of columns */ int nVecs = 3; VectorType<double> colType = new SerialVectorType(); VectorSpace<double> replSpace = colType.createEvenlyPartitionedSpace(MPIComm::world(), nVecs); /* create some random vectors */ Teuchos::Array<Vector<double> > vecs(nVecs); for (int i=0; i<nVecs; i++) { vecs[i] = space.createMember(); vecs[i].randomize(); } /* Test multiplication by a multivector operator. We will compute * y1 by directly summing columns, and y2 by applying the operator */ LinearOperator<double> A = multiVectorOperator<double>(vecs, replSpace); Vector<double> y1 = space.createMember(); Vector<double> y2 = space.createMember(); y1.zero(); y2.zero(); /* Sum columns, putting the weights into x */ Vector<double> x = replSpace.createMember(); Out::os() << "A=" << A << std::endl; for (int j=0; j<replSpace.numLocalElements(); j++) { x[j] = 2.0*(drand48()-0.5); y1 = y1 + x[j] * vecs[j]; Out::os() << "x[" << j << "]=" << x[j] << std::endl; Out::os() << "vecs[j]=" << vecs[j] << std::endl; } Out::os() << "y1=" << std::endl << y1 << std::endl; /* Apply the operator to the vector of weights */ y2 = A * x; Out::os() << "y2=A*x=" << std::endl << y2 << std::endl; Vector<double> y12 = y1-y2; Vector<double> y21 = y2-y1; Out::os() << "y1-y2=" << std::endl << y12 << std::endl; Out::os() << "y2-y1=" << std::endl << y21 << std::endl; double errA = (y1-y2).norm2(); Out::root() << "error in A*x = " << errA << std::endl; /* Now test z = A^T * y */ LinearOperator<double> At = A.transpose(); Vector<double> z1 = replSpace.createMember(); z1.zero(); Vector<double> z2 = replSpace.createMember(); z2.zero(); Vector<double> y = y1.copy(); /* compute by vectorwise multiplication */ for (int j=0; j<replSpace.numLocalElements(); j++) { z1[j] = vecs[j].dot(y); } /* compute with operator */ z2 = At * y; double errAt = (z1-z2).normInf(); Out::root() << "error in At*y = " << errA << std::endl; double tol = 1.0e-13; bool pass = errA + errAt < tol; pass = globalAnd(pass); if (pass) { Out::root() << "multivector op test PASSED" << std::endl; } else { stat = -1; Out::root() << "multivector op test FAILED" << std::endl; } } catch(std::exception& e) { stat = -1; std::cerr << "Caught exception: " << e.what() << std::endl; } return stat; }
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); }