https://github.com/feelpp/feelpp
Raw File
Tip revision: a1d1df957b672495252b9b4642bb556e44fa6dca authored by Christophe Prud'homme on 23 November 2021, 00:21:36 UTC
up #1734
Tip revision: a1d1df9
test_disc.cpp
/* -*- mode: c++; coding: utf-8; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; show-trailing-whitespace: t  -*-

  This file is part of the Feel library

  Author(s): Christophe Prud'homme <christophe.prudhomme@feelpp.org>
       Date: 2010-10-21

  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 test_disc.cpp
   \author Christophe Prud'homme <christophe.prudhomme@feelpp.org>
   \date 2010-10-21
 */

// give a name to the testsuite
#define BOOST_TEST_MODULE discontinuity testsuite
// disable the main function creation, use our own
//#define BOOST_TEST_NO_MAIN


#include <feel/feelcore/testsuite.hpp>

#include <feel/feelalg/backend.hpp>

#include <feel/options.hpp>
#include <feel/feelcore/environment.hpp>
#include <feel/feelmesh/geoentity.hpp>
#include <feel/feelmesh/refentity.hpp>
#include <feel/feeldiscr/functionspace.hpp>
#include <feel/feeldiscr/mesh.hpp>
#include <feel/feelmesh/filters.hpp>
#include <feel/feelpoly/im.hpp>
#include <feel/feelfilters/creategmshmesh.hpp>

#include <feel/feelvf/vf.hpp>

const double DEFAULT_MESH_SIZE=0.1;

namespace Feel
{
template<typename T, int Dim, int Order = 1>
struct imesh
{
    typedef Simplex<Dim, Order> convex_type;
    typedef Mesh<convex_type, T > type;
    typedef std::shared_ptr<type> ptrtype;
};


template<typename value_type = double, int Dim=2, int Order =2>
struct test_disc: public Application
{
    typedef typename imesh<value_type,Dim>::convex_type convex_type;
    typedef typename imesh<value_type,Dim>::type mesh_type;
    typedef typename imesh<value_type,Dim>::ptrtype mesh_ptrtype;
    typedef DiscontinuousInterfaces<fusion::vector<mpl::vector<mpl::int_<4>, mpl::int_<6>, mpl::int_<7> > > > discontinuity_type;
    typedef bases<Lagrange<Order, Scalar, discontinuity_type> > basis_type;
    typedef FunctionSpace<mesh_type, basis_type> space_type;
    typedef std::shared_ptr<space_type> space_ptrtype;
    typedef typename space_type::element_type element_type;

    test_disc()
        :
        Application(),
        backend( Backend<double>::build( soption( _name="backend" ) ) ),
        meshSize( this->vm()["hsize"].template as<double>() ),
        shape( this->vm()["shape"].template as<std::string>() ),
        mesh()
    {
        mesh = createGMSHMesh( _mesh=new mesh_type,
                               _desc=createMesh(),
                               _update=MESH_CHECK|MESH_UPDATE_EDGES|MESH_UPDATE_FACES );
        Xh = space_type::New( mesh );
    }
    gmsh_ptrtype createMesh()
    {
        std::ostringstream ostr;
        ostr << "Mesh.MshFileVersion = " << 2 << ";\n"
             << "a=" << -1 << ";\n"
             << "b=" << 1 << ";\n"
             << "c=" << -1 << ";\n"
             << "d=" << 1 << ";\n"
             << "h=" << meshSize << ";\n"
             << "Point(1) = {a,c,0.0,h};\n"
             << "Point(2) = {b,c,0.0,h};\n"
             << "Point(3) = {b,d,0.0,h};\n"
             << "Point(4) = {a,d,0.0,h};\n"
             << "Point(5) = {0,c,0.0,h};\n"
             << "Point(6) = {0,d,0.0,h};\n"
             << "Point(7) = {a,0,0.0,h};\n"
             << "Point(8) = {b,0,0.0,h};\n"
             << "Point(9) = {0,0,0.0,h};\n"
             << "Line(1) = {1,5};\n"
             << "Line(2) = {5,2};\n"
             << "Line(3) = {2,8};\n"
             << "Line(4) = {8,3};\n"
             << "Line(5) = {3,6};\n"
             << "Line(6) = {6,4};\n"
             << "Line(7) = {4,7};\n"
             << "Line(8) = {7,1};\n"
             << "/* discontinuity (vertical line) */\n"
             << "Line(9) = {5, 9};\n"
             << "Line(10) = {9, 6};\n"
             << "/* horizontal line through square */\n"
             << "Line(11) = {7, 9};\n"
             << "Line(12) = {9, 8};\n"
             << "\n"
             << "Line Loop(19) = {3, -12, -9, 2};\n"
             << "Plane Surface(20) = {19};\n"
             << "Line Loop(21) = {4, 5, -10, 12};\n"
             << "Plane Surface(22) = {21};\n"
             << "Line Loop(23) = {6, 7, 11, 10};\n"
             << "Plane Surface(24) = {23};\n"
             << "Line Loop(25) = {8, 1, 9, -11};\n"
             << "Plane Surface(26) = {25};\n"
             << "\n"
             << "Physical Line(\"Tflux\") = {3, 4};\n"
             << "Physical Line(\"Tfixed\") = {8, 7};\n"
             << "Physical Line(\"Tinsulated\") = {1, 2, 6, 5};\n"
             << "Physical Line(\"Tdiscontinuity\") = {10, 9};\n"
             << "Physical Line(\"Tline\") = {11, 12};\n"
             << "\n"
             << "Physical Surface(\"k1\") = {20, 22};\n"
             << "Physical Surface(\"k2\") = {24, 26};\n";

        gmsh_ptrtype gmshp( new gmsh_type );
        gmshp->setPrefix( "hypercube-2" );
        gmshp->setDescription( ostr.str() );

        return gmshp;
    }

    void operator()()
    {
        using namespace Feel::vf;
        auto u = Xh->element();

        // this is the way to take into account the discontinuity at x = 0
        // properly
        u = vf::project( _space=Xh, _range=elements( mesh ),
                         _expr=( emarker()==mesh->markerName( "k2" ) )*( 2-Px() )+
                         ( emarker()==mesh->markerName( "k1" ) )*Px() );
        BOOST_TEST_MESSAGE( "here\n" );
        double len1 = integrate( _range=markedfaces( mesh, "Tdiscontinuity" ), _expr=cst( 1.0 ) ).evaluate()( 0,0 );
        BOOST_CHECK_CLOSE( len1, 2, 1e-12 );
        BOOST_TEST_MESSAGE( "here 1\n" );
        double len11 = integrate( _range=markedfaces( mesh, "Tdiscontinuity" ), _expr=leftfacev( cst( 1.0 ) )+rightfacev( cst( 1. ) ) ).evaluate()( 0,0 );
        BOOST_CHECK_CLOSE( len11, 4, 1e-12 );
        BOOST_TEST_MESSAGE( "here 2\n" );
        double len2 = integrate( _range=markedfaces( mesh, "Tline" ), _expr=cst( 1.0 ) ).evaluate()( 0,0 );
        BOOST_CHECK_CLOSE( len2, 2, 1e-12 );
        auto int1 = integrate( _range=markedfaces( mesh, "Tdiscontinuity" ), _expr=jumpv( idv( u ) ) ).evaluate();
        BOOST_CHECK_CLOSE( int1( 0,0 ), 4, 1e-12 );
        BOOST_CHECK_SMALL( int1( 1,0 ), 1e-12 );
        auto int2 = integrate( _range=markedfaces( mesh, "Tdiscontinuity" ), _expr=leftfacev( idv( u ) )+rightfacev( idv( u ) ) ).evaluate();
        BOOST_CHECK_CLOSE( int2( 0,0 ), 4, 1e-12 );

        u = vf::project( _space=Xh, _range=elements( mesh ),
                         _expr=( emarker()==mesh->markerName( "k2" ) )*( 2-Px() )*Py()-
                         ( emarker()==mesh->markerName( "k1" ) )*Px()*Py() );
        auto int3 = integrate( _range=markedfaces( mesh, "Tdiscontinuity" ), _expr=jumpv( idv( u ) ) ).evaluate();
        BOOST_CHECK_SMALL( int3( 0,0 ), 1e-12 );
        BOOST_CHECK_SMALL( int3( 1,0 ), 1e-12 );

        u = vf::project( _space=Xh, _range=elements( mesh ), _expr=sin( Px() ) );
        auto int4 = integrate( _range=markedfaces( mesh, "Tdiscontinuity" ), _expr=jumpv( idv( u ) ) ).evaluate();
        BOOST_CHECK_SMALL( int3( 0,0 ), 1e-12 );
        BOOST_CHECK_SMALL( int3( 1,0 ), 1e-12 );
    }
    std::shared_ptr<Feel::Backend<double> > backend;
    double meshSize;
    std::string shape;
    mesh_ptrtype mesh;
    space_ptrtype Xh;
};

} // Feel
inline
Feel::po::options_description
makeOptions()
{
    Feel::po::options_description integrationoptions( "Test Function Space features options" );
    integrationoptions.add_options()
    ( "hsize", Feel::po::value<double>()->default_value( 0.1 ), "h value" )
    ( "shape", Feel::po::value<std::string>()->default_value( "hypercube" ), "shape of the domain (hypercube, simplex, ellipsoid)" )
    ;
    return integrationoptions.add( Feel::feel_options() );
}

inline
Feel::AboutData
makeAbout()
{
    Feel::AboutData about( "test_disc" ,
                           "test_disc" ,
                           "0.2",
                           "1D/2D/3D functionspace features checks",
                           Feel::AboutData::License_GPL,
                           "Copyright (C) 2010 Université Joseph Fourier (Grenoble I)" );

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

}

FEELPP_ENVIRONMENT_WITH_OPTIONS( makeAbout(), makeOptions() )

BOOST_AUTO_TEST_SUITE( disc )

//typedef boost::mpl::list<boost::mpl::int_<1>,boost::mpl::int_<2>,boost::mpl::int_<3> > dim_types;
//typedef boost::mpl::list<boost::mpl::int_<1>,boost::mpl::int_<2> > dim_types;
typedef boost::mpl::list<boost::mpl::int_<2> > dim_types;
//typedef boost::mpl::list<boost::mpl::int_<2>,boost::mpl::int_<3>,boost::mpl::int_<1> > dim_types;

BOOST_AUTO_TEST_CASE_TEMPLATE( test_disc, T, dim_types )
{
    BOOST_TEST_MESSAGE( "Test disc (" << T::value << "D)" );
    Feel::test_disc<double,T::value> t;
    t();
    BOOST_TEST_MESSAGE( "Test disc (" << T::value << "D) done." );
}

BOOST_AUTO_TEST_SUITE_END()
back to top