amg(const Matrix &M, const params &p = params()) : prm(p) { precondition( backend::rows(M) == backend::cols(M), "Matrix should be square!" ); boost::shared_ptr<build_matrix> P, R; boost::shared_ptr<build_matrix> A = boost::make_shared<build_matrix>( M ); sort_rows(*A); while( backend::rows(*A) > prm.coarse_enough) { TIC("transfer operators"); boost::tie(P, R) = Coarsening::transfer_operators( *A, prm.coarsening); precondition( backend::cols(*P) > 0, "Zero-sized coarse level in amgcl (diagonal matrix?)" ); TOC("transfer operators"); TIC("move to backend") levels.push_back( level(A, P, R, prm) ); TOC("move to backend") TIC("coarse operator"); A = Coarsening::coarse_operator(*A, *P, *R, prm.coarsening); sort_rows(*A); TOC("coarse operator"); } TIC("coarsest level"); levels.push_back( level(A, prm, levels.empty()) ); TOC("coarsest level"); }
void BLOCK::compress() { // squash it up #define ROW_SPACING 5 ROW_IT row_it(&rows); ROW *row; ICOORD row_spacing (0, ROW_SPACING); ICOORDELT_IT icoordelt_it; sort_rows(); box = TBOX (box.topleft (), box.topleft ()); box.move_bottom_edge (ROW_SPACING); for (row_it.mark_cycle_pt (); !row_it.cycled_list (); row_it.forward ()) { row = row_it.data (); row->move (box.botleft () - row_spacing - row->bounding_box ().topleft ()); box += row->bounding_box (); } leftside.clear (); icoordelt_it.set_to_list (&leftside); icoordelt_it.add_to_end (new ICOORDELT (box.left (), box.bottom ())); icoordelt_it.add_to_end (new ICOORDELT (box.left (), box.top ())); rightside.clear (); icoordelt_it.set_to_list (&rightside); icoordelt_it.add_to_end (new ICOORDELT (box.right (), box.bottom ())); icoordelt_it.add_to_end (new ICOORDELT (box.right (), box.top ())); }
amg( const Matrix &M, const params &p = params(), const backend_params &bprm = backend_params() ) : prm(p) { boost::shared_ptr<build_matrix> A = boost::make_shared<build_matrix>(M); sort_rows(*A); init(A, bprm); }
static std::shared_ptr< backend::crs<Val, Col, Ptr> > restriction( const AMatrix &A, const std::vector<Val> &Adia, const backend::crs<Val, Col, Ptr> &P_tent, const std::vector<Val> &omega ) { const size_t nc = cols(P_tent); auto R_tent = transpose(P_tent); sort_rows(*R_tent); auto RA = product(*R_tent, A, /*sort rows: */true); // Compute R = R_tent - Omega R_tent A D^-1. /* * Here we use the fact that if R(i,j) != 0, * then with necessity RA(i,j) != 0: * * RA(i,j) = sum_k(R_ik A_kj), and A_jj != 0. */ #pragma omp parallel for for(ptrdiff_t i = 0; i < static_cast<ptrdiff_t>(nc); ++i) { Val w = omega[i]; for(Ptr ja = RA->ptr[i], ea = RA->ptr[i+1], jr = R_tent->ptr[i], er = R_tent->ptr[i+1]; ja < ea; ++ja ) { Col ca = RA->col[ja]; Val va = -w * math::inverse(Adia[ca]) * RA->val[ja]; for(; jr < er; ++jr) { Col cr = R_tent->col[jr]; if (cr > ca) break; if (cr == ca) { va += R_tent->val[jr]; break; } } RA->val[ja] = va; } } return RA; }
virtual void on_column_click( dom::element& table, dom::element& header_cell ) { super::on_column_click( table, header_cell ); dom::element current = table.find_first("th:checked"); if( current == header_cell ) return; // already here, nothing to do. if( current.is_valid() ) current.set_state(0, STATE_CHECKED); header_cell.set_state(STATE_CHECKED); dom::element ctr = get_current_row( table ); sort_rows( table, header_cell.index() ); if( ctr.is_valid() ) ctr.scroll_to_view(); }