Beispiel #1
0
static inline void assemble(boost::shared_ptr<Mesh<Simplex<Dim>>>& mesh, double* vec) {
    boost::timer time;
    auto Vh = FunctionSpace<Mesh<Simplex<Dim>>, bases<Lagrange<Order, Type>>>::New(_mesh = mesh);
    vec[2] = time.elapsed();
    vec[1] = Vh->nDof();
    Environment::logMemoryUsage( "Assemble Laplacian Memory Usage: FunctionSpace" );
    time.restart();
    auto v = Vh->element();
    auto f = backend()->newVector(Vh);
    auto l = form1(_test = Vh, _vector = f);
    l = integrate(_range = elements(mesh), _expr = id(v));

    vec[4] = time.elapsed();
    Environment::logMemoryUsage( "Assemble Laplacian Memory Usage: Form1" );
    time.restart();
    auto u = Vh->element();
    auto A = backend()->newMatrix(Vh, Vh);
    vec[5] = time.elapsed();
    Environment::logMemoryUsage( "Assemble Laplacian Memory Usage: Matrix" );
    time.restart();
    auto a = form2(_trial = Vh, _test = Vh, _matrix = A);
    a = integrate(_range = elements(mesh), _expr = inner(gradt(u),grad(v)));
    a += on(_range = markedfaces(mesh, "Dirichlet"), _rhs = l, _element = u, _expr = cst(0.0));
    vec[3] = time.elapsed();
    auto mem = Environment::logMemoryUsage( "Assemble Laplacian Memory Usage: form2" );
    v[6] = mem.memory_usage/1e9;
    LOG(INFO) << "v[6] = " << v[6];
    cleanup();
}
Beispiel #2
0
boost::tuple<mpl::size_t<MESH_FACES>,
      typename MeshTraits<MeshType>::marker_face_const_iterator,
      typename MeshTraits<MeshType>::marker_face_const_iterator>
      markedfaces( MeshType const& mesh, rank_type __pid, mpl::bool_<true> )
{
    return markedfaces( *mesh, __pid, mpl::bool_<false>() );
}
void
TestInterpolationHDiv<Dim>::testInterpolationOneElt( std::string one_element_mesh )
{
    // expr to interpolate
    int is3D = 0;
    if( Dim == 3 )
        is3D = 1;

    auto myexpr = unitX() + unitY() + is3D*unitZ() ; //(1,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::cout << "nb dof = " << Xh->nDof() << std::endl;

    std::vector<std::string> faces;
    if(Dim == 2)
        faces = { "hypo","vert","hor"};
    else if (Dim == 3)
        faces = {"xzFace","xyFace","xyzFace","yzFace"};

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

    // handly computed interpolant coeff (in hdiv basis)
    for ( int i = 0; i < Xh->nLocalDof(); ++i )
        {
            CHECK( mesh->hasMarkers( {faces[i]} ) );
            U_h_int(i) = integrate( markedfaces( oneelement_mesh, faces[i] ), trans( N() )*myexpr ).evaluate()(0,0);
        }

    // raviart-thomas interpolant using on
    U_h_on.zero();
    U_h_on.on(_range=elements(oneelement_mesh), _expr=myexpr);

    auto exporter_proj = exporter( _mesh=mesh, _name=( boost::format( "%1%-%2%" ) % this->about().appName() %mesh_path.stem().string() ).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();

    U_h_int.printMatlab( "U_h_int_" + mesh_path.stem().string() + ".m" );
    U_h_on.printMatlab( "U_h_on_" + 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  = " << L2error << std::endl;
}
void
TestInterpolationHCurl::testInterpolation( std::string one_element_mesh )
{
    // expr to interpolate
    auto myexpr = unitX() + unitY(); //(1,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, edges; //list of edges
    edges = {"hypo","vert","hor"};

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

    // handly computed interpolant coeff (in hcurl basis)
    for ( int i = 0; i < Xh->nLocalDof(); ++i )
        {
            CHECK( oneelement_mesh->hasMarkers( {edges[i]} ) );
            U_h_int(i) = integrate( markedfaces( oneelement_mesh, edges[i] ), trans( T() )*myexpr ).evaluate()(0,0);
        }

    // nedelec interpolant using on
    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=boundaryfaces(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
PreconditionerBlockMS<space_type>::init( void )
{
    if( Environment::worldComm().isMasterRank() )
        std::cout << "Init preconditioner blockms\n";
    LOG(INFO) << "Init ...\n";
    tic();
    BoundaryConditions M_bc = M_model.boundaryConditions();

    LOG(INFO) << "Create sub Matrix\n";
    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" ) };

    /*
     * AA = [[ A - k^2 M, B^t],
     *      [ B        , 0  ]]
     * We need to extract A-k^2 M and add it M to form A+(1-k^2) M = A+g M
     */
    // Is the zero() necessary ?
    M_11->zero();
    this->matrix()->updateSubMatrix(M_11, M_Vh_indices, M_Vh_indices, false); // M_11 = A-k^2 M
    LOG(INFO) << "Use relax = " << M_relax << std::endl;
    M_11->addMatrix(M_relax,M_mass);                            // A-k^2 M + M_relax*M = A+(M_relax-k^2) M
    auto f2A = form2(_test=M_Vh, _trial=M_Vh,_matrix=M_11);
    auto f1A = form1(_test=M_Vh);
    for(auto const & it : m_dirichlet_u )
        f2A += on(_range=markedfaces(M_Vh->mesh(),it.first), _expr=it.second,_rhs=f1A, _element=u, _type="elimination_symmetric");

    /* 
     * Rebuilding sub-backend
     */
    backend(_name=M_prefix_11, _rebuild=true);
    backend(_name=M_prefix_22, _rebuild=true);
    // We have to set the G, Px,Py,Pz or X,Y,Z matrices to AMS
    if(soption(_name="pc-type", _prefix=M_prefix_11) == "ams")
    {
#if FEELPP_DIM == 3
    initAMS();
    {
        if(boption(_name="setAlphaBeta",_prefix=M_prefix_11))
        {
            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("a_alpha",M_a_alpha);
            prec->attachAuxiliarySparseMatrix("a_beta",M_a_beta);
        }
    }
#else
    std::cerr << "ams preconditioner is not interfaced in two dimensions\n";
#endif
    }
    toc("[PreconditionerBlockMS] Init",FLAGS_v>0);
    LOG(INFO) << "Init done\n";
}
double
ThermalBlockMinimalVersion::output( int output_index, parameter_type const& mu , element_type& u, bool need_to_solve)
{

    double output=0;
    auto mesh = Xh->mesh();

    if ( output_index==0 )
    {
        output =  integrate( _range=markedfaces( mesh,"south_domain-1" ), _expr= idv( u ) ).evaluate()(0,0)
                + integrate( _range=markedfaces( mesh,"south_domain-2" ), _expr= idv( u ) ).evaluate()(0,0)
                + integrate( _range=markedfaces( mesh,"south_domain-3" ), _expr= idv( u ) ).evaluate()(0,0);
    }
    else
    {
        throw std::logic_error( "[ThermalBlock::output] error with output_index : only 0 " );
    }

    return output;
}//output
Beispiel #7
0
void DrivenCavity<Dim>::exportResults( element_type const& U )
{
    auto uex=unitX();
    auto u_exact=vf::project(Vh->template functionSpace<0>(), markedfaces(mesh, "wall2"), uex );

    if ( exporter->doExport() )
    {
        exporter->step( 0 )->setMesh( U.functionSpace()->mesh() );
        exporter->step( 0 )->addRegions();
        exporter->step( 0 )->add( "u", U.template element<0>() );
        exporter->step( 0 )->add( "p", U.template element<1>() );
        exporter->step( 0 )->add( "uex", u_exact);
        exporter->save();
    }

}
Beispiel #8
0
    void
    updateP0EltMarkerFromFaceMarker()
    {
        if (!M_XhP0)
            this->buildSpaceP0();
        if (!M_markP0Elt)
            M_markP0Elt = M_XhP0->elementPtr();

        auto markEltVec = backend()->newVector( M_XhP0 );

        for ( std::string mark : M_listMarkers )
            updateP0EltMarkerFromFaceRange( markedfaces(M_mesh,mark), M_XhP0, markEltVec );

        markEltVec->close();

        //*M_markP0Elt = *markEltVec;

        // because we add values, we need to push only the positives values
        for ( size_type k=0 ; k < M_XhP0->nLocalDof() ; ++k )
            if ( markEltVec->operator()(k) > 1e-8 ) M_markP0Elt->set( k,1. );
        //if ( M_markP0Elt->operator()(k) > 1e-8 ) M_markP0Elt->set( k,1. );
    }
Beispiel #9
0
static inline void assemble(boost::shared_ptr<Mesh<Simplex<Dim>>>& mesh, double* vec) {
    boost::timer time;
    auto Vh = FunctionSpace<Mesh<Simplex<Dim>>, bases<Lagrange<Order, Type>, Lagrange<OrderBis, TypeBis>>>::New(_mesh = mesh,
                                                                                   _worldscomm = std::vector<WorldComm>(2, mesh->worldComm()),
                                                                                   _extended_doftable = std::vector<bool>(2, false));
    vec[2] = time.elapsed();
    Environment::logMemoryUsage( "Assemble Stokes Memory Usage: FunctionSpace" );
    vec[1] = Vh->nDof();
    time.restart();
    auto V = Vh->element();
    auto v = V.template element<0>();
    auto f = backend()->newVector(Vh);
    auto l = form1(_test = Vh, _vector = f);
    l = integrate(_range = elements(mesh),
                  _expr = trans(oneY()) * id(v));
    vec[4] = time.elapsed();
    Environment::logMemoryUsage( "Assemble Stokes Memory Usage: Form1" );
    time.restart();
    auto U = Vh->element();
    auto u = U.template element<0>();
    auto p = U.template element<1>();
    auto q = V.template element<1>();
    auto A = backend()->newMatrix(Vh, Vh);
    vec[5] = time.elapsed();
    Environment::logMemoryUsage( "Assemble Stokes Memory Usage: Matrix" );
    time.restart();
    auto a = form2(_trial = Vh, _test = Vh, _matrix = A);
    a = integrate(_range = elements(mesh),
                  _expr = trace(gradt(u) * trans(grad(v))));
    a += integrate(_range = elements(mesh),
                   _expr = - div(v) * idt(p) );
    a += integrate(_range = elements(mesh),
                   _expr = - divt(u) * id(q));
    a += on(_range = markedfaces(mesh, "Dirichlet"), _rhs = l, _element = u, _expr = zero<Dim, 1>());
    vec[3] = time.elapsed();
    auto mem = Environment::logMemoryUsage( "Assemble Stokes Memory Usage: Form2" );
    v[6] = mem.memory_usage/1.e9; 
    cleanup();
}
Beispiel #10
0
void
DrivenCavity<Dim>::Residual(const vector_ptrtype& X, vector_ptrtype& R)
{
    auto U = Vh->element( "(u,p)" );
    auto V = Vh->element( "(v,q)" );
    auto u = U.template element<0>( "u" );
    //auto u_exact = U.template element<0>( "u_exact" );
    auto v = V.template element<0>( "u" );
    auto p = U.template element<1>( "p" );
    auto q = V.template element<1>( "p" );
    //#if defined( FEELPP_USE_LM )
    auto lambda = U.template element<2>();
    auto nu = V.template element<2>();
    //#endif

    auto uex=unitX();
    auto u_exact=vf::project(Vh->template functionSpace<0>(), markedfaces(mesh, "wall2"), uex );


    U=*X;
    auto r = form1( _test=Vh, _vector=R );
    //r += integrate( elements( mesh ),-inner( f,id( v ) ) );
    r = integrate( elements( mesh ), trans(gradv( u )*idv(u))*id(v));//convective term
    r += integrate( elements( mesh ), inner(gradv( u ),grad( v ))/Re );
    r +=  integrate( elements( mesh ),-idv(p)*div(v) + id(q)*divv(u));
    //#if defined( FEELPP_USE_LM )
    r += integrate ( elements( mesh ), +id( q )*idv( lambda )+idv( p )*id( nu ) );
    //#endif


    //Weak Dirichlet
    auto SigmaNv = ( -idv( p )*N() + gradv( u )*N()/Re );
    auto SigmaN = ( -id( q )*N() + grad( v )*N()/Re );
    r +=integrate ( boundaryfaces(mesh), - trans( SigmaNv )*id( v ) - trans( SigmaN )*( idv( u ) -idv(u_exact) ) + penalbc*trans( idv( u ) - idv(u_exact) )*id( v )/hFace() );


}
Beispiel #11
0
static inline void assemble(boost::shared_ptr<Mesh<Simplex<Dim>>>& mesh, double* vec) {
    boost::timer time;
    //HeapProfilerStart("FunctionSpace");
    auto Vh = FunctionSpace<Mesh<Simplex<Dim>>, bases<Lagrange<Order, Type>>>::New(_mesh = mesh);
    //HeapProfilerDump("dump");
    //HeapProfilerStop();
    vec[2] = time.elapsed();
    Environment::logMemoryUsage( "Assemble Elasticity Memory Usage: FunctionSpace" );
    vec[1] = Vh->nDof();
    auto E = 1e+8;
    auto nu = 0.25;
    auto mu = E / (2 * (1 + nu));
    auto lambda = E * nu / ((1 + nu) * (1 - 2 * nu));
    time.restart();
    auto v = Vh->element();
    auto f = backend()->newVector(Vh);
    auto l = form1(_test = Vh, _vector = f);
    l = integrate(_range = elements(mesh), _expr = -1e+3 * trans(oneY()) * id(v));
    vec[4] = time.elapsed();
    Environment::logMemoryUsage( "Assemble Elasticity Memory Usage: Form1" );
    time.restart();
    auto u = Vh->element();
    auto A = backend()->newMatrix(Vh, Vh);
    vec[5] = time.elapsed();
    Environment::logMemoryUsage( "Assemble Elasticity Memory Usage: Matrix" );
    time.restart();
    auto a = form2(_trial = Vh, _test = Vh, _matrix = A);
    a = integrate(_range = elements(mesh),
                  _expr = lambda * divt(u) * div(v) +
                          2 * mu * trace(trans(sym(gradt(u))) * sym(grad(u))));
    a += on(_range = markedfaces(mesh, "Dirichlet"), _rhs = l, _element = u, _expr = zero<Dim, 1>());
    vec[3] = time.elapsed();
    auto mem = Environment::logMemoryUsage( "Assemble Elasticity Memory Usage: Form2" );
    v[6] = mem.memory_usage/1e9; 
    cleanup();
}
Beispiel #12
0
void
NavierStokes::run()
{
    this->init();

    auto U = Xh->element( "(u,p)" );
    auto V = Xh->element( "(u,q)" );
    auto u = U.element<0>( "u" );
    auto v = V.element<0>( "u" );
    auto p = U.element<1>( "p" );
    auto q = V.element<1>( "p" );
#if defined( FEELPP_USE_LM )
    auto lambda = U.element<2>();
    auto nu = V.element<2>();
#endif
    //# endmarker4 #

    LOG(INFO) << "[dof]         number of dof: " << Xh->nDof() << "\n";
    LOG(INFO) << "[dof]    number of dof/proc: " << Xh->nLocalDof() << "\n";
    LOG(INFO) << "[dof]      number of dof(U): " << Xh->functionSpace<0>()->nDof()  << "\n";
    LOG(INFO) << "[dof] number of dof/proc(U): " << Xh->functionSpace<0>()->nLocalDof()  << "\n";
    LOG(INFO) << "[dof]      number of dof(P): " << Xh->functionSpace<1>()->nDof()  << "\n";
    LOG(INFO) << "[dof] number of dof/proc(P): " << Xh->functionSpace<1>()->nLocalDof()  << "\n";

    LOG(INFO) << "Data Summary:\n";
    LOG(INFO) << "   hsize = " << meshSize << "\n";
    LOG(INFO) << "  export = " << this->vm().count( "export" ) << "\n";
    LOG(INFO) << "      mu = " << mu << "\n";
    LOG(INFO) << " bccoeff = " << penalbc << "\n";




    //# marker5 #
    auto deft = gradt( u )+trans(gradt(u));
    auto def = grad( v )+trans(grad(v));
    //# endmarker5 #

    //# marker6 #
    // total stress tensor (trial)
    auto SigmaNt = -idt( p )*N()+mu*deft*N();

    // total stress tensor (test)
    auto SigmaN = -id( p )*N()+mu*def*N();
    //# endmarker6 #

    auto F = M_backend->newVector( Xh );
    auto D =  M_backend->newMatrix( Xh, Xh );

    // right hand side
    auto ns_rhs = form1( _test=Xh, _vector=F );


    LOG(INFO) << "[navier-stokes] vector local assembly done\n";

    // construction of the BDF
    auto bdfns=bdf(_space=Xh);

    /*
     * Construction of the left hand side
     */

    auto navierstokes = form2( _test=Xh, _trial=Xh, _matrix=D );
    mpi::timer chrono;
    navierstokes += integrate( elements( mesh ), mu*inner( deft,def )+ trans(idt( u ))*id( v )*bdfns->polyDerivCoefficient( 0 ) );
    LOG(INFO) << "mu*inner(deft,def)+(bdf(u),v): " << chrono.elapsed() << "\n";
    chrono.restart();
    navierstokes +=integrate( elements( mesh ), - div( v )*idt( p ) + divt( u )*id( q ) );
    LOG(INFO) << "(u,p): " << chrono.elapsed() << "\n";
    chrono.restart();
#if defined( FEELPP_USE_LM )
    navierstokes +=integrate( elements( mesh ), id( q )*idt( lambda ) + idt( p )*id( nu ) );
    LOG(INFO) << "(lambda,p): " << chrono.elapsed() << "\n";
    chrono.restart();
#endif

    std::for_each( inflow_conditions.begin(), inflow_conditions.end(),
                   [&]( BoundaryCondition const&  bc )
                   {
                       // right hand side
                       ns_rhs += integrate( markedfaces( mesh, bc.marker() ), inner( idf(&bc,BoundaryCondition::operator()),-SigmaN+penalbc*id( v )/hFace() ) );

                       navierstokes +=integrate( boundaryfaces( mesh ), -inner( SigmaNt,id( v ) ) );
                       navierstokes +=integrate( boundaryfaces( mesh ), -inner( SigmaN,idt( u ) ) );
                       navierstokes +=integrate( boundaryfaces( mesh ), +penalbc*inner( idt( u ),id( v ) )/hFace() );
                   });
    std::for_each( wall_conditions.begin(), wall_conditions.end(),
                   [&]( BoundaryCondition const&  bc )
                   {
                       navierstokes +=integrate( boundaryfaces( mesh ), -inner( SigmaNt,id( v ) ) );
                       navierstokes +=integrate( boundaryfaces( mesh ), -inner( SigmaN,idt( u ) ) );
                       navierstokes +=integrate( boundaryfaces( mesh ), +penalbc*inner( idt( u ),id( v ) )/hFace() );
                   });
    std::for_each( outflow_conditions.begin(), outflow_conditions.end(),
                   [&]( BoundaryCondition const&  bc )
                   {
                       ns_rhs += integrate( markedfaces( mesh, bc.marker() ), inner( idf(&bc,BoundaryCondition::operator()),N() ) );
                   });

    LOG(INFO) << "bc: " << chrono.elapsed() << "\n";
    chrono.restart();

    u = vf::project( _space=Xh->functionSpace<0>(), _expr=cst(0.) );
    p = vf::project( _space=Xh->functionSpace<1>(), _expr=cst(0.) );

    M_bdf->initialize( U );

    for( bdfns->start(); bdfns->isFinished(); bdfns->next() )
    {
        // add time dependent terms
        auto bdf_poly = bdfns->polyDeriv();
        form1( _test=Xh, _vector=Ft ) =
            integrate( _range=elements(mesh), _expr=trans(idv( bdf_poly ))*id( v ) );
        // add convective terms
        form1( _test=Xh, _vector=Ft ) +=
            integrate( _range=elements(mesh), _expr=trans(gradv(u)*idv( u ))*id(v) );
        // add contrib from time independent terms
        Ft->add( 1., F );

        // add time stepping terms from BDF to right hand side
        backend()->solve( _matrix=D, _solution=U, _rhs=Ft );

        this->exportResults( bdfns->time(), U );
    }





} // NavierNavierstokes::run
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()
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 );
}
Beispiel #15
0
// <int Order_s, int Order_p, int Order_t>
void Convection ::initLinearOperator2( sparse_matrix_ptrtype& L )
{
    boost::timer ti;
    LOG(INFO) << "[initLinearOperator2] start\n";

    mesh_ptrtype mesh = Xh->mesh();
    element_type U( Xh, "u" );
    element_type Un( Xh, "un" );
    element_type V( Xh, "v" );
    element_0_type u = U. element<0>(); // fonction vitesse
    element_0_type un = Un. element<0>(); // fonction vitesse
    element_0_type v = V. element<0>(); // fonction test vitesse
    element_1_type p = U. element<1>(); // fonction pression
    element_1_type pn = Un. element<1>(); // fonction pression
    element_1_type q = V. element<1>(); // fonction test pression
    element_2_type t = U. element<2>(); // fonction temperature
    element_2_type tn = Un. element<2>(); // fonction temperature
    element_2_type s = V. element<2>(); // fonction test temperature
#if defined( FEELPP_USE_LM )
    element_3_type xi = U. element<3>(); // fonction multipliers
    element_3_type eta = V. element<3>(); // fonction test multipliers
#endif

    double gr= M_current_Grashofs;
    double sqgr( 1/math::sqrt( gr ) );
    double pr = M_current_Prandtl;
    double sqgrpr( 1/( pr*math::sqrt( gr ) ) );
    double gamma( this->vm()["penalbc"]. as<double>() );

    double k=this->vm()["k"]. as<double>();
    double nu=this->vm()["nu"]. as<double>();
    double rho=this->vm()["rho"]. as<double>();
    //double dt=this->vm()["dt"]. as<double>();
    int adim=this->vm()["adim"]. as<int>();
    int weakdir=this->vm()["weakdir"]. as<int>();
    //choix de la valeur des paramètres dimensionnés ou adimensionnés
    double a=0.0,b=0.0,c=0.0;
    double pC=1;

    if ( adim == 0 ) pC = this->vm()["pC"]. as<double>();

    if ( adim==1 )
    {
        a=1;
        b=sqgr;
        c=sqgrpr;
    }

    else
    {
        a=rho;
        b=nu;
        c=k;
    }

    double expansion = 1;

    if ( adim == 0 ) expansion=3.7e-3;

    auto bf = form2( _test=Xh, _trial=Xh, _matrix=L );
    // Temperature
#if CONVECTION_DIM==2
    // buyoancy forces c(theta,v)
    bf +=integrate( _range=elements( mesh ),
                    _expr=-expansion*idt( t )*( trans( vec( constant( 0. ),constant( 1.0 ) ) )*id( v ) ) );
#else
    bf +=integrate( _range=elements( mesh ),
                    _expr=-expansion*idt( t )*( trans( vec( cst(0.), constant( 0. ),constant( 1.0 ) ) )*id( v ) ) );
#endif

    LOG(INFO) << "[initLinearOperator] temperature Force terms done\n";
    // heat conduction/diffusion: e(beta1,theta,chi)+f(theta,chi)
    bf  += integrate( _range=elements( mesh ),
                      _expr=cst( c )*gradt( t )*trans( grad( s ) ) );
    LOG(INFO) << "[initLinearOperator] Temperature Diffusion terms done\n";

    if ( weakdir == 1 )
    {
        // weak Dirichlet on temperature (T=0|left wall)
        bf  += integrate ( markedfaces( mesh, "Tfixed"  ),
                           - gradt( t )*N()*id( s )*cst_ref( sqgrpr ) );
        bf  += integrate ( markedfaces( mesh, "Tfixed"  ),
                           - grad( s )*N()*idt( t )*cst_ref( sqgrpr ) );
        bf  += integrate ( markedfaces( mesh, "Tfixed"  ),
                           gamma*idt( t )*id( s )/hFace() );
    }

    LOG(INFO) << "[initLinearOperator2] done in " << ti.elapsed() << "s\n";
}
Beispiel #16
0
void
Beam<nDim,nOrder>::run()
{

    this->changeRepository( boost::format( "doc/manual/solid/%1%/%2%/P%3%/h_%4%/" )
                            % this->about().appName()
                            % entity_type::name()
                            % nOrder
                            % meshSize );
    /*
     * First we create the mesh
     */
    mesh_ptrtype mesh = createGMSHMesh( _mesh=new mesh_type,
                                        _update=MESH_UPDATE_EDGES|MESH_UPDATE_FACES|MESH_CHECK,
                                        _desc=domain( _name=( boost::format( "beam-%1%" ) % nDim ).str() ,

                                                      _shape="hypercube",
                                                      _xmin=0., _xmax=0.351,
                                                      _ymin=0., _ymax=0.02,
                                                      _zmin=0., _zmax=0.02,
                                                      _h=meshSize ) );
    // add marker clamped to the mesh
    mesh->addMarkerName( "clamped",( nDim==2 )?1:19, (nDim==2)?1:2);
    mesh->addMarkerName( "tip",( nDim==2)?3:27, (nDim==2)?1:2);
    /*
     * The function space and some associate elements are then defined
     */
    timers["init"].first.restart();
    space_ptrtype Xh = space_type::New( mesh );
    Xh->printInfo();

    element_type u( Xh, "u" );
    element_type v( Xh, "v" );
    timers["init"].second = timers["init"].first.elapsed();

    /*
     * Data associated with the simulation
     */
    auto E = doption(_name="E")*pascal;
    const double nu = doption(_name="nu");

    auto mu = E/( 2*( 1+nu ) );
    auto lambda = E*nu/( ( 1+nu )*( 1-2*nu ) );
    auto density = 1e3;
    auto gravity = -2*newton/pow<Dim>(meter);//-density*0.05;
    LOG(INFO) << "lambda = " << lambda << "\n"
          << "mu     = " << mu << "\n"
          << "gravity= " << gravity << "\n";

    /*
     * Construction of the right hand side
     *
     * \f$ f = \int_\Omega g * v \f$ where \f$ g \f$ is a vector
     * directed in the \f$ y \f$ direction.
     */
    auto F = backend()->newVector( Xh );
    F->zero();
    timers["assembly"].first.restart();

    if ( Dim == 3 )
        form1( _test=Xh, _vector=F ) = integrate( elements( mesh ), trans( gravity.value()*oneZ() )*id( v ) );
    else
        form1( _test=Xh, _vector=F ) = integrate( elements( mesh ), trans( gravity.value()*oneY() )*id( v ) );

    timers["assembly"].second = timers["assembly"].first.elapsed();

    /*
     * Construction of the left hand side
     */
    auto D = backend()->newMatrix( Xh, Xh );
    timers["assembly"].first.restart();
    auto deft = sym(gradt(u));
    auto def = sym(grad(u));
    auto a = form2( _test=Xh, _trial=Xh, _matrix=D );
    a = integrate( elements( mesh ),
                   lambda.value()*divt( u )*div( v )  +
                   2.*mu.value()*trace( trans( deft )*def ) );

    if ( M_bctype == 1 ) // weak Dirichlet bc
    {
        auto Id = eye<nDim>();
        a += integrate( markedfaces( mesh, "clamped" ),
                        - trans( ( 2.*mu.value()*deft+lambda.value()*trace( deft )*Id )*N() )*id( v )
                        - trans( ( 2.*mu.value()*def+lambda.value()*trace( def )*Id )*N() )*idt( u )
                        + bcCoeff*std::max(2.*mu.value(),lambda.value())*trans( idt( u ) )*id( v )/hFace() );
    }

    if ( M_bctype == 0 )
        a += on( markedfaces( mesh, "clamped" ), u, F, zero<nDim,1>() );

    timers["assembly"].second += timers["assembly"].first.elapsed();

    backend(_rebuild=true)->solve( _matrix=D, _solution=u, _rhs=F );

    v = vf::project( Xh, elements( Xh->mesh() ), P() );
    this->exportResults( 0, u, v );

    auto i1 = mean( _range=markedfaces( mesh, "tip"  ), _expr=idv( u ) );
    LOG(INFO) << "deflection: " << i1 << "\n";

} // Beam::run
Beispiel #17
0
 void updateFaceMarker3FromFaceMarker()
 {
     for ( std::string mark : M_listMarkers )
         M_mesh->updateMarker3WithRange(markedfaces(M_mesh,mark),1);
 }
Beispiel #18
0
void
Partitioning<Dim>::run()
{
    int p = 2;
    int* pm = new int[p];
    for(unsigned short i = 0; i < p; ++i)
        pm[i] = i * (Environment::numberOfProcessors() / p);
    bool excluded = std::binary_search(pm, pm + p, Environment::rank());
    mpi::group new_group;
    if(excluded)
        new_group = Environment::worldComm().group().include(pm,pm+p);
    else
        new_group = Environment::worldComm().group().exclude(pm,pm+p);
    delete [] pm;

    boost::mpi::communicator bComm(Environment::worldComm(), new_group);
    std::vector<int> active( bComm.size(), true );
    WorldComm wComm(bComm,bComm,bComm,bComm.rank(),active);
    //wComm.showMe();
    boost::shared_ptr<Mesh<Simplex<Dim>>> mesh;
    if(!excluded)
    {
        std::cout << "proc " << Environment::rank() 
                  << " is not excluded and is locally rank " << wComm.rank() << " and loads mesh with " 
                  << wComm.globalSize() << " partitions\n";
        // mesh = loadMesh(_mesh = new Mesh<Simplex<Dim>>(wComm), _worldcomm=wComm );
        mesh = createGMSHMesh(_mesh = new Mesh<Simplex<Dim>>(wComm),
                              _worldcomm = wComm,
                              _desc = domain(_worldcomm = wComm, _name = "hypercube", _shape = "hypercube",
                                             _xmin = 0.0, _xmax = 1.0,
                                             _ymin = 0.0, _ymax = 1.0,
                                             _zmin = 0.0, _zmax = 1.0));
        std::cout << " - nelement(mesh)=" << nelements(elements(mesh)) << "\n";
        std::cout << " - loading space\n";
        auto Vh = Pch<2>( mesh );

        auto u = Vh->element("u");
        auto f = expr( soption(_name="functions.f"), "f", wComm );

        auto g = expr( soption(_name="functions.g"), "g", wComm );
        auto v = Vh->element( g, "g" );

        auto l = form1( _test=Vh );
        l = integrate(_range=elements(mesh),_expr=f*id(v));

        auto a = form2( _trial=Vh, _test=Vh);
        a = integrate(_range=elements(mesh),
                      _expr=gradt(u)*trans(grad(v)) );
        if(boption("gmsh.domain.usenames")) {
            if(nelements(markedfaces(mesh, "Dirichlet"), boption("use_global")) > 0)
                a+=on(_range=markedfaces(mesh, "Dirichlet"), _rhs=l, _element=u, _expr=g);
        }
        else
            a+=on(_range=boundaryfaces(mesh), _rhs=l, _element=u, _expr=g);
        a.solve(_rhs=l,_solution=u);
        auto e = exporter( _mesh=mesh );
        //e->addRegions();
        e->add( "u", u );
        e->add( "g", v );
        e->save();
    }
    else
    {
        std::cout << "proc " << Environment::rank() 
                  << " is excluded and does not load mesh";
        int np = 0;
        mpi::all_reduce(wComm, 1, np, std::plus<int>());
        std::cout << "proc " << Environment::rank() 
                  <<   " - nb proc = " << np << "\n";
    }
} // Partitioning::run
Beispiel #19
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 );
}