LinearOperator<double> epetraRightScale( const LinearOperator<double>& A, const Vector<double>& d) { /* 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->RightScale(epv); /* Prepare an operator object for the scaled matrix */ RCP<LinearOperatorBase<double> > rtn = rcp(new EpetraMatrix(mtxCopy, A.domain(), A.range())); return rtn; }
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[]) { 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; } }
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); }
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; }
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; } }
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; }
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); }