/*! * \brief Solve. */ void JacobiSolver::iterate( const int max_iters, const double tolerance ) { // Extract the linear problem. Epetra_CrsMatrix *A = dynamic_cast<Epetra_CrsMatrix*>( d_linear_problem->GetMatrix() ); Epetra_Vector *x = dynamic_cast<Epetra_Vector*>( d_linear_problem->GetLHS() ); const Epetra_Vector *b = dynamic_cast<Epetra_Vector*>( d_linear_problem->GetRHS() ); // Setup the residual. Epetra_Map row_map = A->RowMap(); Epetra_Vector residual( row_map ); // Iterate. Epetra_CrsMatrix H = buildH( A ); Epetra_Vector temp_vec( row_map ); d_num_iters = 0; double residual_norm = 1.0; double b_norm; b->NormInf( &b_norm ); double conv_crit = b_norm*tolerance; while ( residual_norm > conv_crit && d_num_iters < max_iters ) { H.Apply( *x, temp_vec ); x->Update( 1.0, temp_vec, 1.0, *b, 0.0 ); A->Apply( *x, temp_vec ); residual.Update( 1.0, *b, -1.0, temp_vec, 0.0 ); residual.NormInf( &residual_norm ); ++d_num_iters; } }
int build(const IntRect &sourceRect, const IntRect &destRect, Vertex *verts) { int ox = destRect.x; int oy = destRect.y; int width = destRect.w; int height = destRect.h; if (width <= 0 || height <= 0) return 0; int fullCount = height / sourceRect.h; int partSize = height % sourceRect.h; int rowTileCount = oneDimCount(sourceRect.w, width); int qCount = 0; int v = 0; for (int i = 0; i < fullCount; ++i) { qCount += buildH(sourceRect, width, ox, oy, &verts[v]); v += rowTileCount*4; oy += sourceRect.h; } if (partSize) { IntRect partSourceRect = sourceRect; partSourceRect.h = partSize; qCount += buildH(partSourceRect, width, ox, oy, &verts[v]); } return qCount; }
TEUCHOS_UNIT_TEST( MCSA, one_step_solve_test) { int N = 100; int problem_size = N*N; // Build the diffusion operator. double bc_val = 10.0; double dx = 0.01; double dy = 0.01; double dt = 0.01; double alpha = 0.01; HMCSA::DiffusionOperator diffusion_operator( 5, HMCSA::HMCSA_DIRICHLET, HMCSA::HMCSA_DIRICHLET, HMCSA::HMCSA_DIRICHLET, HMCSA::HMCSA_DIRICHLET, bc_val, bc_val, bc_val, bc_val, N, N, dx, dy, dt, alpha ); Teuchos::RCP<Epetra_CrsMatrix> A = diffusion_operator.getCrsMatrix(); Epetra_Map map = A->RowMap(); // Solution Vectors. std::vector<double> x_vector( problem_size ); Epetra_Vector x( View, map, &x_vector[0] ); std::vector<double> x_aztec_vector( problem_size ); Epetra_Vector x_aztec( View, map, &x_aztec_vector[0] ); // Build source - set intial and Dirichlet boundary conditions. std::vector<double> b_vector( problem_size, 1.0 ); int idx; for ( int j = 1; j < N-1; ++j ) { int i = 0; idx = i + j*N; b_vector[idx] = bc_val; } for ( int j = 1; j < N-1; ++j ) { int i = N-1; idx = i + j*N; b_vector[idx] = bc_val; } for ( int i = 0; i < N; ++i ) { int j = 0; idx = i + j*N; b_vector[idx] = bc_val; } for ( int i = 0; i < N; ++i ) { int j = N-1; idx = i + j*N; b_vector[idx] = bc_val; } Epetra_Vector b( View, map, &b_vector[0] ); // MCSA Linear problem. Teuchos::RCP<Epetra_LinearProblem> linear_problem = Teuchos::rcp( new Epetra_LinearProblem( A.getRawPtr(), &x, &b ) ); // MCSA Jacobi precondition. Teuchos::RCP<Epetra_CrsMatrix> H = buildH( A ); double spec_rad_H = HMCSA::OperatorTools::spectralRadius( H ); std::cout << std::endl << std::endl << "---------------------" << std::endl << "Iteration matrix spectral radius: " << spec_rad_H << std::endl; HMCSA::JacobiPreconditioner preconditioner( linear_problem ); preconditioner.precondition(); H = buildH( preconditioner.getOperator() ); double spec_rad_precond_H = HMCSA::OperatorTools::spectralRadius( H ); std::cout << "Preconditioned iteration matrix spectral radius: " << spec_rad_precond_H << std::endl << "---------------------" << std::endl; }