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; }
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; }