void projectPointsToPlane(const std::vector<CgalPoint>& points, const CgalPlane& plane, std::vector<CgalPoint2>& coords_2d) { CgalPoint origin = plane.projection(points[0]); CgalVector base1 = plane.base1(); CgalVector base2 = plane.base2(); base1 = base1 / std::sqrt(base1.squared_length()); base2 = base2 / std::sqrt(base2.squared_length()); CgalLine base_line1(origin, base1); CgalLine base_line2(origin, base2); for (size_t i = 0, iEnd = points.size(); i < iEnd; ++i) { CgalPoint point = plane.projection(points[i]); CgalVector x_vector(origin, base_line1.projection(point)); CgalVector y_vector(origin, base_line2.projection(point)); double x = std::sqrt(x_vector.squared_length()); double y = std::sqrt(y_vector.squared_length()); x = x_vector * base1 < 0 ? -x : x; y = y_vector * base2 < 0 ? -y : y; coords_2d.push_back(CgalPoint2(x, y)); } return; }
void chrobak_payne_straight_line_drawing(const Graph& g, PlanarEmbedding embedding, ForwardIterator ordering_begin, ForwardIterator ordering_end, GridPositionMap drawing, VertexIndexMap vm ) { typedef typename graph_traits<Graph>::vertex_descriptor vertex_t; typedef typename graph_traits<Graph>::edge_descriptor edge_t; typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator_t; typedef typename PlanarEmbedding::value_type::const_iterator edge_permutation_iterator_t; typedef typename graph_traits<Graph>::vertices_size_type v_size_t; typedef std::vector<vertex_t> vertex_vector_t; typedef std::vector<v_size_t> vsize_vector_t; typedef std::vector<bool> bool_vector_t; typedef boost::iterator_property_map <typename vertex_vector_t::iterator, VertexIndexMap> vertex_to_vertex_map_t; typedef boost::iterator_property_map <typename vsize_vector_t::iterator, VertexIndexMap> vertex_to_vsize_map_t; typedef boost::iterator_property_map <typename bool_vector_t::iterator, VertexIndexMap> vertex_to_bool_map_t; vertex_vector_t left_vector(num_vertices(g), graph_traits<Graph>::null_vertex() ); vertex_vector_t right_vector(num_vertices(g), graph_traits<Graph>::null_vertex() ); vsize_vector_t seen_as_right_vector(num_vertices(g), 0); vsize_vector_t seen_vector(num_vertices(g), 0); vsize_vector_t delta_x_vector(num_vertices(g),0); vsize_vector_t y_vector(num_vertices(g)); vsize_vector_t x_vector(num_vertices(g),0); bool_vector_t installed_vector(num_vertices(g),false); vertex_to_vertex_map_t left(left_vector.begin(), vm); vertex_to_vertex_map_t right(right_vector.begin(), vm); vertex_to_vsize_map_t seen_as_right(seen_as_right_vector.begin(), vm); vertex_to_vsize_map_t seen(seen_vector.begin(), vm); vertex_to_vsize_map_t delta_x(delta_x_vector.begin(), vm); vertex_to_vsize_map_t y(y_vector.begin(), vm); vertex_to_vsize_map_t x(x_vector.begin(), vm); vertex_to_bool_map_t installed(installed_vector.begin(), vm); v_size_t timestamp = 1; vertex_vector_t installed_neighbors; ForwardIterator itr = ordering_begin; vertex_t v1 = *itr; ++itr; vertex_t v2 = *itr; ++itr; vertex_t v3 = *itr; ++itr; delta_x[v2] = 1; delta_x[v3] = 1; y[v1] = 0; y[v2] = 0; y[v3] = 1; right[v1] = v3; right[v3] = v2; installed[v1] = installed[v2] = installed[v3] = true; for(ForwardIterator itr_end = ordering_end; itr != itr_end; ++itr) { vertex_t v = *itr; // First, find the leftmost and rightmost neighbor of v on the outer // cycle of the embedding. // Note: since we're moving clockwise through the edges adjacent to v, // we're actually moving from right to left among v's neighbors on the // outer face (since v will be installed above them all) looking for // the leftmost and rightmost installed neigbhors vertex_t leftmost = graph_traits<Graph>::null_vertex(); vertex_t rightmost = graph_traits<Graph>::null_vertex(); installed_neighbors.clear(); vertex_t prev_vertex = graph_traits<Graph>::null_vertex(); edge_permutation_iterator_t pi, pi_end; pi_end = embedding[v].end(); for(pi = embedding[v].begin(); pi != pi_end; ++pi) { vertex_t curr_vertex = source(*pi,g) == v ? target(*pi,g) : source(*pi,g); // Skip any self-loops or parallel edges if (curr_vertex == v || curr_vertex == prev_vertex) continue; if (installed[curr_vertex]) { seen[curr_vertex] = timestamp; if (right[curr_vertex] != graph_traits<Graph>::null_vertex()) { seen_as_right[right[curr_vertex]] = timestamp; } installed_neighbors.push_back(curr_vertex); } prev_vertex = curr_vertex; } typename vertex_vector_t::iterator vi, vi_end; vi_end = installed_neighbors.end(); for(vi = installed_neighbors.begin(); vi != vi_end; ++vi) { if (right[*vi] == graph_traits<Graph>::null_vertex() || seen[right[*vi]] != timestamp ) rightmost = *vi; if (seen_as_right[*vi] != timestamp) leftmost = *vi; } ++timestamp; //stretch gaps ++delta_x[right[leftmost]]; ++delta_x[rightmost]; //adjust offsets std::size_t delta_p_q = 0; vertex_t stopping_vertex = right[rightmost]; for(vertex_t temp = right[leftmost]; temp != stopping_vertex; temp = right[temp] ) { delta_p_q += delta_x[temp]; } delta_x[v] = ((y[rightmost] + delta_p_q) - y[leftmost])/2; y[v] = y[leftmost] + delta_x[v]; delta_x[rightmost] = delta_p_q - delta_x[v]; bool leftmost_and_rightmost_adjacent = right[leftmost] == rightmost; if (!leftmost_and_rightmost_adjacent) delta_x[right[leftmost]] -= delta_x[v]; //install v if (!leftmost_and_rightmost_adjacent) { left[v] = right[leftmost]; vertex_t next_to_rightmost; for(vertex_t temp = leftmost; temp != rightmost; temp = right[temp] ) { next_to_rightmost = temp; } right[next_to_rightmost] = graph_traits<Graph>::null_vertex(); } else { left[v] = graph_traits<Graph>::null_vertex(); } right[leftmost] = v; right[v] = rightmost; installed[v] = true; } graph::detail::accumulate_offsets (*ordering_begin,0,g,x,delta_x,left,right); vertex_iterator_t vi, vi_end; for(boost::tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) { vertex_t v(*vi); drawing[v].x = x[v]; drawing[v].y = y[v]; } }
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; }
//---------------------------------------------------------------------------// int main( int argc, char** argv ) { // Problem parameters. int xN = 201; int yN = 201; int problem_size = xN*yN; double x_min = 0.0; double x_max = 2.0; double y_min = 0.0; double y_max = 2.0; double ic_val = 0.0; double bc_val_xmin = 0.0; double bc_val_xmax = 0.0; double bc_val_ymin = 10.0; double bc_val_ymax = 10.0; int num_steps = 1; double T = 0.01; double dx = (x_max-x_min)/(xN-1); double dy = (y_max-y_min)/(yN-1); double dt = T / num_steps; double alpha = 0.01; int max_iters = 1000; double tolerance = 1.0e-8; int num_histories = 40000; double weight_cutoff = 1.0e-12; // Setup up a VTK mesh for output. HMCSA::VtkWriter vtk_writer( x_min, x_max, y_min, y_max, dx, dy, xN, yN ); // Build the Diffusion operator. HMCSA::DiffusionOperator diffusion_operator( 5, HMCSA::HMCSA_DIRICHLET, HMCSA::HMCSA_DIRICHLET, HMCSA::HMCSA_DIRICHLET, HMCSA::HMCSA_DIRICHLET, bc_val_xmin, bc_val_xmax, bc_val_ymin, bc_val_ymax, xN, yN, dx, dy, dt, alpha ); Teuchos::RCP<Epetra_CrsMatrix> A = diffusion_operator.getCrsMatrix(); Epetra_Map map = A->RowMap(); // Solution Vector. std::vector<double> x_vector( problem_size ); Epetra_Vector x( View, map, &x_vector[0] ); // Build source - set intial and Dirichlet boundary conditions. std::vector<double> b_vector( problem_size, ic_val ); buildIC( b_vector, xN, yN, bc_val_xmin, bc_val_xmax, bc_val_ymin, bc_val_ymax ); Epetra_Vector b( View, map, &b_vector[0] ); // Linear problem. Teuchos::RCP<Epetra_LinearProblem> linear_problem = Teuchos::rcp( new Epetra_LinearProblem( A.getRawPtr(), &x, &b ) ); // Time step. HMCSA::TimeIntegrator time_integrator( linear_problem, vtk_writer ); time_integrator.integrate( true, num_steps, max_iters, tolerance, num_histories, weight_cutoff ); return 0; }
TEUCHOS_UNIT_TEST( MCSA, MCSA_test) { int problem_size = 16; Epetra_SerialComm comm; Epetra_Map map( problem_size, 0, comm ); 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] ); std::vector<double> b_vector( problem_size, 0.4 ); Epetra_Vector b( View, map, &b_vector[0] ); Teuchos::RCP<Epetra_CrsMatrix> A = Teuchos::rcp( new Epetra_CrsMatrix( Copy, map, problem_size ) ); double lower_diag = -0.1; double diag = 2.4; double upper_diag = -0.1; int global_row = 0; int lower_row = 0; int upper_row = 0; for ( int i = 0; i < problem_size; ++i ) { global_row = A->GRID(i); lower_row = i-1; upper_row = i+1; if ( lower_row > -1 ) { A->InsertGlobalValues( global_row, 1, &lower_diag, &lower_row ); } A->InsertGlobalValues( global_row, 1, &diag, &global_row ); if ( upper_row < problem_size ) { A->InsertGlobalValues( global_row, 1, &upper_diag, &upper_row ); } } A->FillComplete(); double spec_rad_A = HMCSA::OperatorTools::spectralRadius( A ); std::cout << std::endl << "Operator spectral radius: " << spec_rad_A << std::endl; Teuchos::RCP<Epetra_LinearProblem> linear_problem = Teuchos::rcp( new Epetra_LinearProblem( A.getRawPtr(), &x, &b ) ); HMCSA::JacobiPreconditioner preconditioner( linear_problem ); preconditioner.precondition(); HMCSA::MCSA mcsa_solver( linear_problem ); mcsa_solver.iterate( 100, 1.0e-8, 100, 1.0e-8 ); std::cout << "MCSA ITERS: " << mcsa_solver.getNumIters() << std::endl; Epetra_LinearProblem aztec_linear_problem( A.getRawPtr(), &x_aztec, &b ); AztecOO aztec_solver( aztec_linear_problem ); aztec_solver.SetAztecOption( AZ_solver, AZ_gmres ); aztec_solver.Iterate( 100, 1.0e-8 ); std::vector<double> error_vector( problem_size ); Epetra_Vector error( View, map, &error_vector[0] ); for (int i = 0; i < problem_size; ++i) { error[i] = x[i] - x_aztec[i]; } double error_norm; error.Norm2( &error_norm ); std::cout << std::endl << "Aztec GMRES vs. MCSA absolute error L2 norm: " << error_norm << std::endl; }