int PreconditionerBlockMS<space_type>::applyInverse ( const vector_type& X, vector_type& Y ) const { tic(); U = X; U.close(); *M_uin = U.template element<0>(); M_uin->close(); *M_pin = U.template element<1>(); M_pin->close(); // Solve eq (12) // solve here eq 15 : Pm v = c backend(_name=M_prefix_11)->solve(_matrix=M_11, _rhs=M_uin, _solution=M_uout ) ; M_uout->close(); // solve here eq 16 backend(_name=M_prefix_22)->solve(_matrix=M_L, _rhs=M_pin, _solution=M_pout ); M_pout->close(); U.template element<0>() = *M_uout; U.template element<1>() = *M_pout; U.close(); Y=U; Y.close(); toc("[PreconditionerBlockMS] applyInverse update solution",FLAGS_v>0); return 0; }
void prod( sparse_matrix_type const& A, vector_type const& x, vector_type& b ) const { int ierr = 0; petsc_sparse_matrix_type const& _A = dynamic_cast<petsc_sparse_matrix_type const&>( A ); petsc_vector_type const& _x = dynamic_cast<petsc_vector_type const&>( x ); petsc_vector_type const& _b = dynamic_cast<petsc_vector_type const&>( b ); if ( _A.mapCol().worldComm().globalSize() == x.map().worldComm().globalSize() ) { //std::cout << "BackendPetsc::prod STANDART"<< std::endl; ierr = MatMult( _A.mat(), _x.vec(), _b.vec() ); CHKERRABORT( _A.comm().globalComm(),ierr ); } else { //std::cout << "BackendPetsc::prod with convert"<< std::endl; auto x_convert = petscMPI_vector_type(_A.mapColPtr()); x_convert.duplicateFromOtherPartition(x); x_convert.close(); ierr = MatMult( _A.mat(), x_convert.vec(), _b.vec() ); CHKERRABORT( _A.comm().globalComm(),ierr ); } b.close(); }
int PreconditionerAS<space_type,coef_space_type>::applyInverse ( const vector_type& X /*R*/, vector_type& Y /*W*/) const { /* * We solve Here P_v w = r * With P_v^-1 = diag(P_m)^-1 (=A) * + P (\bar L + g \bar Q) P^t (=B) * + C (L^-1) C^T (=C) */ U = X; U.close(); // solve equ (12) if ( this->type() == AS ) { tic(); *M_r = U; M_r->close(); // step A : diag(Pm)^-1*r A->pointwiseDivide(*M_r,*M_diagPm); A->close(); // s = P^t r M_Pt->multVector(M_r,M_s); // Impose boundary conditions on M_s #if 1 M_qh3_elt = *M_s; M_qh3_elt.close(); #if FEELPP_DIM == 3 M_qh3_elt.on( _range=boundaryfaces( M_Qh3->mesh() ), _expr=vec(cst(0.), cst(0.), cst(0.)) ); #else M_qh3_elt.on( _range=boundaryfaces( M_Qh3->mesh() ), _expr=vec(cst(0.), cst(0.)) ); #endif *M_s = M_qh3_elt; M_s->close(); #endif #if 1 // Subvectors for M_s (per component) need to be updated M_s1 = M_s->createSubVector(M_Qh3_indices[0], true); M_s2 = M_s->createSubVector(M_Qh3_indices[1], true); #if FEELPP_DIM == 3 M_s3 = M_s->createSubVector(M_Qh3_indices[2], true); #endif #else // s = [ s1, s2, s3 ] M_s->updateSubVector(M_s1, M_Qh3_indices[0]); M_s->updateSubVector(M_s2, M_Qh3_indices[1]); #if FEELPP_DIM == 3 M_s->updateSubVector(M_s3, M_Qh3_indices[2]); #endif #endif M_s->close(); /* * hat(L) + g Q is a (Qh,Qh) matrix * [[ hat(L) + g Q, 0 , 0 ], [ y1 ] [ s1 ] * [ 0, hat(L) + g Q, 0 ], * [ y2 ] = [ s2 ] * [ 0, 0 , hat(L) + g Q ]] [ y3 ] [ s3 ] */ M_lgqOp->applyInverse(M_s1,M_y1); M_lgqOp->applyInverse(M_s2,M_y2); #if FEELPP_DIM == 3 M_lgqOp->applyInverse(M_s3,M_y3); #endif // y = [ y1, y2, y3 ] M_y->updateSubVector(M_y1, M_Qh3_indices[0]); M_y->updateSubVector(M_y2, M_Qh3_indices[1]); #if FEELPP_DIM == 3 M_y->updateSubVector(M_y3, M_Qh3_indices[2]); #endif M_y->close(); // step B : P*y M_P->multVector(M_y,B); // Impose boundary conditions on B = Py #if 1 M_vh_elt = *B; M_vh_elt.close(); #if FEELPP_DIM == 3 M_vh_elt.on( _range=boundaryfaces( M_Qh3->mesh() ), _expr=vec(cst(0.), cst(0.), cst(0.)) ); #else M_vh_elt.on( _range=boundaryfaces( M_Qh3->mesh() ), _expr=vec(cst(0.), cst(0.)) ); #endif *B = M_vh_elt; B->close(); #endif // t = C^t r M_Ct->multVector(M_r,M_t); // Impose boundary conditions on M_t #if 1 M_qh_elt = *M_t; M_qh_elt.close(); M_qh_elt.on( _range=boundaryfaces( M_Qh3->mesh() ), _expr=cst(0.) ); *M_t = M_qh_elt; M_t->close(); #endif // 14.b : hat(L) z = t M_lOp->applyInverse(M_t,M_z); M_z->close(); // step C : M_C z M_C->multVector(M_z,C); C->scale(1./M_g); // Impose boundary conditions on C = Cz #if 1 M_vh_elt = *C; M_vh_elt.close(); #if FEELPP_DIM == 3 M_vh_elt.on( _range=boundaryfaces( M_Qh3->mesh() ), _expr=vec(cst(0.), cst(0.), cst(0.)) ); #else M_vh_elt.on( _range=boundaryfaces( M_Qh3->mesh() ), _expr=vec(cst(0.), cst(0.)) ); #endif *C = M_vh_elt; C->close(); #endif //if(M_g != 1.0) A->add(*C); A->add(*B); C->close(); B->close(); A->close(); toc("assemble preconditioner AS",FLAGS_v>0); *M_uout = *A; // 15 : w = A + B + C } else if( this->type() == SIMPLE ) { SimpleOp->applyInverse(X, Y); *M_uout = Y; } else { Y=U; *M_uout = Y; } M_uout->close(); tic(); Y=*M_uout; Y.close(); toc("PreconditionerAS::applyInverse", FLAGS_v>0 ); return 0; }