void TPZArtDiff::ContributeImplDiff(int dim, TPZFMatrix<REAL> &jacinv, TPZVec<FADREAL> &sol, TPZVec<FADREAL> &dsol, TPZFMatrix<STATE> &ek, TPZFMatrix<STATE> &ef, REAL weight, REAL timeStep, REAL deltaX) { TPZVec<STATE> solReal(sol.NElements()); int i; for(i = 0; i < sol.NElements(); i++) solReal[i] = sol[i].val(); REAL delta = Delta(deltaX, solReal); REAL constant = /*-*/ delta * weight * timeStep; TPZVec<TPZVec<FADREAL> > TauDiv; PrepareFastDiff(dim, jacinv, sol, dsol, TauDiv); TPZVec<FADREAL> Diff; TPZVec<REAL> gradv(dim); int j, k, l; int nstate = dim + 2; int neq = sol[0].size(); int nshape = neq/nstate; for(l=0;l<nshape;l++) { for(k=0;k<dim;k++) gradv[k] = dsol[k].dx/*fastAccessDx*/(/*k+*/l*nstate);// always retrieving this information from the first state variable... ODotOperator(gradv, TauDiv, Diff); for(i=0;i<nstate;i++) { ef(i+l*nstate,0) += constant * Diff[i].val(); for(j=0;j<neq;j++) ek(i+l*nstate, j) -= constant * Diff[i].dx/*fastAccessDx*/(j); } } }
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() ); }
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); }
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() ); }
void cv<Dim,Order>::run() { auto mesh = loadMesh(_mesh = new mesh_type ,_update = MESH_CHECK|MESH_UPDATE_FACES|MESH_UPDATE_EDGES|MESH_RENUMBER ); auto Xh = space_type::New( mesh ); auto Xhm1 = space_pm1_type::New( mesh ); auto Xhm1vec = space_pm1vec_type::New( mesh ); auto phi = Xh->element(); auto gphi = Xhm1vec->element(); auto gphi0 = Xhm1->element(); phi = vf::project(Xh,elements(mesh), Px()*Px() + Py()*Py() ); // P0 vector gphi = vf::project(Xhm1vec, elements(mesh), trans( gradv(phi) ) ); // P0 scalar auto gphi_compx = gphi.comp( ( ComponentType )0 ); gphi0 = vf::project(Xhm1, elements(mesh), idv(gphi_compx) ); auto e = exporter(_mesh = mesh, _name = "myExporter"); e->add( "phi", phi ); e->add( "grad_phi", gphi ); e->add( "grad_phi0", gphi0 ); e->save(); }
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
element_type grad_error_project(const space_ptrtype & Xh, const element_type & T, const double & val) { auto gproj = grad_exact_project(Xh, val); return (gproj - gradv(T)); }