예제 #1
0
파일: filters.hpp 프로젝트: LANTZT/feelpp
boost::tuple<mpl::size_t<MESH_ELEMENTS>,
      typename MeshTraits<MeshType>::marker_element_const_iterator,
      typename MeshTraits<MeshType>::marker_element_const_iterator>
      markedelements( MeshType const& mesh, flag_type flag, rank_type pid, mpl::bool_<true> )
{
    return markedelements( *mesh, flag, pid, mpl::bool_<false>() );
}
 void updateCinematicViscosity( vf::Expr<ExprT> const& __expr, std::string const& marker = "" )
 {
     if ( !M_fieldCinematicViscosity ) return;
     if ( marker.empty() )
         M_fieldCinematicViscosity->on(_range=elements(M_fieldCinematicViscosity->mesh()),_expr=__expr );
     else
         M_fieldCinematicViscosity->on(_range=markedelements(M_fieldCinematicViscosity->mesh(),marker),_expr=__expr );
 }
 void updateCinematicViscosity( std::string const& marker = "" )
 {
     std::string markerUsed = ( marker.empty() )? self_type::defaultMaterialName() : marker;
     M_cstCinematicViscosity[markerUsed] = this->cstMu(markerUsed)/this->cstRho(markerUsed);
     if ( M_fieldCinematicViscosity )
     {
         if ( marker.empty() )
             M_fieldCinematicViscosity->on(_range=elements(M_fieldCinematicViscosity->mesh()),
                                           _expr=idv(this->fieldMu())/idv(this->fieldRho()) );
         else
             M_fieldCinematicViscosity->on(_range=markedelements(M_fieldCinematicViscosity->mesh(),marker),
                                           _expr=idv(this->fieldMu())/idv(this->fieldRho()) );
     }
 }
PreconditionerBlockMS<space_type>::PreconditionerBlockMS(space_ptrtype Xh,             // (u)x(p)
                                                         ModelProperties model,        // model
                                                         std::string const& p,         // prefix
                                                         sparse_matrix_ptrtype AA, value_type relax )    // The matrix
    :
        M_backend(backend()),           // the backend associated to the PC
        M_Xh( Xh ),
        M_Vh( Xh->template functionSpace<0>() ), // Potential
        M_Qh( Xh->template functionSpace<1>() ), // Lagrange
        M_Vh_indices( M_Vh->nLocalDofWithGhost() ),
        M_Qh_indices( M_Qh->nLocalDofWithGhost() ),
        M_uin( M_backend->newVector( M_Vh )  ),
        M_uout( M_backend->newVector( M_Vh )  ),
        M_pin( M_backend->newVector( M_Qh )  ),
        M_pout( M_backend->newVector( M_Qh )  ),
        U( M_Xh, "U" ),
        M_mass(M_backend->newMatrix(M_Vh,M_Vh)),
        M_L(M_backend->newMatrix(M_Qh,M_Qh)),
        M_er( 1. ),
        M_model( model ),
        M_prefix( p ),
        M_prefix_11( p+".11" ),
        M_prefix_22( p+".22" ),
        u(M_Vh, "u"),
        ozz(M_Vh, "ozz"),
        zoz(M_Vh, "zoz"),
        zzo(M_Vh, "zzo"),
        M_ozz(M_backend->newVector( M_Vh )),
        M_zoz(M_backend->newVector( M_Vh )),
        M_zzo(M_backend->newVector( M_Vh )),
        X(M_Qh, "X"),
        Y(M_Qh, "Y"),
        Z(M_Qh, "Z"),
        M_X(M_backend->newVector( M_Qh )),
        M_Y(M_backend->newVector( M_Qh )),
        M_Z(M_backend->newVector( M_Qh )),
        phi(M_Qh, "phi"),
        M_relax(relax)
{
    tic();
    LOG(INFO) << "[PreconditionerBlockMS] setup starts";
    this->setMatrix( AA );
    this->setName(M_prefix);

    /* Indices are need to extract sub matrix */
    std::iota( M_Vh_indices.begin(), M_Vh_indices.end(), 0 );
    std::iota( M_Qh_indices.begin(), M_Qh_indices.end(), M_Vh->nLocalDofWithGhost() );

    M_11 = AA->createSubMatrix( M_Vh_indices, M_Vh_indices, true, true);

    /* Boundary conditions */
    BoundaryConditions M_bc = M_model.boundaryConditions();
    map_vector_field<FEELPP_DIM,1,2> m_dirichlet_u { M_bc.getVectorFields<FEELPP_DIM> ( "u", "Dirichlet" ) };
    map_scalar_field<2> m_dirichlet_p { M_bc.getScalarFields<2> ( "phi", "Dirichlet" ) };

    /* Compute the mass matrix (needed in first block, constant) */
    auto f2A = form2(_test=M_Vh, _trial=M_Vh, _matrix=M_mass);
    auto f1A = form1(_test=M_Vh);
    f2A = integrate(_range=elements(M_Vh->mesh()), _expr=inner(idt(u),id(u))); // M
    for(auto const & it : m_dirichlet_u )
    {
        LOG(INFO) << "Applying " << it.second << " on " << it.first << " for "<<M_prefix_11<<"\n";
        f2A += on(_range=markedfaces(M_Vh->mesh(),it.first), _expr=it.second,_rhs=f1A, _element=u, _type="elimination_symmetric");
    }
    
    /* Compute the L (= er * grad grad) matrix (the second block) */
    auto f2L = form2(_test=M_Qh,_trial=M_Qh, _matrix=M_L);
#if 0
    //If you want to manage the relative permittivity materials per material,
    //here is the entry to deal with.
    for(auto it : M_model.materials() )
    { 
        f2L += integrate(_range=markedelements(M_Qh->mesh(),marker(it)), _expr=M_er*inner(gradt(phi), grad(phi)));
    }
#else
    f2L += integrate(_range=elements(M_Qh->mesh()), _expr=M_er*inner(gradt(phi), grad(phi)));
#endif
    auto f1LQ = form1(_test=M_Qh);

    for(auto const & it : m_dirichlet_p)
    {
        LOG(INFO) << "Applying " << it.second << " on " << it.first << " for "<<M_prefix_22<<"\n";
        f2L += on(_range=markedfaces(M_Qh->mesh(),it.first),_element=phi, _expr=it.second, _rhs=f1LQ, _type="elimination_symmetric");
    }

    toc( "[PreconditionerBlockMS] setup done ", FLAGS_v > 0 );
}
void
TestInterpolationHCurl3D::testInterpolation( std::string one_element_mesh )
{
    //auto myexpr = unitX() + unitY() + unitZ() ; //(1,1,1)
    auto myexpr = vec( cst(1.), cst(1.), cst(1.));

    // one element mesh
    auto mesh_name = one_element_mesh + ".msh"; //create the mesh and load it
    fs::path mesh_path( mesh_name );

    mesh_ptrtype oneelement_mesh = loadMesh( _mesh=new mesh_type,
                                             _filename=mesh_name);

    // refined mesh (export)
    auto refine_level = std::floor(1 - math::log( 0.1 )); //Deduce refine level from meshSize (option)
    mesh_ptrtype mesh = loadMesh( _mesh=new mesh_type,
                                  _filename=mesh_name,
                                  _refine=( int )refine_level);

    space_ptrtype Xh = space_type::New( oneelement_mesh );

    std::vector<std::string> faces = {"yzFace","xyzFace","xyFace"};
    std::vector<std::string> edges = {"zAxis","yAxis","yzAxis","xyAxis","xzAxis","xAxis"};

    element_type U_h_int = Xh->element();
    element_type U_h_on = Xh->element();
    element_type U_h_on_boundary = Xh->element();

    submesh1d_ptrtype edgeMesh( new submesh1d_type );
    edgeMesh = createSubmesh(oneelement_mesh, boundaryedges(oneelement_mesh) ); //submesh of edges

    // Tangents on ref element
    auto t0 = vec(cst(0.),cst(0.),cst(-2.));
    auto t1 = vec(cst(0.),cst(2.),cst(0.));
    auto t2 = vec(cst(0.),cst(-2.),cst(2.));
    auto t3 = vec(cst(2.),cst(-2.),cst(0.));
    auto t4 = vec(cst(2.),cst(0.),cst(-2.));
    auto t5 = vec(cst(2.),cst(0.),cst(0.));

    // Jacobian of geometrical transforms
    std::string jac;
    if(mesh_path.stem().string() == "one-elt-ref-3d" || mesh_path.stem().string() == "one-elt-real-h**o-3d" )
        jac = "{1,0,0,0,1,0,0,0,1}:x:y:z";
    else if(mesh_path.stem().string() == "one-elt-real-rotx" )
        jac = "{1,0,0,0,0,-1,0,1,0}:x:y:z";
    else if(mesh_path.stem().string() == "one-elt-real-roty" )
        jac = "{0,0,1,0,1,0,-1,0,0}:x:y:z";
    else if(mesh_path.stem().string() == "one-elt-real-rotz" )
        jac = "{0,-1,0,1,0,0,0,0,1}:x:y:z";

    U_h_int(0) = integrate( markedelements(edgeMesh, edges[0]), trans(expr<3,3>(jac)*t0)*myexpr ).evaluate()(0,0);
    U_h_int(1) = integrate( markedelements(edgeMesh, edges[1]), trans(expr<3,3>(jac)*t1)*myexpr ).evaluate()(0,0);
    U_h_int(2) = integrate( markedelements(edgeMesh, edges[2]), trans(expr<3,3>(jac)*t2)*myexpr ).evaluate()(0,0);
    U_h_int(3) = integrate( markedelements(edgeMesh, edges[3]), trans(expr<3,3>(jac)*t3)*myexpr ).evaluate()(0,0);
    U_h_int(4) = integrate( markedelements(edgeMesh, edges[4]), trans(expr<3,3>(jac)*t4)*myexpr ).evaluate()(0,0);
    U_h_int(5) = integrate( markedelements(edgeMesh, edges[5]), trans(expr<3,3>(jac)*t5)*myexpr ).evaluate()(0,0);

    for(int i=0; i<edges.size(); i++)
        {
            double edgeLength = integrate( markedelements(edgeMesh, edges[i]), cst(1.) ).evaluate()(0,0);
            U_h_int(i) /= edgeLength;
        }

#if 0 //Doesn't work for now
    for(int i=0; i<Xh->nLocalDof(); i++)
        {
            CHECK( edgeMesh->hasMarkers( {edges[i]} ) );
            U_h_int(i) = integrate( markedelements(edgeMesh, edges[i]), trans( print(T(),"T=") )*myexpr ).evaluate()(0,0);
            std::cout << "U_h_int(" << i << ")= " << U_h_int(i) << std::endl;
        }
#endif

    // nedelec interpolant using on keyword
    // interpolate on element
    U_h_on.zero();
    U_h_on.on(_range=elements(oneelement_mesh), _expr=myexpr);
    U_h_on_boundary.on(_range=boundaryfaces(oneelement_mesh), _expr=myexpr);

    auto exporter_proj = exporter( _mesh=mesh, _name=( boost::format( "%1%" ) % this->about().appName() ).str() );
    exporter_proj->step( 0 )->add( "U_interpolation_handly_"+mesh_path.stem().string(), U_h_int );
    exporter_proj->step( 0 )->add( "U_interpolation_on_"+mesh_path.stem().string(), U_h_on );
    exporter_proj->save();

    // print coefficient only for reference element
    U_h_int.printMatlab( "U_h_int_" + mesh_path.stem().string() + ".m" );
    U_h_on.printMatlab( "U_h_on_" + mesh_path.stem().string() + ".m" );
    U_h_on_boundary.printMatlab( "U_h_on_boundary_" + mesh_path.stem().string() + ".m" );

    //L2 norm of error
    auto error = vf::project(_space=Xh, _range=elements(oneelement_mesh), _expr=idv(U_h_int) - idv(U_h_on) );
    double L2error = error.l2Norm();
    std::cout << "L2 error (elements) = " << L2error << std::endl;

    auto error_boundary = vf::project(_space=Xh, _range=elements(oneelement_mesh), _expr=idv(U_h_int) - idv(U_h_on_boundary) );
    double L2error_boundary = error_boundary.l2Norm();
    std::cout << "L2 error (boundary) = " << L2error_boundary << std::endl;
    BOOST_CHECK_SMALL( L2error_boundary - L2error, 1e-13 );
}
void
ThermalBlockMinimalVersion::initModel()
{

    gamma_dir=option(_name="gamma_dir").template as<double>();

    this->setFunctionSpaces( Pch<1>( loadMesh( _mesh=new Mesh<Simplex<2>> ) ) );

    auto mesh = Xh->mesh();

    if( Environment::worldComm().isMasterRank() )
    {
        std::cout << "Number of local dof " << Xh->nLocalDof() << "\n";
        std::cout << "Number of dof " << Xh->nDof() << "\n";
    }

    auto mu_min = Dmu->element();
    auto mu_max = Dmu->element();
    mu_min <<  0.1 , 0.1 , 0.1 , 0.1 , 0.1 , 0.1 , 0.1 , 0.1 ;
    mu_max <<  10 , 10 , 10 , 10 , 10 , 10 , 10 , 10 ;
    Dmu->setMin( mu_min );
    Dmu->setMax( mu_max );

    auto u = Xh->element();
    auto v = Xh->element();

    auto M = backend()->newMatrix( Xh , Xh );

    double mu_min_coeff=0.1;
    // on boundary north we have u=0 so term from weak dirichlet condition
    // vanish in the right hand side
    //rhs
    auto f0 = form1( _test=Xh );
    f0 =  integrate( _range=markedfaces( mesh,"south_domain-1" ), _expr= id( v ) )
        + integrate( _range=markedfaces( mesh,"south_domain-2" ), _expr= id( v ) )
        + integrate( _range=markedfaces( mesh,"south_domain-3" ), _expr= id( v ) );
    this->addRhs( { f0, "1" } );

    //lhs
    auto a0 = form2( _trial=Xh, _test=Xh);
    a0 = integrate( markedelements( mesh, "domain-1" ), gradt( u )*trans( grad( v ) ) );
    this->addLhs( { a0 , "1" } );
    auto a1 = form2( _trial=Xh, _test=Xh);
    a1 = integrate( markedelements( mesh, "domain-2" ), gradt( u )*trans( grad( v ) ) );
    this->addLhs( { a1 , "mu0" } );
    auto a2 = form2( _trial=Xh, _test=Xh);
    a2 = integrate( markedelements( mesh, "domain-3" ), gradt( u )*trans( grad( v ) ) );
    this->addLhs( { a2 , "mu1" } );
    auto a3 = form2( _trial=Xh, _test=Xh);
    a3 = integrate( markedelements( mesh, "domain-4" ), gradt( u )*trans( grad( v ) ) );
    this->addLhs( { a3 , "mu2" } );
    auto a4 = form2( _trial=Xh, _test=Xh);
    a4 = integrate( markedelements( mesh, "domain-5" ), gradt( u )*trans( grad( v ) ) );
    this->addLhs( { a4 , "mu3" } );
    auto a5 = form2( _trial=Xh, _test=Xh);
    a5 = integrate( markedelements( mesh, "domain-6" ), gradt( u )*trans( grad( v ) ) );
    this->addLhs( { a5 , "mu4" } );
    auto a6 = form2( _trial=Xh, _test=Xh);
    a6 = integrate( markedelements( mesh, "domain-7" ), gradt( u )*trans( grad( v ) ) )
        +integrate( markedfaces( mesh, "north_domain-7" ),
                   -gradt( u )*vf::N()*id( v )
                   -grad( u )*vf::N()*idt( v )
                   );
    this->addLhs( { a6 , "mu5" } );
    auto a7 = form2( _trial=Xh, _test=Xh);
    a7 = integrate( markedelements( mesh, "domain-8" ), gradt( u )*trans( grad( v ) ) )
        +integrate( markedfaces( mesh, "north_domain-8" ),
                   -gradt( u )*vf::N()*id( v )
                   -grad( u )*vf::N()*idt( v )
                   );
    this->addLhs( { a7 , "mu6" } );
    auto a8 = form2( _trial=Xh, _test=Xh);
    a8 = integrate( markedelements( mesh, "domain-9" ), gradt( u )*trans( grad( v ) ) )
        +integrate( markedfaces( mesh, "north_domain-9" ),
                   -gradt( u )*vf::N()*id( v )
                   -grad( u )*vf::N()*idt( v )
                   );
    this->addLhs( { a8 , "mu7" } );
    auto a9 = form2( _trial=Xh, _test=Xh);
    a9 = integrate( markedfaces( mesh, "north_domain-7" ),gamma_dir*idt( u )*id( v )/h() )
        +integrate( markedfaces( mesh, "north_domain-8" ),gamma_dir*idt( u )*id( v )/h() )
        +integrate( markedfaces( mesh, "north_domain-9" ),gamma_dir*idt( u )*id( v )/h() );
    this->addLhs( { a9 , "1" } );


    form2( Xh, Xh, M ) = integrate( markedelements( mesh, "domain-1" ), gradt( u )*trans( grad( v ) )  );
    form2( Xh, Xh, M ) += integrate( markedelements( mesh, "domain-2" ), gradt( u )*trans( grad( v ) ) * mu_min_coeff );
    form2( Xh, Xh, M ) += integrate( markedelements( mesh, "domain-3" ), gradt( u )*trans( grad( v ) ) * mu_min_coeff );
    form2( Xh, Xh, M ) += integrate( markedelements( mesh, "domain-4" ), gradt( u )*trans( grad( v ) ) * mu_min_coeff );
    form2( Xh, Xh, M ) += integrate( markedelements( mesh, "domain-5" ), gradt( u )*trans( grad( v ) ) * mu_min_coeff );
    form2( Xh, Xh, M ) += integrate( markedelements( mesh, "domain-6" ), gradt( u )*trans( grad( v ) ) * mu_min_coeff );
    form2( Xh, Xh, M ) += integrate( markedelements( mesh, "domain-7" ), gradt( u )*trans( grad( v ) ) * mu_min_coeff );
    form2( Xh, Xh, M ) += integrate( markedelements( mesh, "domain-8" ), gradt( u )*trans( grad( v ) ) * mu_min_coeff );
    form2( Xh, Xh, M ) += integrate( markedelements( mesh, "domain-9" ), gradt( u )*trans( grad( v ) ) * mu_min_coeff );
    form2( Xh, Xh, M ) +=  integrate( markedfaces( mesh, "north_domain-7" ),
                                      -gradt( u )*vf::N()*id( v ) * mu_min_coeff
                                      -grad( u )*vf::N()*idt( v ) * mu_min_coeff
                                      );
    form2( Xh, Xh, M ) +=  integrate( markedfaces( mesh, "north_domain-8" ),
                                      -gradt( u )*vf::N()*id( v ) * mu_min_coeff
                                      -grad( u )*vf::N()*idt( v ) * mu_min_coeff
                                      );
    form2( Xh, Xh, M ) +=  integrate( markedfaces( mesh, "north_domain-9" ),
                                      -gradt( u )*vf::N()*id( v ) * mu_min_coeff
                                      -grad( u )*vf::N()*idt( v ) * mu_min_coeff
                                      );
    form2( Xh, Xh, M ) += integrate( markedfaces( mesh, "north_domain-7" ),gamma_dir*idt( u )*id( v )/h() );
    form2( Xh, Xh, M ) += integrate( markedfaces( mesh, "north_domain-8" ),gamma_dir*idt( u )*id( v )/h() );
    form2( Xh, Xh, M ) += integrate( markedfaces( mesh, "north_domain-9" ),gamma_dir*idt( u )*id( v )/h() );
    this->addEnergyMatrix( M );

}//initModel()
예제 #7
0
PreconditionerBlockMS<space_type>::PreconditionerBlockMS(space_ptrtype Xh,             // (u)x(p)
                                                         ModelProperties model,        // model
                                                         std::string const& p,         // prefix
                                                         sparse_matrix_ptrtype AA )    // The matrix
    :
        M_backend(backend()),           // the backend associated to the PC
        M_Xh( Xh ),
        M_Vh( Xh->template functionSpace<0>() ), // Potential
        M_Qh( Xh->template functionSpace<1>() ), // Lagrange
        M_Vh_indices( M_Vh->nLocalDofWithGhost() ),
        M_Qh_indices( M_Qh->nLocalDofWithGhost() ),
        M_uin( M_backend->newVector( M_Vh )  ),
        M_uout( M_backend->newVector( M_Vh )  ),
        M_pin( M_backend->newVector( M_Qh )  ),
        M_pout( M_backend->newVector( M_Qh )  ),
        U( M_Xh, "U" ),
        M_mass(M_backend->newMatrix(M_Vh,M_Vh)),
        M_L(M_backend->newMatrix(M_Qh,M_Qh)),
        M_er( 1. ),
        M_model( model ),
        M_prefix( p ),
        M_prefix_11( p+".11" ),
        M_prefix_22( p+".22" ),
        u(M_Vh, "u"),
        ozz(M_Vh, "ozz"),
        zoz(M_Vh, "zoz"),
        zzo(M_Vh, "zzo"),
        M_ozz(M_backend->newVector( M_Vh )),
        M_zoz(M_backend->newVector( M_Vh )),
        M_zzo(M_backend->newVector( M_Vh )),
        X(M_Qh, "X"),
        Y(M_Qh, "Y"),
        Z(M_Qh, "Z"),
        M_X(M_backend->newVector( M_Qh )),
        M_Y(M_backend->newVector( M_Qh )),
        M_Z(M_backend->newVector( M_Qh )),
        phi(M_Qh, "phi")
{
    tic();
    LOG(INFO) << "[PreconditionerBlockMS] setup starts";
    this->setMatrix( AA );
    this->setName(M_prefix);

    /* Indices are need to extract sub matrix */
    std::iota( M_Vh_indices.begin(), M_Vh_indices.end(), 0 );
    std::iota( M_Qh_indices.begin(), M_Qh_indices.end(), M_Vh->nLocalDofWithGhost() );

    M_11 = AA->createSubMatrix( M_Vh_indices, M_Vh_indices, true, true);

    /* Boundary conditions */
    BoundaryConditions M_bc = M_model.boundaryConditions();
    map_vector_field<FEELPP_DIM,1,2> m_dirichlet_u { M_bc.getVectorFields<FEELPP_DIM> ( "u", "Dirichlet" ) };
    map_scalar_field<2> m_dirichlet_p { M_bc.getScalarFields<2> ( "phi", "Dirichlet" ) };

    /* Compute the mass matrix (needed in first block, constant) */
    auto f2A = form2(_test=M_Vh, _trial=M_Vh, _matrix=M_mass);
    auto f1A = form1(_test=M_Vh);
    f2A = integrate(_range=elements(M_Vh->mesh()), _expr=inner(idt(u),id(u))); // M
    for(auto const & it : m_dirichlet_u )
    {
        LOG(INFO) << "Applying " << it.second << " on " << it.first << " for "<<M_prefix_11<<"\n";
        f2A += on(_range=markedfaces(M_Vh->mesh(),it.first), _expr=it.second,_rhs=f1A, _element=u, _type="elimination_symmetric");
    }
    
    /* Compute the L (= er * grad grad) matrix (the second block) */
    auto f2L = form2(_test=M_Qh,_trial=M_Qh, _matrix=M_L);
    for(auto it : M_model.materials() )
    { 
        f2L += integrate(_range=markedelements(M_Qh->mesh(),marker(it)), _expr=M_er*inner(gradt(phi), grad(phi)));
    }
    auto f1LQ = form1(_test=M_Qh);

    for(auto const & it : m_dirichlet_p)
    {
        LOG(INFO) << "Applying " << it.second << " on " << it.first << " for "<<M_prefix_22<<"\n";
        f2L += on(_range=markedfaces(M_Qh->mesh(),it.first),_element=phi, _expr=it.second, _rhs=f1LQ, _type="elimination_symmetric");
    }


    if(soption(_name="pc-type", _prefix=M_prefix_11) == "ams")
#if FEELPP_DIM == 3
    {
        M_grad  = Grad( _domainSpace=M_Qh, _imageSpace=M_Vh);

        // This preconditioner is linked to that backend : the backend will
        // automatically use the preconditioner.
        auto prec = preconditioner(_pc=pcTypeConvertStrToEnum(soption(M_prefix_11+".pc-type")),
                                   _backend=backend(_name=M_prefix_11),
                                   _prefix=M_prefix_11,
                                   _matrix=M_11
                                  );
        prec->setMatrix(M_11);
        prec->attachAuxiliarySparseMatrix("G",M_grad.matPtr());
        if(boption(M_prefix_11+".useEdge"))
        {
            LOG(INFO) << "[ AMS ] : using SetConstantEdgeVector \n";
            ozz.on(_range=elements(M_Vh->mesh()),_expr=vec(cst(1),cst(0),cst(0)));
            zoz.on(_range=elements(M_Vh->mesh()),_expr=vec(cst(0),cst(1),cst(0)));
            zzo.on(_range=elements(M_Vh->mesh()),_expr=vec(cst(0),cst(0),cst(1)));
            *M_ozz = ozz; M_ozz->close();
            *M_zoz = zoz; M_zoz->close();
            *M_zzo = zzo; M_zzo->close();

            prec->attachAuxiliaryVector("Px",M_ozz);
            prec->attachAuxiliaryVector("Py",M_zoz);
            prec->attachAuxiliaryVector("Pz",M_zzo);
        }
        else
        {
            LOG(INFO) << "[ AMS ] : using SetCoordinates \n";
            X.on(_range=elements(M_Vh->mesh()),_expr=Px());
            Y.on(_range=elements(M_Vh->mesh()),_expr=Py());
            Z.on(_range=elements(M_Vh->mesh()),_expr=Pz());
            *M_X = X; M_X->close();
            *M_Y = Y; M_Y->close();
            *M_Z = Z; M_Z->close();
            prec->attachAuxiliaryVector("X",M_X);
            prec->attachAuxiliaryVector("Y",M_Y);
            prec->attachAuxiliaryVector("Z",M_Z);
        }
    }
#else
    std::cerr << "ams preconditioner is not interfaced in two dimensions\n";
#endif
    toc( "[PreconditionerBlockMS] setup done ", FLAGS_v > 0 );
}