void Ortho() { cout << "Basis = Dubiner Orthonormal on Simplex !\n"; cout << "N = " << N << endl; D_Order << N << endl; typedef T value_type; timer t_tot; timer t; timeout( t.elapsed() ); cout << "Basis Construction ... "; t.restart(); const OrthonormalPolynomialSet<2, N, Scalar, value_type, Simplex> Dubiner_Basis; //const Dubiner<2, N, Normalized<false>, value_type> Dubiner_Basis; timeout( t.elapsed() ); const int_type Dim_Basis = Dubiner_Basis.basis().coeff().size1(); cout << "Construction of the Integration Method ... \n"; const Gauss<Simplex<2,1>, N+N, value_type> Quad; /** Matrix construction **/ /** Stiffness **/ cout << "\n/********************************/" << endl; cout << "Construction of Stiffness Matrix..." <<endl; cout <<"Dubiner Basis Derivation... "; t.restart(); const ublas::vector<ublas::matrix<value_type> > Diff( Dubiner_Basis.derivate( Quad.points() ) ); timeout( t.elapsed() ); cout << "Wgts construction ... "; t.restart(); ublas::diagonal_matrix<value_type> Wgts( Quad.weights().size() ); for ( int_type i=0; i < Wgts.size1() ; ++i ) { Wgts( i,i ) = Quad.weights()( i ); } timeout( t.elapsed() ); cout << "Stiffness numeric construction ... "; t.restart(); #if 1 cout << "prod ... "; ublas::matrix<value_type> A ( ublas::prod( Diff( 0 ), Wgts ) ); A = ublas::prod( A, ublas::trans( Diff( 0 ) ) ); ublas::matrix<value_type> B ( ublas::prod( Diff( 1 ), Wgts ) ); B = ublas::prod( B, ublas::trans( Diff( 1 ) ) ); #else cout << "axpy_prod ... "; ublas::matrix<value_type> A2( Diff( 0 ).size1(), Wgts.size2() ); ublas::matrix<value_type> A( A2.size1(), Diff( 0 ).size1() ); ublas::matrix<value_type> B2( Diff( 1 ).size1(), Wgts.size2() ); ublas::matrix<value_type> B( B2.size1(), Diff( 1 ).size1() ); ublas::matrix<value_type> tDiff_0( ublas::trans( Diff( 0 ) ) ); ublas::matrix<value_type> tDiff_1( ublas::trans( Diff( 1 ) ) ); ublas::axpy_prod( Diff( 0 ), Wgts, A2 ); ublas::axpy_prod( A2, tDiff_0, A ); ublas::axpy_prod( Diff( 1 ), Wgts, B2 ); ublas::axpy_prod( B2, tDiff_1, B ); #endif ublas::matrix<value_type> Stiff( A + B ); timeout( t.elapsed() ); /** Mass **/ cout << "\n/********************************/" << endl; cout << "Construction of the Mass Matrix..." << endl; cout <<"Dubiner Basis Evaluation... "; t.restart(); ublas::matrix<value_type> Psi = Dubiner_Basis.evaluate( Quad.points() ); timeout( t.elapsed() ); cout << "Mass numeric construction ... "; t.restart(); #if 1 cout << "prod ... "; ublas::matrix<value_type> Mass ( ublas::prod( Psi, Wgts ) ); Mass = ublas::prod( Mass, ublas::trans( Psi ) ); #else cout << "axpy_prod ... "; ublas::matrix<value_type> M0( Psi.size1(), Wgts.size2() ); ublas::matrix<value_type> Mass( Psi.size1(), Psi.size1() ); ublas::matrix<value_type> tPsi( ublas::trans( Psi ) ); ublas::axpy_prod( Psi, Wgts, M0 ); ublas::axpy_prod( M0, tPsi, Mass ); #endif timeout( t.elapsed() ); /** Global **/ cout << "\n/********************************/" << endl; cout << "Assembly of the Global matrix ..."<<endl; ublas::matrix<value_type> Global( Stiff + Mass ); /** Condition number estimation **/ cout << "Condition number estimation ... "; t.restart(); value_type condition = cond2<value_type>( Global ); timeout( t.elapsed() ); cout << "Condition number = " << condition << endl; D_cond << condition << endl; /** Right hand side **/ cout << "Construction of the RHS ... "; t.restart(); ublas::vector<value_type> F( Quad.points().size2() ); ublas::vector<value_type> G0( Quad.fpoints( 0 ).size2() ); ublas::vector<value_type> G1( Quad.fpoints( 1 ).size2() ); ublas::vector<value_type> G2( Quad.fpoints( 2 ).size2() ); ublas::diagonal_matrix<value_type> Wgts0( Quad.weights( 0 ).size() ); ublas::diagonal_matrix<value_type> Wgts1( Quad.weights( 1 ).size() ); ublas::diagonal_matrix<value_type> Wgts2( Quad.weights( 2 ).size() ); for ( int_type i=0; i < F.size(); ++i ) { F( i ) = f<value_type>( Quad.point( i ) ); } F= ublas::prod( Wgts,F ); F= ublas::prod( Psi,F ); for ( int_type i=0; i < Wgts0.size1() ; ++i ) { Wgts0( i,i ) = Quad.weights( 0 )( i ); G0( i ) = g0<value_type>( ublas::column( Quad.fpoints( 0 ), i ) ); } G0= ublas::prod( Wgts0,G0 ); G0= ublas::prod( Dubiner_Basis.evaluate( Quad.fpoints( 0 ) ),G0 ); for ( int_type i=0; i < Wgts1.size1() ; ++i ) { Wgts1( i,i ) = Quad.weights( 1 )( i ); G1( i ) = g1<value_type>( ublas::column( Quad.fpoints( 1 ), i ) ); } G1= ublas::prod( Wgts1,G1 ); G1= ublas::prod( Dubiner_Basis.evaluate( Quad.fpoints( 1 ) ),G1 ); for ( int_type i=0; i < Wgts2.size1() ; ++i ) { Wgts2( i,i ) = Quad.weights( 2 )( i ); G2( i ) = g2<value_type>( ublas::column( Quad.fpoints( 2 ), i ) ); } G2= ublas::prod( Wgts2,G2 ); G2= ublas::prod( Dubiner_Basis.evaluate( Quad.fpoints( 2 ) ),G2 ); /** Global right-hand side assembly **/ F+=G0+G1+G2; timeout( t.elapsed() ); /** System Resolution **/ cout << "System Resolution ... "; t.restart(); ublas::vector<value_type> Sol( Dim_Basis ); LU<ublas::matrix<value_type> > lu( Global ); Sol = lu.solve( F ); timeout( t.elapsed() ); /** L_2 Error Estimation **/ cout << "L_2 Error estimation ... "; t.restart(); ublas::vector<value_type> Error( Quad.points().size2() ); for ( int_type i=0; i< Error.size(); ++i ) Error( i ) = exact_sol<value_type>( ublas::column( Quad.points(), i ) ); Error = Error - ublas::prod( ublas::trans( Psi ),Sol ); Error = ublas::element_prod( Error,Error ); value_type err = sqrt( ublas::inner_prod( Error, Quad.weights() ) ); timeout( t.elapsed() ); cout << "\nErreur L_2= " << err << endl; D_error_L2 << err << endl; /** H¹ Error Estimation **/ cout << "H^1 Error estimation ... "; t.restart(); ublas::vector<value_type> Error_H1( Quad.points().size2() ); ublas::vector<value_type> Approx ( Error_H1.size() ); ublas::vector<value_type> Approx_x( Error_H1.size() ); ublas::vector<value_type> Approx_y( Error_H1.size() ); for ( uint16_type i=0; i< Error_H1.size(); ++i ) { Approx( i ) = exact_sol<value_type>( ublas::column( Quad.points(), i ) ); Approx_x( i ) = dexact_sol_x<value_type>( ublas::column( Quad.points(), i ) ); Approx_y( i ) = dexact_sol_y<value_type>( ublas::column( Quad.points(), i ) ); } ublas::vector<value_type> Delta( Approx - ublas::prod( ublas::trans( Psi ),Sol ) ); ublas::vector<value_type> Delta_x( Approx_x - ublas::prod( ublas::trans( Diff( 0 ) ),Sol ) ); ublas::vector<value_type> Delta_y( Approx_y - ublas::prod( ublas::trans( Diff( 1 ) ),Sol ) ); Error_H1 = ublas::element_prod( Delta,Delta ) + ublas::element_prod( Delta_x,Delta_x ) + ublas::element_prod( Delta_y,Delta_y ); value_type err_H1 = sqrt( ublas::inner_prod( Error_H1, Quad.weights() ) ); timeout( t.elapsed() ); cout << "\nErreur H^1= " << err_H1 << endl; D_error << err_H1 << endl; double tol = 10*pow( 1.0/pow( N,N ), 0.2 ); cout << "\n10*N^{-N/5} = " << tol << endl; D_tol << tol << endl; cout << "\n-------------------------------\n"; cout << "Total runtime = "; double timing( t_tot.elapsed() ); timeout( timing ); cout << "-------------------------------\n"; cout << "\n\n"; D_timing << timing << endl; BOOST_CHECK( ( err_H1 <= tol ) ); }
void Boundary() { cout << "Basis = Boundary Adapted on Simplex !\n"; cout << "N = " << N << endl; B_Order << N << endl; typedef T value_type; cout << "Construction of the Integration Method ... "; timer t_tot; timer t; const Gauss<Simplex<2,1>, N+N, value_type> Quad; cout << t.elapsed() << " seconds.\n"; cout << "Basis Construction ... "; t.restart(); const BoundaryAdaptedPolynomialSet<2, N, Scalar, value_type, Simplex> BA_Basis; timeout( t.elapsed() ); const int_type Dim_Basis = BA_Basis.basis().coeff().size1(); /** Matrix construction **/ /** Stiffness **/ cout << "\n/********************************/" << endl; cout << "Construction of Stiffness Matrix..." <<endl; cout <<"Boundary Adapted Basis Derivation... "; t.restart(); const ublas::vector<ublas::matrix<value_type> > Diff( BA_Basis.derivate( Quad.points() ) ); timeout( t.elapsed() ); cout << "Wgts construction ... "; t.restart(); ublas::diagonal_matrix<value_type> Wgts( Quad.weights().size() ); for ( int_type i=0; i < Wgts.size1() ; ++i ) { Wgts( i,i ) = Quad.weights()( i ); } timeout( t.elapsed() ); cout << "Stiffness numeric construction ... "; t.restart(); ublas::matrix<value_type> A ( ublas::prod( Diff( 0 ), Wgts ) ); A = ublas::prod( A, ublas::trans( Diff( 0 ) ) ); ublas::matrix<value_type> B ( ublas::prod( Diff( 1 ), Wgts ) ); B = ublas::prod( B, ublas::trans( Diff( 1 ) ) ); ublas::matrix<value_type> Stiff( A + B ); timeout( t.elapsed() ); /** Mass **/ cout << "\n/********************************/" << endl; cout << "Construction of the Mass Matrix..." << endl; cout <<"Boundary Adapted Basis Evaluation... "; t.restart(); ublas::matrix<value_type> Psi = BA_Basis.evaluate( Quad.points() ); timeout( t.elapsed() ); cout << "Mass numeric construction ... "; t.restart(); ublas::matrix<value_type> Mass ( ublas::prod( Psi, Wgts ) ); Mass = ublas::prod( Mass, ublas::trans( Psi ) ); timeout( t.elapsed() ); if ( N == 14 ) { #if 0 PrintMatlab<value_type>( Mass ); #else PrintMatlab<value_type>( Stiff ); #endif } /** Global **/ cout << "\n/********************************/" << endl; cout << "Assembly of the Global matrix ..."<<endl; ublas::matrix<value_type> Global( Stiff + Mass ); /** Right hand side **/ cout << "Construction of the RHS ... "; t.restart(); ublas::vector<value_type> F( Quad.points().size2() ); ublas::vector<value_type> G0( Quad.fpoints( 0 ).size2() ); ublas::vector<value_type> G2( Quad.fpoints( 2 ).size2() ); ublas::diagonal_matrix<value_type> Wgts0( Quad.weights( 0 ).size() ); ublas::diagonal_matrix<value_type> Wgts2( Quad.weights( 2 ).size() ); for ( int_type i=0; i < F.size(); ++i ) { F( i ) = f<value_type>( Quad.point( i ) ); } F= ublas::prod( Wgts,F ); F= ublas::prod( Psi,F ); for ( int_type i=0; i < Wgts0.size1() ; ++i ) { Wgts0( i,i ) = Quad.weights( 0 )( i ); G0( i ) = g0<value_type>( ublas::column( Quad.fpoints( 0 ), i ) ); } G0= ublas::prod( Wgts0,G0 ); G0= ublas::prod( BA_Basis.evaluate( Quad.fpoints( 0 ) ),G0 ); for ( int_type i=0; i < Wgts2.size1() ; ++i ) { Wgts2( i,i ) = Quad.weights( 2 )( i ); G2( i ) = g2<value_type>( ublas::column( Quad.fpoints( 2 ), i ) ); } G2= ublas::prod( Wgts2,G2 ); G2= ublas::prod( BA_Basis.evaluate( Quad.fpoints( 2 ) ),G2 ); /** Global right-hand side assembly **/ F+=G0+G2; timeout( t.elapsed() ); /** Imposing Dirichlet boundary conditions **/ cout << "Imposing Dirichlet boundary conditions ... "; t.restart(); ublas::matrix<value_type> Global2( Global.size1()-( N-1 ), Global.size2()-( N-1 ) ); ublas::vector<value_type> F2( F.size()- ( N-1 ) ); for ( int_type i= 0 ; i < 3+( N-1 ) ; ++i ) { for ( int_type j= 0 ; j < 3+( N-1 ) ; ++j ) { Global2( i,j ) = Global( i,j ); } for ( int_type j=3+2*( N-1 ); j < Global.size1() ; ++j ) { Global2( i,j-( N-1 ) ) = Global( i,j ); } F2( i ) = F( i ); } for ( int_type i=3+2*( N-1 ); i < Global.size1() ; ++i ) { for ( int_type j= 0 ; j < 3+( N-1 ) ; ++j ) { Global2( i-N+1,j ) = Global( i,j ); } for ( int_type j=3+2*( N-1 ); j < Global.size1() ; ++j ) { Global2( i-N+1,j-( N-1 ) ) = Global( i,j ); } F2( i-N+1 ) = F( i ); } timeout( t.elapsed() ); /** Condition number estimation **/ cout << "Condition number estimation ... "; t.restart(); value_type condition = cond2<value_type>( Global2 ); timeout( t.elapsed() ); cout << "Condition number = " << condition << endl; B_cond << condition << endl; /** System Resolution **/ cout << "System Resolution ... "; t.restart(); ublas::vector<value_type> Sol( Dim_Basis ); LU<ublas::matrix<value_type> > lu( Global2 ); ublas::vector<value_type> Sol2( Dim_Basis-N+1 ); Sol2 = lu.solve( F2 ); /** Expanding Solution on the Dirichlet boundary **/ for ( int_type i= 0 ; i < 3+( N-1 ) ; ++i ) { Sol( i ) = Sol2( i ); } for ( int_type i= 3+( N-1 ) ; i < 3+2*( N-1 ) ; ++i ) { Sol( i ) = value_type( 0.0 ); } for ( int_type i=3+2*( N-1 ); i < Global.size1() ; ++i ) { Sol( i ) = Sol2( i-N+1 ); } timeout( t.elapsed() ); /** Error Estimation **/ cout << "Error estimation ... "; t.restart(); ublas::vector<value_type> Error( Quad.points().size2() ); for ( int_type i=0; i< Error.size(); ++i ) Error( i ) = exact_sol<value_type>( ublas::column( Quad.points(), i ) ); Error = Error - ublas::prod( ublas::trans( Psi ),Sol ); Error = ublas::element_prod( Error,Error ); value_type err = sqrt( ublas::inner_prod( Error, Quad.weights() ) ); timeout( t.elapsed() ); cout << "\nErreur L_2 = " << err << endl; B_error_L2 << err << endl; /** H¹ Error Estimation **/ cout << "H^1 Error estimation ... "; t.restart(); ublas::vector<value_type> Error_H1( Quad.points().size2() ); ublas::vector<value_type> Approx ( Error_H1.size() ); ublas::vector<value_type> Approx_x( Error_H1.size() ); ublas::vector<value_type> Approx_y( Error_H1.size() ); for ( uint16_type i=0; i< Error_H1.size(); ++i ) { Approx( i ) = exact_sol<value_type>( ublas::column( Quad.points(), i ) ); Approx_x( i ) = dexact_sol_x<value_type>( ublas::column( Quad.points(), i ) ); Approx_y( i ) = dexact_sol_y<value_type>( ublas::column( Quad.points(), i ) ); } ublas::vector<value_type> Delta( Approx - ublas::prod( ublas::trans( Psi ),Sol ) ); ublas::vector<value_type> Delta_x( Approx_x - ublas::prod( ublas::trans( Diff( 0 ) ),Sol ) ); ublas::vector<value_type> Delta_y( Approx_y - ublas::prod( ublas::trans( Diff( 1 ) ),Sol ) ); Error_H1 = ublas::element_prod( Delta,Delta ) + ublas::element_prod( Delta_x,Delta_x ) + ublas::element_prod( Delta_y,Delta_y ); value_type err_H1 = sqrt( ublas::inner_prod( Error_H1, Quad.weights() ) ); timeout( t.elapsed() ); cout << "\nErreur H^1= " << err_H1 << endl; B_error << err_H1 << endl; double tol = 10*pow( 1.0/pow( N,N ), 0.2 ); cout << "\n10*N^{-N/5} = " << tol << endl; B_tol << tol << endl; cout << "\n-------------------------------\n"; cout << "Total runtime = "; double timing( t_tot.elapsed() ); timeout( timing ); cout << "-------------------------------\n"; cout << "\n\n"; B_timing << timing << endl; BOOST_CHECK( ( err_H1 <= tol ) ); }