Raw File
/* -*- 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=cpp: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: 2010-03-04

  Copyright (C) 2010 Universitť Joseph Fourier (Grenoble I)

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

  This library 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
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/
/**
   \file testhermite.hpp
   \author Christophe Prud'homme <christophe.prudhomme@feelpp.org>
   \date 2010-03-04
 */
#ifndef __TestHermite_H
#define __TestHermite_H 1

#include <feel/feelpoly/hermite.hpp>
#include <feel/feelpoly/im.hpp>

using namespace Feel;


/*!
  \class TestHermite
  \brief Test Hermite Polynomials

  Test some properties of the Hermite polynomials

  @author Christophe Prud'homme
  @see
*/
template<typename FE>
class TestHermite
{
public:


    /** @name Typedefs
     */
    //@{

    typedef typename FE::value_type value_type;
    typedef typename FE::matrix_type matrix_type;

    //@}


    /** @name Constructors, destructor
     */
    //@{

    TestHermite( value_type eps = value_type( 3000 )*Feel::type_traits<value_type>::epsilon() )
        :
        M_eps( eps )
    {}
    TestHermite( TestHermite const & tl )
        :
        M_eps( tl.M_eps )
    {}
    ~TestHermite() {}

    //@}

    /** @name Operator overloads
     */
    //@{
    void operator()() const
    {
        std::ostringstream os;
        os << "hermite." << FE::nDim << "." << FE::nOrder;

        //BOOST_CHECK( fe.familyName() == os.str() );
        if ( fe.name() != os.str() )
        {
            std::cout << "[FAILURE] invalid name : " << fe.name() << " instead of " << os.str() << "\n";
        }

        BOOST_MESSAGE( "checkIdentity()\n" );
        checkIdentity();
        BOOST_MESSAGE( "checkDiff()\n" );
        checkDiff();
    }


    //@}

protected:

    void
    checkDiff() const
    {
        const int nDim = fe.nDim;

        if ( nDim == 2 ) return;

        //BOOST_TEST_MESSAGE( "Checking Hermite polynomials differentiation" );

        ublas::vector<value_type> error( FE::nDim );
        ublas::vector<matrix_type> der( fe.derivate( fe.points() ) );
        glas::clean( der[0],1e-10 );
        BOOST_TEST_MESSAGE( "der[0]=" << der[0] << "\n" );

        matrix_type result( der[0].size1(), der[0].size2() );
        result = ublas::zero_matrix<value_type>( result.size1(), result.size2() );

        for ( int d = 0; d < nDim; ++d )
        {
            ublas::subrange( result, ( d+1 )*( nDim+1 ), ( d+2 )*( nDim+1 ), ( d )*( nDim+1 ), ( d+1 )*( nDim+1 ) ) = ublas::identity_matrix<value_type>( nDim+1 );
            ublas::subrange( result, ( d+1 )*( nDim+1 ), ( d+2 )*( nDim+1 ), ( d+1 )*( nDim+1 ), ( d+2 )*( nDim+1 ) ) = ublas::identity_matrix<value_type>( nDim+1 );
        }

        BOOST_TEST_MESSAGE( "result = " << result << "\n" );

        for ( int i = 0; i < FE::nDim; ++i )
            error[i] = ublas::norm_frobenius( der[i] - result );

        //error[i] = ublas::norm_frobenius( der[i] - fe.derivate( i ).evaluate( fe.points() ) );

#if defined(  USE_TEST )
        BOOST_TEST_MESSAGE( "[checkDiff] Hermite " << " dim : " << FE::nDim << " order : " << FE::nOrder << " error: " << error << " eps: " << M_eps  );

        for ( int i = 0; i < FE::nDim; ++i )
            BOOST_CHECK(  error[i] < M_eps );

#endif
    }

    void
    checkIdentity() const
    {
        BOOST_MESSAGE( "Checking Hermite polynomials identity" );
        const int nDim = fe.nDim;
        BOOST_TEST_MESSAGE( "points=" << fe.points() );
        BOOST_TEST_MESSAGE( "Hemite at points=" << fe.evaluate( fe.points() ) );
        matrix_type eval_at_pts( FE::polyset_type::toMatrix( fe.evaluate( fe.points() ) ) );
        matrix_type result( eval_at_pts.size1(), eval_at_pts.size2() );
        result = ublas::zero_matrix<value_type>( result.size1(), result.size2() );
        ublas::subrange( result, 0, nDim+1, 0, nDim+1 ) = ublas::identity_matrix<value_type>( nDim+1 );

        for ( int d = 0; d < nDim; ++d )
            ublas::subrange( result, 0, nDim+1, ( d+1 )*( nDim+1 ), ( d+2 )*( nDim+1 ) ) = ublas::identity_matrix<value_type>( nDim+1 );

        if ( nDim == 2 )
            result( fe.numPoints-1, fe.numPoints-1 ) = 1;

        BOOST_TEST_MESSAGE( "result = " << result << "\n" );
        BOOST_TEST_MESSAGE( "Hermite eval_at_pts = " << eval_at_pts  );
        value_type error = ublas::norm_frobenius( eval_at_pts-result );

#if defined(  USE_TEST )
        BOOST_TEST_MESSAGE( "[checkIdentity] Hermite "
                            << " dim : " << FE::nDim
                            << " order : " << FE::nOrder
                            << " epsilon = " << M_eps
                            << " error = " << error );
        BOOST_CHECK( error < M_eps );
#endif
    }
private:
    FE fe;
    value_type M_eps;
};
#endif /* __TestHermite_H */

back to top