Exemple #1
0
void GraphProto::dump(std::ostream& stream, size_t indent) {
  stream << idt(indent) << "GraphProto {" << nlidt(indent+1)
         << "name: \"" << name << "\"" << nlidt(indent+1)
         << "inputs: [";
  for (size_t i=0; i < inputs.size(); ++i) {
    inputs[i]->dump(stream, indent+2);
    stream << (i == inputs.size() - 1 ? "" : ",");
  }
  stream << "]" << nlidt(indent+1)
         << "outputs: [";
  for (size_t i=0; i < outputs.size(); ++i) {
    outputs[i]->dump(stream, indent+2);
    stream << (i == outputs.size() - 1 ? "" : ",");
  }
  stream << "]" << nlidt(indent+1)
         << "initializers: [";
  for (size_t i=0; i < initializers.size(); ++i) {
    initializers[i]->dump(stream, indent+2);
    stream << (i == initializers.size() - 1 ? "" : ",");
  }
  stream << "]" << nlidt(indent+1)
         << "nodes: [" << nlidt(indent+2);
  for (size_t i=0; i < nodes.size(); ++i) {
    nodes[i]->dump(stream, indent+2);
    if (i != nodes.size() - 1) stream << "," << nlidt(indent+2);
  }
  stream << nlidt(indent+1) << "]\n" << idt(indent) << "}\n";
}
// <int Order_s, int Order_p, int Order_t>
void Convection::updateJacobian2( const vector_ptrtype& X,
        sparse_matrix_ptrtype& D )
{
    mesh_ptrtype mesh = Xh->mesh();
    element_type U( Xh, "u" );
    U = *X;
    LOG(INFO) << "[updateJacobian] ||X|| = " << U.l2Norm() << "\n";
    element_type V( Xh, "v" );
    element_type W( Xh, "v" );
    element_0_type u = U. 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 q = V. element<1>(); // fonction test pression
    element_2_type t = U. 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 dt=this->vm()["dt"]. as<double>();
    int adim=this->vm()["adim"]. as<int>();
    double pC=1;

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

    //
    // temperature derivatives
    //
    // heat convection by the fluid: attention 2 terms
    form2( _test=Xh, _trial=Xh, _matrix=D ) +=
        integrate ( elements( mesh ),
                    pC*grad( s )*( idv( t )*idt( u ) ) );

    form2( _test=Xh, _trial=Xh, _matrix=D ) +=
        integrate ( elements( mesh ),
                    pC*grad( s )*( idt( t )*idv( u ) ) );

    form2( _test=Xh, _trial=Xh, _matrix=D ) +=
        integrate ( boundaryfaces( mesh ),
                    pC*( trans( idv( u ) )*N() )*id( s )*idt( t ) );

    form2( _test=Xh, _trial=Xh, _matrix=D ) +=
        integrate ( boundaryfaces( mesh ),
                    pC*( trans( idt( u ) )*N() )*id( s )*idv( t ) );

    LOG(INFO) << "[updateJacobian2] Temperature convection terms done\n";


    LOG(INFO) << "[updateJacobian2] Temperature weak Dirichlet BC terms done\n";


}
Exemple #3
0
void display_list( int indent, std::ostream& os, const T& v )
{
	for( typename T::const_iterator i = v.begin() ; i != v.end() ; ++i ) {
		os << std::endl;
		os << idt(indent) << dsp( indent, (*i) );
	}
}
Exemple #4
0
void
DrivenCavity<Dim>::Jacobian(const vector_ptrtype& X, sparse_matrix_ptrtype& J)
{
    auto U = Vh->element( "(u,p)" );
    auto V = Vh->element( "(v,q)" );
    auto u = U.template element<0>( "u" );
    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

    if (!J) J = backend(_name="newtonns")->newMatrix( Vh, Vh );
    auto a = form2( _test=Vh, _trial=Vh, _matrix=J );
    a = integrate( elements( mesh ), inner(gradt( u ),grad( v ))/Re );
    a += integrate( elements( mesh ), id(q)*divt(u) -idt(p)*div(v) );
    // Convective terms
    a += integrate( elements( mesh ), trans(id(v))*gradv(u)*idt(u));
    a += integrate( elements( mesh ), trans(id(v))*gradt(u)*idv(u));

    //#if defined( FEELPP_USE_LM )
    a += integrate(elements(mesh), id(q)*idt(lambda)+idt(p)*id(nu));
    //#elif
    //a += integrate(elements(mesh), idt(p)*id(nu));

    //Weak Dirichlet conditions
    a += integrate( boundaryfaces( mesh ),-trans( -idt(p)*N()+gradt(u)*N()/Re )*id( v ));//
    a += integrate( boundaryfaces( mesh ),-trans( -id(p)*N()+grad(u)*N()/Re )*idt( u ));//
    a += integrate( boundaryfaces( mesh ), +penalbc*inner( idt( u ),id( v ) )/hFace() );


}
Exemple #5
0
void ModelProto::dump(std::ostream& stream, size_t indent) {
  stream << idt(indent)
         << "ModelProto {" << nlidt(indent+1)
         << "producer_name: \"" << producer_name << "\"" << nlidt(indent+1)
         << "domain: \"" << domain << "\"" << nlidt(indent+1)
         << "doc_string: \"" << doc_string << "\"";
  if (graph) {
    stream << nlidt(indent+1) << "graph:\n";
    graph->dump(stream, indent+2);
  }
  if (opset_import.size()) {
    stream << idt(indent+1) << "opset_import: [";
    for (auto &opset_imp : opset_import) {
      opset_imp->dump(stream, indent+2);
    }
    stream << "],\n";
  }
  stream << idt(indent) << "}\n";
}
Exemple #6
0
void World::IntegrateBoxForces(f64 dt)
{
	/*integration_data.clear();
	int numPerThread = 100; // should be a multiple of 1,2,5,10,20,25,50,100,200 or 400
	for(int i=0;i<firstTriangleIndex-4;i+=numPerThread) // 0 to 800
	{
	IntegrationData idt(i, i+numPerThread, dt, this);
	integration_data.push_back(idt);
	physicsPool->AddTask(Task(TAddForces, &integration_data.back()));
	}*/
	IntegrationData idt(0, firstTriangleIndex, dt, this);
	Integrate(&idt);
	//physicsPool->FinishAllTasks();
};
Exemple #7
0
void World::IntegrateBoxes(f64 dt)
{
	// This is thread safe as objects are updated without changing other objects. Therefore we can thread the update to
	// put it on as many as we want. We can tweak the value to update per thread but it should be fairly large (maybe ~100 a time?)
	// as the process is very fast
	//integration_data.clear();
	/*int numPerThread = 100; // should be a multiple of 1,2,5,10,20,25,50,100,200 or 400
	for(int i=0;i<firstTriangleIndex-4;i+=numPerThread) // 0 to 800
	{
	IntegrationData idt(i, i+numPerThread, dt, this);
	integration_data.push_back(idt);
	physicsPool->AddTask(Task(Integrate, &integration_data.back()));
	}*/
	IntegrationData idt(0, firstTriangleIndex, dt, this);
	Integrate(&idt);

	// wait for everything to finish for physics for this frame
	//physicsPool->FinishAllTasks();
};
Exemple #8
0
//template< typename Expr_convection, typename Expr_bc >
void
PreconditionerAS<space_type,coef_space_type>::update( sparse_matrix_ptrtype Pm,   // A + g M
                                                      sparse_matrix_ptrtype L,    // e_r * grad grad
                                                      sparse_matrix_ptrtype hatL, // 1/mu * grad grad
                                                      sparse_matrix_ptrtype Q     // e_r * id id
                                                      )
{
    tic();
    if(this->type() == AS)
    {
        // A = Pm
        backend()->diag(Pm,M_diagPm);
        M_diagPm->close();

        /*
         * hat(L) = 1/mu * grad grad = 1/(mu*e_r) * L
         * bar(L) = diag( hat(L), hat(L), hat(L) )
         * bar(Q) = diag( er*Q, er*Q, er*Q ) with Q = mass matrix on Qh3
         * blockms.11.1 <=> bar(L) + g*bar(Q) y = s = Pt*r
         * blockms.11.2 <=> L z = t = trans(C)*r
         */

        // Operator hat(L) + g Q
        sparse_matrix_ptrtype Lgq = hatL;
        Lgq->addMatrix(M_g,Q);
        M_lgqOp = op( Lgq, "blockms.11.1");
        // Operator L
        M_lOp = op(L,"blockms.11.2");
    }
    else if(this->type() == SIMPLE)
    {
        auto uu = M_Vh->element("uu");
        auto f22 = form2(M_Vh, M_Vh);
        f22 = integrate(_range=elements(M_Vh->mesh()),
                        _expr=inner(id(uu),idt(uu)));
        SimpleOp = op( f22.matrixPtr(),"blockms.11.1");
    }
    toc( "PreconditionerAS::update", FLAGS_v > 0 );
}
Exemple #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();
}
Exemple #10
0
////////////////////////////////////////////////////////////////
// Module
void Module::display( int indent, std::ostream& os )
{
	os << idt(indent) << "<Module>" << hdr( h );
	topelems->display( indent+1, os );
	os << std::endl;
}
Exemple #11
0
////////////////////////////////////////////////////////////////
// Member
void Member::display( int indent, std::ostream& os )
{
	os << idt(indent) << dsp( 0, farg ) << hdr( h );
}
Exemple #12
0
std::string nlidt(size_t indent) {
  return std::string("\n") + idt(indent);
}
Exemple #13
0
////////////////////////////////////////////////////////////////
// FunDef
void FunDef::display( int indent, std::ostream& os )
{
	os << "<FunDef>" << hdr( h ) << std::endl;
	os << idt(indent+1) << dsp( indent+1, sig ) << std::endl;
	body->display( indent+1, os );
}
Exemple #14
0
////////////////////////////////////////////////////////////////
// StructDef
void StructDef::display( int indent, std::ostream& os )
{
	os << idt(indent) << "<StructDef "
	   << name->source->s << ">";
	members->display( indent+1, os );
}
Exemple #15
0
////////////////////////////////////////////////////////////////
// Block
void Block::display( int indent, std::ostream& os )
{
	os << idt(indent) << "<Block>" << hdr( h );
	statements->display( indent+1, os );
}
Exemple #16
0
////////////////////////////////////////////////////////////////
// FunDecl
void FunDecl::display( int indent, std::ostream& os )
{
	os << idt(indent) << "<FunDecl>" << hdr( h );
	sig->display( indent+1, os );
}
Exemple #17
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 run()
{

    Environment::changeRepository( boost::format( "/testsuite/feeldiscr/%1%/P%2%/" )
                                   % Environment::about().appName()
                                   % OrderPoly );


    /* change parameters below */
    const int nDim = 2;
    const int nOrderPoly = OrderPoly;
    const int nOrderGeo = 1;

    //------------------------------------------------------------------------------//

    typedef Mesh< Simplex<nDim, 1,nDim> > mesh_type;
    typedef Mesh< Simplex<nDim, 1,nDim> > mesh_bis_type;

    double meshSize = option("hsize").as<double>();
    double meshSizeBis = option("hsize-bis").as<double>();

    // mesh
    GeoTool::Node x1( 0,0 );
    GeoTool::Node x2( 4,1 );
    GeoTool::Rectangle Omega( meshSize,"Omega",x1,x2 );
    Omega.setMarker( _type="line",_name="Entree",_marker4=true );
    Omega.setMarker( _type="line",_name="Sortie",_marker2=true );
    Omega.setMarker( _type="line",_name="Paroi",_marker1=true,_marker3=true );
    Omega.setMarker( _type="surface",_name="Fluid",_markerAll=true );
    auto mesh = Omega.createMesh(_mesh=new mesh_type,_name="omega_"+ mesh_type::shape_type::name() );
    LOG(INFO) << "created mesh\n";

    GeoTool::Rectangle OmegaBis( meshSizeBis,"Omega",x1,x2 );
    OmegaBis.setMarker( _type="line",_name="Entree",_marker4=true );
    OmegaBis.setMarker( _type="line",_name="Sortie",_marker2=true );
    OmegaBis.setMarker( _type="line",_name="Paroi",_marker1=true,_marker3=true );
    OmegaBis.setMarker( _type="surface",_name="Fluid",_markerAll=true );
    auto meshBis = OmegaBis.createMesh(_mesh=new mesh_bis_type,_name="omegaBis_"+ mesh_type::shape_type::name() );

    //auto meshBis= mesh->createP1mesh();
    LOG(INFO) << "created meshBis\n";

    typedef Lagrange<nOrderPoly,Scalar,Continuous,PointSetFekete> basis_type;
    typedef FunctionSpace<mesh_type, bases<basis_type> > space_type;

    auto Xh = space_type::New( mesh );
    auto u = Xh->element();
    auto v = Xh->element();
    auto u2 = Xh->element();
    LOG(INFO) << "created space and elements\n";

    auto mybackend = backend();

    //--------------------------------------------------------------//

    auto A = mybackend->newMatrix( Xh, Xh );
    auto F = mybackend->newVector( Xh );
    auto pi = cst( M_PI );
    auto u_exact = cos( pi*Px() )*sin( pi*Py() );
    auto dudx = -pi*sin( pi*Px() )*sin( pi*Py() );
    auto dudy = pi*cos( pi*Px() )*cos( pi*Py() );
    auto grad_u_uexact = vec( dudx,dudy );
    auto lap = -2*pi*pi*cos( pi*Px() )*sin( pi*Py() );
    //auto lap = -pi*pi*cos(pi*Px())*sin(pi*Py())
    //    -pi*pi*cos(pi*Px())*sin(pi*Py());
    LOG(INFO) << "created exact data and matrix/vector\n";

    auto f = -lap;//cst(1.);
    double gammabc=10;

    // assemblage
    form2( Xh, Xh, A, _init=true ) =
        integrate( elements( mesh ), //_Q<15>(),
                   + gradt( u )*trans( grad( v ) ) );

    form2( Xh, Xh, A ) +=
        integrate( boundaryfaces( mesh ),
                   - gradt( u )*N()*id( v )
                   + gammabc*idt( u )*id( v )/hFace() );

    form1( Xh, F, _init=true ) =
        integrate( elements( mesh ), // _Q<10>(),
                   trans( f )*id( v ) );

    form1( Xh, F ) +=
        integrate( boundaryfaces( mesh ),
                   + gammabc*u_exact*id( v )/hFace() );

    LOG(INFO) << "A,F assembled\n";

    //form2( Xh, Xh, A ) +=
    //    on( boundaryfaces(mesh) , u, F, u_exact );

    // solve system
    mybackend->solve( A,u,F );
    LOG(INFO) << "A u = F solved\n";
    //--------------------------------------------------------------//

    auto a2 = form2( _test=Xh, _trial=Xh );
    auto f2 = form1( _test=Xh );
    LOG(INFO) << "created form2 a2 and form1 F2\n";

    // assemblage

    a2 = integrate( elements( meshBis ),
                    + gradt( u2 )*trans( grad( v ) ),
                    _Q<10>() );
    LOG(INFO) << "a2 grad.grad term\n";
    a2 += integrate( boundaryfaces( meshBis ),
                     - gradt( u2 )*N()*id( v )
                     + gammabc*idt( u2 )*id( v )/hFace(),
                     _Q<10>() );
    LOG(INFO) << "a2 weak dirichlet terms\n";

    f2 = integrate( elements( meshBis ),
                    trans( f )*id( v ),
                    _Q<10>() );
    LOG(INFO) << "f2 source term\n";
    f2 += integrate( boundaryfaces( meshBis ),
                     + gammabc*u_exact*id( v )/hFace(),
                     _Q<10>() );
    LOG(INFO) << "f2 dirichlet terms\n";

    LOG(INFO) << "a2,f2 assembled\n";

    //form2( Xh, Xh, A2 ) +=
    //     on( boundaryfaces(mesh) , u2, F2, u_exact );



#if 0

    for ( size_type i = 0 ; i< F->size() ; ++i )
    {
        auto errOnF = std::abs( ( *F )( i )-( *F2 )( i ) );

        if ( errOnF > 1e-8 )
            std::cout << "\nerrOnF : " << errOnF;
    }

    std::cout << "\nFin errOnF !!!!\n";
#endif

    // solve system
    a2.solve( _rhs=f2, _solution=u2 );


    auto diff = std::sqrt( integrate( elements( mesh ), ( idv( u )-idv( u2 ) )*( idv( u )-idv( u2 ) ) ).evaluate()( 0,0 ) );
#if 0
    auto int1 = integrate( elements( mesh ), abs( idv( u ) ) ).evaluate()( 0,0 );
    auto int2 = integrate( elements( mesh ), abs( idv( u2 ) ) ).evaluate()( 0,0 );

    std::cout << "\nThe diff : " << diff
              << " int1 :" << int1
              << " int2 :" << int2
              << "\n";
#endif
#if USE_BOOST_TEST
    BOOST_CHECK_SMALL( diff,1e-2 );
#endif


    //--------------------------------------------------------------//

    if ( option("exporter.export").as<bool>() )
    {
        // export
        auto ex = exporter( _mesh=mesh );
        ex->add( "u", u );
        ex->add( "ubis", u2 );
        ex->save();
    }
}
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 );
}
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 );
}
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()
Exemple #22
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
Exemple #23
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";
}