Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
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();
 }
Ejemplo n.º 3
0
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;
}