element_type exact_project(const space_ptrtype & Xh, const double & val) { ex solution = getSolution(val); auto mesh = Xh->mesh(); auto gproj = vf::project( _space=Xh, _range=elements( mesh ), _expr=expr(solution,vars) ); return gproj; }
element_type rhs_project(const space_ptrtype & Xh) { ex solution = getRhs(); auto mesh = Xh->mesh(); auto gproj = vf::project( _space=Xh, _range=elements( mesh ), _expr=expr(solution,vars) ); return gproj; }
double L2_error(const space_ptrtype & Xh, const element_type & T, const double & values) const { // replace params by specified values ex solution = getSolution(values); auto g = expr(solution,vars); auto mesh = Xh->mesh(); return math::sqrt( integrate( elements(mesh), Px()*(idv(T) - g)*(idv(T) - g) ).evaluate()(0,0) ); }
element_type grad_exact_project(const space_ptrtype & Xh) { ex solution = getSolution(); auto gradg = expr<1,Dim,2>(grad(solution,vars), vars ); auto mesh = Xh->mesh(); auto gproj = vf::project( _space=Xh, _range=elements( mesh ), _expr=expr(gradg,vars) ); return gproj; }
double H1_error(const space_ptrtype & Xh, const element_type & T, const double & values) const { // replace params by specified values ex solution = getSolution(values); auto gradg = expr<1,Dim,2>(grad(solution,vars), vars ); auto mesh = Xh->mesh(); double L2error = L2_error(Xh, T, values); double H1seminorm = math::sqrt( integrate( elements(mesh), Px()*(gradv(T) - gradg)*trans(gradv(T) - gradg) ).evaluate()(0,0) ); return math::sqrt( L2error*L2error + H1seminorm*H1seminorm); }
PreconditionerAS<space_type,coef_space_type>::PreconditionerAS( std::string t, space_ptrtype Xh, coef_space_ptrtype Mh, BoundaryConditions bcFlags, std::string const& p, sparse_matrix_ptrtype Pm, double k ) : M_type( AS ), M_Xh( Xh ), M_Vh(Xh->template functionSpace<0>() ), M_Qh(Xh->template functionSpace<1>() ), M_Mh( Mh ), M_Vh_indices( M_Vh->nLocalDofWithGhost() ), M_Qh_indices( M_Qh->nLocalDofWithGhost() ), M_Qh3_indices( Dim ), A(backend()->newVector(M_Vh)), B(backend()->newVector(M_Vh)), C(backend()->newVector(M_Vh)), M_r(backend()->newVector(M_Vh)), M_r_t(backend()->newVector(M_Vh)), M_uout(backend()->newVector(M_Vh)), M_diagPm(backend()->newVector(M_Vh)), //M_t(backend()->newVector(M_Vh)), U( M_Vh, "U" ), M_mu(M_Mh, "mu"), M_er(M_Mh, "er"), M_bcFlags( bcFlags ), M_prefix( p ), M_k(k), M_g(1.-k*k) { tic(); LOG(INFO) << "[PreconditionerAS] setup starts"; this->setMatrix( Pm ); // Needed only if worldComm > 1 // QH3 : Lagrange vectorial space type M_Qh3 = lag_v_space_type::New(Xh->mesh()); M_qh3_elt = M_Qh3->element(); M_qh_elt = M_Qh->element(); M_vh_elt = M_Vh->element(); // Block 11.1 M_s = backend()->newVector(M_Qh3); M_y = backend()->newVector(M_Qh3); // Block 11.2 M_z = backend()->newVector(M_Qh); M_t = backend()->newVector(M_Qh); // Create the interpolation and keep only the matrix auto pi_curl = I(_domainSpace=M_Qh3, _imageSpace=M_Vh); auto Igrad = Grad( _domainSpace=M_Qh, _imageSpace=M_Vh); M_P = pi_curl.matPtr(); M_C = Igrad.matPtr(); M_Pt = backend()->newMatrix(M_Qh3,M_Vh); M_Ct = backend()->newMatrix(M_Qh3,M_Vh); M_P->transpose(M_Pt,MATRIX_TRANSPOSE_UNASSEMBLED); M_C->transpose(M_Ct,MATRIX_TRANSPOSE_UNASSEMBLED); LOG(INFO) << "size of M_C = " << M_C->size1() << ", " << M_C->size2() << std::endl; LOG(INFO) << "size of M_P = " << M_P->size1() << ", " << M_P->size2() << std::endl; // Create vector of indices to create subvectors/matrices std::iota( M_Vh_indices.begin(), M_Vh_indices.end(), 0 ); // Vh indices in Xh std::iota( M_Qh_indices.begin(), M_Qh_indices.end(), M_Vh->nLocalDofWithGhost() ); // Qh indices in Xh // "Components" of Qh3 auto Qh3_dof_begin = M_Qh3->dof()->dofPointBegin(); auto Qh3_dof_end = M_Qh3->dof()->dofPointEnd(); int dof_comp, dof_idx; for( auto it = Qh3_dof_begin; it!= Qh3_dof_end; it++ ) { dof_comp = it->template get<2>(); //Component dof_idx = it->template get<1>(); //Global index M_Qh3_indices[dof_comp].push_back( dof_idx ); } // Subvectors for M_y (per component) M_y1 = M_y->createSubVector(M_Qh3_indices[0], true); M_y2 = M_y->createSubVector(M_Qh3_indices[1], true); #if FEELPP_DIM == 3 M_y3 = M_y->createSubVector(M_Qh3_indices[2], true); #endif // Subvectors for M_s (per component) M_s1 = M_y->createSubVector(M_Qh3_indices[0], true); M_s2 = M_y->createSubVector(M_Qh3_indices[1], true); #if FEELPP_DIM == 3 M_s3 = M_y->createSubVector(M_Qh3_indices[2], true); #endif this->setType ( t ); toc( "[PreconditionerAS] setup done ", FLAGS_v > 0 ); }
void AdvectionDiffusion::initModel() { // geometry is a ]0,1[x]0,1[ GeoTool::Node x1( 0,0 ); GeoTool::Node x2( 1,1 ); GeoTool::Rectangle R( meshSize,"Omega",x1,x2 ); R.setMarker( _type="line",_name="Inflow",_marker4=true ); R.setMarker( _type="line",_name="Bottom",_marker1=true ); R.setMarker( _type="line",_name="Top",_marker3=true ); R.setMarker( _type="line",_name="Outflow",_marker2=true ); R.setMarker( _type="surface",_name="Omega",_markerAll=true ); mesh = R.createMesh( _mesh=new mesh_type, _name="Omega" ); /* * The function space and some associate elements are then defined */ Xh = space_type::New( mesh ); RbXh = rbfunctionspace_type::New( this->shared_from_this() , mesh ); // allocate an element of Xh pT = element_ptrtype( new element_type( Xh ) ); // initialisation de A1 et A2 M_Aqm.resize( Qa() ); for(int q=0; q<Qa(); q++) { M_Aqm[q].resize( 1 ); M_Aqm[q][0] = backend->newMatrix( Xh, Xh ); } M_Fqm.resize( this->Nl() ); for(int l=0; l<Nl(); l++) { M_Fqm[l].resize( Ql(l) ); for(int q=0; q<Ql(l) ; q++) { M_Fqm[l][q].resize(1); M_Fqm[l][q][0] = backend->newVector( Xh ); } } D = backend->newMatrix( Xh, Xh ); F = backend->newVector( Xh ); using namespace Feel::vf; Feel::ParameterSpace<2>::Element mu_min( M_Dmu ); mu_min << 1, 0.1; M_Dmu->setMin( mu_min ); Feel::ParameterSpace<2>::Element mu_max( M_Dmu ); mu_max << 10,100; M_Dmu->setMax( mu_max ); element_type u( Xh, "u" ); element_type v( Xh, "v" ); std::cout << "Number of dof " << Xh->nLocalDof() << "\n"; // right hand side form1( Xh, M_Fqm[0][0][0], _init=true ) = integrate( markedfaces( mesh, "Bottom" ), id( v ) ); M_Fqm[0][0][0]->close(); form2( Xh, Xh, M_Aqm[0][0], _init=true ) = integrate( elements( mesh ), Py()*dxt( u )*id( v ) ); M_Aqm[0][0]->close(); form2( Xh, Xh, M_Aqm[1][0], _init=true ) = integrate( elements( mesh ), dxt( u )*dx( v ) ); M_Aqm[1][0]->close(); form2( Xh, Xh, M_Aqm[2][0], _init=true ) = integrate( elements( mesh ), dyt( u )*dy( v ) ); form2( Xh, Xh, M_Aqm[2][0] ) += integrate( markedfaces( mesh,"Top" ), - dyt( u )*Ny()*id( v ) - dy( u )*Ny()*idt( v ) + 20*idt( u )*id( v )/hFace() ); M_Aqm[2][0]->close(); form2( Xh, Xh, M_Aqm[3][0], _init=true ) = integrate( markedfaces( mesh,"Inflow" ), - dxt( u )*Nx()*id( v ) - dx( u )*Nx()*idt( v ) ); M_Aqm[3][0]->close(); form2( Xh, Xh, M_Aqm[4][0], _init=true ) = integrate( markedfaces( mesh,"Inflow" ), 20*idt( u )*id( v )/hFace() ); M_Aqm[4][0]->close(); M = backend->newMatrix( Xh, Xh ); form2( Xh, Xh, M, _init=true ) = integrate( elements( mesh ), id( u )*idt( v ) + grad( u )*trans( gradt( u ) ) ); M->close(); } // AdvectionDiffusion::run
void Microphone::init() { if ( M_is_initialized ) return; M_is_initialized = true; LOG(INFO) << "[MIC::init] starting...\n"; // geometry is a ]0,1[x]0,1[ GeoTool::Node x1( 0,0 ); GeoTool::Node x2( 1.5,0.25 ); GeoTool::Node x3( 0.5,0.25 ); GeoTool::Node x4( 1.5,0.65 ); GeoTool::Rectangle R1( meshSize,"R1",x1,x2 ); R1.setMarker( _type="line",_name="In",_marker4=true ); R1.setMarker( _type="surface",_name="Bottom",_markerAll=true ); GeoTool::Rectangle R2( meshSize,"R2",x3,x4 ); R2.setMarker( _type="surface",_name="Top",_markerAll=true ); mesh = ( R1+R2 ).createMesh<mesh_type>( "Omega" ); #if 0 /* * The function space and some associate elements are then defined */ Xh = space_type::New( mesh ); // allocate an element of Xh pT = element_ptrtype( new element_type( Xh ) ); // initialisation de A1 et A2 M_Aqm.resize( Qa() ); for(int q=0; q<Qa(); q++) M_Aqm[q].resize( 1 ); M_Aqm[0][0] = backend->newMatrix( Xh, Xh ); M_Aqm[1][0] = backend->newMatrix( Xh, Xh ); M_Aqm[2][0] = backend->newMatrix( Xh, Xh ); M_Fqm.resize( Nl() ); M_Fqm[0].resize( Ql( 0 ) ); M_Fqm[0][0].resize(1); M_Fqm[0][0][0] = backend->newVector( Xh ); D = backend->newMatrix( Xh, Xh ); F = backend->newVector( Xh ); using namespace Feel::vf; static const int N = 2; Feel::ParameterSpace<2>::Element mu_min( M_Dmu ); mu_min << 0.8, 10; M_Dmu->setMin( mu_min ); Feel::ParameterSpace<2>::Element mu_max( M_Dmu ); mu_max << 1.2,50; M_Dmu->setMax( mu_max ); element_type u( Xh, "u" ); element_type v( Xh, "v" ); LOG(INFO) << "Number of dof " << Xh->nLocalDof() << "\n"; // right hand side form1( Xh, M_Fqm[0][0][0], _init=true ) = integrate( elements( mesh ), id( v ) ); M_Fqm[0][0[0]->close(); form2( Xh, Xh, M_Aqm[0][0], _init=true ) = integrate( elements( mesh ), dxt( u )*dx( v ) ); M_Aqm[0][0]->close(); form2( Xh, Xh, M_Aqm[1][0], _init=true ) = integrate( elements( mesh ), dyt( u )*dy( v ) ); // Dirichlet condition apply to Bottom, only y-dir terms non zero because of normal being N()=(Nx(),Ny()) = (0,-1) // thus the simplification below with the signs which should -Ny() = +1 form2( Xh, Xh, M_Aqm[1][0] ) += integrate( markedfaces( mesh,"Bottom" ), dyt( u )*id( v )+dy( u )*idt( v )+M_gammabc*idt( u )*id( v )/hFace() ); M_Aqm[1][0]->close(); form2( Xh, Xh, M_Aqm[2][0], _init=true ) = integrate( elements( mesh ), idt( u )*id( v ) ); M_Aqm[2][0]->close(); M = backend->newMatrix( Xh, Xh ); form2( Xh, Xh, M, _init=true ) = integrate( elements( mesh ), id( u )*idt( v ) + grad( u )*trans( gradt( u ) ) ); M->close(); #endif LOG(INFO) << "[MIC::init] done\n"; } // Microphone::run
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