Raw File
test_integration_opt.cpp
/* -*- mode: c++; coding: utf-8; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; show-trailing-whitespace: t -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4

   This file is part of the Feel library

   Author(s): Christophe Prud'homme <christophe.prudhomme@feelpp.org>
   Date: 2011-07-09

   Copyright (C) 2011 Universite Joseph Fourier (Grenoble I)

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#define USE_BOOST_TEST 1

#define BOOST_TEST_MODULE integration_opt testsuite

#include <testsuite/testsuite.hpp>

#include <feel/options.hpp>

#include <feel/feelalg/backend.hpp>
#include <feel/feeldiscr/functionspace.hpp>
#include <feel/feelfilters/creategmshmesh.hpp>
#include <feel/feelfilters/savegmshmesh.hpp>
#include <feel/feelfilters/domain.hpp>
#include <feel/feelvf/vf.hpp>
#include <feel/feelfilters/exporter.hpp>
#include <feel/feelfilters/geotool.hpp>


using namespace Feel;
using namespace Feel::vf;

double hsize = 2;
int straighten = 1;
int nlevels = 3;

inline
Feel::AboutData
makeAbout()
{
    Feel::AboutData about( "test_integration_opt" ,
                           "test_integration_opt" ,
                           "0.1",
                           "integration tests",
                           Feel::AboutData::License_GPL,
                           "Copyright (C) 2006-2010 Universite Joseph Fourier (Grenoble I)" );

    about.addAuthor( "Christophe Prud'homme", "developer", "christophe.prudhomme@feelpp.org", "" );
    return about;

}

po::options_description
makeOptions()
{
    // Declare the supported options.
    namespace po = boost::program_options;
    po::options_description desc( "Allowed options" );
    desc.add_options()
    ( "help", "produce help message" )
    ( "hsize", po::value<double>( &hsize )->default_value( 2 ), "h size" )
    ( "straight", po::value<int>( &straighten )->default_value( 1 ), "straighten" )
    ( "nlevels", po::value<int>( &nlevels )->default_value( 3 ), "number of refinement levels" )
    ( "shape", po::value<std::string>()->default_value( "pie" ), "pie,circle" )
    ;
    return desc.add( Feel::feel_options() );
}
#if USE_BOOST_TEST

FEELPP_ENVIRONMENT_WITH_OPTIONS( makeAbout(), makeOptions() )

BOOST_AUTO_TEST_SUITE( integration_opt )

typedef boost::mpl::list<boost::mpl::pair<mpl::int_<2>,mpl::int_<2> >,
        boost::mpl::pair<mpl::int_<2>,mpl::int_<3> >,
        boost::mpl::pair<mpl::int_<2>,mpl::int_<4> >,
        boost::mpl::pair<mpl::int_<3>,mpl::int_<2> >,
        boost::mpl::pair<mpl::int_<3>,mpl::int_<3> >
        > dim_types;
BOOST_AUTO_TEST_CASE_TEMPLATE( integration_opt, T, dim_types )
{
    BOOST_TEST_MESSAGE( "============================================================\n"
                        << "Dim: " << T::first::value << "  Order: " << T::second::value << "\n" );

    using namespace Feel;
    using namespace Feel::vf;

    typedef Mesh<Simplex<T::first::value,T::second::value> > mesh_type;
    auto mesh = createGMSHMesh( _mesh=new mesh_type,
                                _desc=domain( _name=( boost::format( "ellipsoid-%1%-%2%" ) % T::first::value % T::second::value ).str() ,
                                        _usenames=true,
                                        _shape="ellipsoid",
                                        _dim=T::first::value,
                                        _order=T::second::value,
                                        _h=hsize ),
                                _update=MESH_CHECK|MESH_UPDATE_FACES|MESH_UPDATE_EDGES,
                                _straighten=straighten );
    saveGMSHMesh( _mesh=mesh, _filename=( boost::format( "ellipsoid-%1%-%2%-%3%-saved.msh" ) % T::first::value % T::second::value % straighten ).str() );

    boost::timer ti;
    auto i1 = integrate( _range=elements( mesh ), _expr=cst( 1. ), _geomap=GeomapStrategyType::GEOMAP_HO ).evaluate().norm();
    std::cout << "Ho: " << ti.elapsed() << "s\n";
    ti.restart();
    auto i2 = integrate( _range=elements( mesh ), _expr=cst( 1. ), _geomap=GeomapStrategyType::GEOMAP_OPT ).evaluate().norm();
    std::cout << "Opt: " << ti.elapsed() << "s\n";
    ti.restart();
    auto i3 = integrate( _range=elements( mesh ),  _expr=cst( 1. ), _geomap=GeomapStrategyType::GEOMAP_O1 ).evaluate().norm();
    std::cout << "P1: " << ti.elapsed() << "s\n";
    ti.restart();

    BOOST_CHECK_CLOSE( i1, i2, 1e-12 );
    BOOST_TEST_MESSAGE( "ho = " << std::scientific << std::setprecision( 16 ) << i1 << "\n" <<
                        "opt = " << std::scientific << std::setprecision( 16 ) << i2 << "\n"
                        "p1 = " << std::scientific << std::setprecision( 16 ) << i3 << "\n"
                        << "\n" );


}

typedef boost::mpl::list<mpl::int_<1>,mpl::int_<2>, mpl::int_<3>, mpl::int_<4>, mpl::int_<5> > order_types;
BOOST_AUTO_TEST_CASE_TEMPLATE( test_pie, T, order_types )
{
    BOOST_TEST_MESSAGE( "============================================================\n"
                        << "Order: " << T::value << "\n" );


    po::variables_map vm = Environment::vm();

    using namespace Feel;
    using namespace Feel::vf;
    typedef Mesh<Simplex<2,T::value> > mesh_type;
    typedef boost::shared_ptr<mesh_type> mesh_ptrtype;
    mesh_ptrtype mesh;
    std::string shape =  vm["shape"].template as<std::string>();
    std::map<std::string,std::vector<boost::tuple<double,double,double,double> > > ho;
    double exact=1;

    for ( int l = 1; l <= nlevels; ++l )
    {
        double meshSize= hsize/std::pow( 2.,l );

        if ( shape == "pie" )

        {
            exact = M_PI/8;
            GeoTool::Node C( 0,0 );
            GeoTool::Node A( 1,0. );
            GeoTool::Node B( std::sqrt( 2. )/2,std::sqrt( 2. )/2 ); // 45D

            GeoTool::Pie Pie( meshSize,"pie", C, A, B );
            Pie.setMarker(_type="line",_name="Boundary",_markerAll=true);
            Pie.setMarker(_type="surface",_name="Omega",_markerAll=true);

            mesh = Pie.createMesh(_mesh=new mesh_type,
                                  _name=( boost::format( "pie-%1%-%2%" ) % T::value % l ).str() );
        }

        if ( shape == "circle" )
        {
            exact = M_PI;
            GeoTool::Node C( 0,0 );
            GeoTool::Node A( 1,0. );
            GeoTool::Circle Circle( meshSize,"circle", C, A );
            Circle.setMarker(_type="line",_name="Boundary",_markerAll=true);
            Circle.setMarker(_type="surface",_name="Omega",_markerAll=true);

            mesh = Circle.createMesh(_mesh=new mesh_type,
                                     _name=( boost::format( "circle-%1%-%2%" ) % T::value % l ).str() );
        }


        boost::timer ti;
        double i1 =  integrate( _range=elements( mesh ), _expr=cst( 1. ), _geomap=GeomapStrategyType::GEOMAP_HO ).evaluate().norm();
        ho["ho"].push_back( boost::make_tuple( meshSize, i1, math::abs( i1-exact ), ti.elapsed() ) );
        ti.restart();
        double i2 = integrate( _range=elements( mesh ), _expr=cst( 1. ), _geomap=GeomapStrategyType::GEOMAP_OPT ).evaluate().norm();
        ho["opt"].push_back( boost::make_tuple( meshSize, i2, math::abs( i2-exact ), ti.elapsed() ) );
        ti.restart();
        BOOST_CHECK_CLOSE( i1, i2, 1e-12 );
        //std::cout << "Opt: " << ti.elapsed() << "s\n";
        double i3 = integrate( _range=elements( mesh ),  _expr=cst( 1. ), _geomap=GeomapStrategyType::GEOMAP_O1 ).evaluate().norm();
        ho["p1"].push_back( boost::make_tuple( meshSize, i3, math::abs( i3-exact ), ti.elapsed() ) );
        //std::cout << "P1: " << ti.elapsed() << "s\n";
    }


    for ( auto it = ho.begin(); it != ho.end(); ++ it )
    {
        BOOST_TEST_MESSAGE( std::setw( 10 ) << std::right << "levels" <<
                            std::setw( 10 ) << std::right << "h"  <<
                            std::setw( 15 ) << std::right << it->first <<
                            std::setw( 15 ) << std::right << "error" <<
                            std::setw( 15 ) << std::right << "ROC" <<
                            std::setw( 10 ) << std::right << "Time(s)"
                            << "\n" );

        for ( int l = 1; l <= nlevels; ++l )
        {
            auto data = it->second;
            double roc = 1;

            if ( l > 1 )
                roc = std::log10( data[l-2].template get<2>()/data[l-1].template get<2>() )/std::log10( data[l-2].template get<0>()/data[l-1].template get<0>() );

            BOOST_TEST_MESSAGE( std::right << std::setw( 10 ) << l <<
                                std::right << std::setw( 10 ) << data[l-1].template get<0>() <<
                                std::right << std::setw( 15 ) << std::scientific << std::setprecision( 5 ) << data[l-1].template get<1>() <<
                                std::right << std::setw( 15 ) << std::scientific << std::setprecision( 5 ) << data[l-1].template get<2>() <<
                                std::right << std::setw( 15 ) << std::scientific << std::setprecision( 5 ) << roc <<
                                std::right << std::setw( 10 ) << std::scientific << std::setprecision( 2 ) << data[l-1].template get<3>() << "\n" );
        }
    }

}
BOOST_AUTO_TEST_SUITE_END()

#else

int
main( int argc, char** argv )
{

}

#endif
back to top