Raw File
equispaced.hpp
/* -*- 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: 2006-03-06

Copyright (C) 2006 EPFL

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 3.0 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 equispaced.hpp
   \author Gilles Steiner <gilles.steiner@epfl.ch>
   \author Goncalo Pena <goncalo.pena@epfl.ch>
   \date 2006-09-26
*/
#ifndef __PointSetEquiSpaced_H
#define __PointSetEquiSpaced_H 1

#include <feel/feelmesh/refentity.hpp>
#include <feel/feelmesh/pointset.hpp>
#include <feel/feelmesh/simplex.hpp>
#include <feel/feelmesh/hypercube.hpp>

#include <feel/feelcore/visitor.hpp>
#include <feel/feelcore/traits.hpp>

#include <stdexcept>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/io.hpp>

#include <feel/feelalg/glas.hpp>


namespace Feel
{
namespace ublas = boost::numeric::ublas;

template<class Convex, uint16_type Order, typename T>
class PointSetEquiSpaced :  public PointSet< Convex, T>
{

public :

    typedef PointSet<Convex, T> super;

    typedef T value_type;

    typedef typename super::return_type return_type;
    typedef typename super::self_type self_type;

    typedef typename super::node_type node_type;

    typedef typename super::nodes_type nodes_type;

    typedef typename matrix_node<value_type>::type points_type;

    static const uint32_type Dim = Convex::nDim;
    static const uint32_type convexOrder = Convex::nOrder;
    static const uint32_type topological_dimension = Convex::topological_dimension;
    static const uint32_type nRealDim = Convex::nRealDim;

    static const size_type Shape = Convex::Shape;

    static const bool is_simplex = Convex::is_simplex;
    static const bool is_hypercube = Convex::is_hypercube;

    typedef mpl::if_< mpl::bool_< is_simplex >,
            Simplex<Dim, Order, /*nRealDim*/Dim> ,
            Hypercube<Dim, Order, /*nRealDim*/Dim> > conv_order_type;

    typedef Reference<Convex, Dim, convexOrder, Dim/*nRealDim*/, value_type> RefElem;

    static const uint32_type numPoints = conv_order_type::type::numPoints;
    static const uint32_type nbPtsPerVertex = conv_order_type::type::nbPtsPerVertex;
    static const uint32_type nbPtsPerEdge = conv_order_type::type::nbPtsPerEdge;
    static const uint32_type nbPtsPerFace = conv_order_type::type::nbPtsPerFace;
    static const uint32_type nbPtsPerVolume = conv_order_type::type::nbPtsPerVolume;

    typedef typename Convex::edge_to_point_t edge_to_point_t;
    typedef typename Convex::face_to_point_t face_to_point_t;
    typedef typename Convex::face_to_edge_t face_to_edge_t;

    typedef std::pair<uint16_type, uint16_type> range_type;
    typedef std::vector< std::vector<size_type> > index_map_type;

    RefElem RefConv;

    PointSetEquiSpaced( int interior = 0 )
        :
        super( numPoints, Dim ),
        M_eid()
    {
        M_eid.resize( topological_dimension + 1 );
        M_pt_to_entity.resize( numPoints );

        nodes_type pts( Dim, numPoints );

        if ( interior == 0 && Order > 0 )
        {
            // loop on each convex of topological dimension <= to the current convex
            // where we build the polynomial set
            for ( uint16_type d = 0, p = 0; d < topological_dimension+1; ++d )
            {
                // loop on each entity forming the convex of topological
                // dimension d
                for ( int e = RefConv.entityRange( d ).begin();
                        e < RefConv.entityRange( d ).end();
                        ++e )
                {
                    nodes_type Gt ( makePoints( d, e ) );

                    if ( Gt.size2() )
                    {
                        ublas::subrange( pts, 0, Dim, p, p+Gt.size2() ) = Gt;

                        for ( size_type j = 0; j < Gt.size2(); ++j )
                        {
                            addToEid( d, p+j );
                            addToPtE( p+j, std::make_pair( d, e ) );
                        }

                        p+=Gt.size2();
                    }
                }
            }

            this->setPoints( pts );
        }

        else if ( interior == 1 && Order > 0 )
            this->setPoints( makePoints( Dim, 0 ) );

        else if ( Order == 0 )
            this->setPoints( glas::average( RefConv.vertices() ) );

        this->setName( "equispaced", Order );
    }

    ~PointSetEquiSpaced() {}

    ublas::matrix_range<nodes_type const> pointsByEntity( uint16_type e ) const
    {
        FEELPP_ASSERT( M_eid[e].size() )( e ).error( "no points defined on this entity" );

        return ublas::project( this->points(),
                               ublas::range( 0,Dim ),
                               ublas::range( *M_eid[e].begin(), *M_eid[e].rbegin() + 1 ) );
    }

    std::pair<uint16_type, uint16_type> interiorRangeById( uint16_type e, uint16_type id ) const
    {
        uint16_type numEntities = 1;

        if ( e == 0 )
            numEntities = Convex::numVertices;

        else if ( e == 1 )
            numEntities = Convex::numEdges;

        else if ( e == 2 )
            numEntities = Convex::numFaces;

        uint16_type N = M_eid[e].size()/numEntities;

        return std::make_pair( *M_eid[e].begin() + id*N, *M_eid[e].begin() + ( id+1 )*N );
    }

    ublas::matrix_range<nodes_type const> interiorPointsById( uint16_type e, uint16_type id ) const
    {
        std::pair<uint16_type, uint16_type> position = interiorRangeById( e, id );

        ublas::matrix_range<nodes_type const> G = ublas::project( this->points(),
                ublas::range( 0, Dim ),
                ublas::range( position.first, position.second ) );

        return G;
    }

    uint32_type entityIds( int i, int j ) const
    {
        return M_eid[i][j];
    }

    uint32_type numEntities( int i ) const
    {
        return M_eid[i].size();
    }

    std::pair<uint16_type, uint16_type> const& pointToEntity( int p ) const
    {
        return M_pt_to_entity[p];
    }

    //Returns the local indices of all the subentities that compose the entity
    index_map_type entityToLocal ( uint16_type top_dim, uint16_type local_id, bool boundary = 0 ) const
    {
        index_map_type indices( top_dim+1 );

        if ( top_dim == 0 && boundary )
        {
            range_type pair = interiorRangeById( top_dim, local_id );

            indices[0].push_back( pair.first );
        }

        else
        {
            if ( !boundary && top_dim > 0 )
            {
                if ( numEntities( top_dim ) != 0 )
                    indices[top_dim].push_back( local_id );
            }

            else
            {
                if ( top_dim > 0 )
                {
                    //For the time being, this definition works, but in a more general framework,
                    //a entity shoulkd be created here with the respective top_dim
                    //in order to retrieve the number of vertices, edges, faces.

                    //number of vertices, number of edges and number of faces in the volume
                    std::map<uint16_type, uint16_type> numPointsInEntity;

                    numPointsInEntity[0] = ( uint16_type ) ( is_simplex )?( top_dim+1 ):( 2 + ( top_dim-1 )*( 2+3*( top_dim-2 ) ) );
                    numPointsInEntity[1] = ( uint16_type ) ( 2 + ( top_dim-1 )*( 1+2*is_simplex + ( 5-4*is_simplex )*( top_dim-1 ) ) )/2;
                    numPointsInEntity[2] = ( uint16_type ) 6-2*is_simplex;

                    for ( uint16_type i=0; i < numPointsInEntity[0] ; i++ )
                    {
                        if ( top_dim == 1 )
                            indices[0].push_back( RefConv.e2p( local_id, i ) );

                        else if ( top_dim == 2 )
                            indices[0].push_back( RefConv.f2p( local_id, i ) );
                    }

                    if ( ( top_dim == 2 ) && ( M_eid[1].size() != 0 ) )
                    {
                        for ( uint16_type i=0; i < numPointsInEntity[1] ; i++ )
                            indices[1].push_back( RefConv.f2e( local_id, i ) );
                    }

                    if ( top_dim == 3 )
                    {
                        for ( uint16_type k=0; k<numPointsInEntity.size(); k++ )
                            for ( uint16_type i=0; i < numPointsInEntity[k]; i++ )
                                indices[k].push_back( i );
                    }

                    if ( M_eid[top_dim].size() )
                        indices[top_dim].push_back( local_id );
                }
            }
        }

        return indices;
    }


    points_type pointsBySubEntity( uint16_type top_dim, uint16_type local_id, bool boundary = 0 ) const
    {
        index_map_type index_list = entityToLocal( top_dim, local_id, boundary );

        uint16_type matrix_size = 0;

        if ( index_list[0].size() != 0 )
            matrix_size +=index_list[0].size()*nbPtsPerVertex;

        if ( ( top_dim >= 1 ) && ( index_list[1].size() != 0 ) )
            matrix_size +=index_list[1].size()*nbPtsPerEdge;

        if ( ( top_dim >= 2 ) && ( index_list[2].size() != 0 ) )
            matrix_size +=index_list[2].size()*nbPtsPerFace;

        if ( ( top_dim == 3 ) && ( index_list[3].size() != 0 ) )
            matrix_size +=nbPtsPerVolume;

        points_type G ( Dim, matrix_size );

        for ( uint16_type i=0, p=0; i < top_dim+1; i++ )
        {
            if ( index_list[i].size() )
            {
                for ( uint16_type j=0; j < index_list[i].size(); j++ )
                {
                    points_type aux = interiorPointsById( i, index_list[i][j] );

                    ublas::subrange( G, 0, Dim, p, p+aux.size2() ) = aux;

                    p+=aux.size2();
                }
            }
        }

        return G;
    }

    index_map_type getEid ()
    {
        return M_eid;
    }

    std::vector<range_type> getPtE()
    {
        return M_pt_to_entity;
    }

    void setEid ( index_map_type eid )
    {
        M_eid = eid;
    }

    void setPtE ( std::vector<range_type> pt_ent )
    {
        M_pt_to_entity = pt_ent;
    }

    void addToEid ( uint16_type p, uint16_type q )
    {
        M_eid[p].push_back( q );
    }

    void addToPtE ( uint16_type p, range_type q )
    {
        M_pt_to_entity[p] = q;
    }

    FEELPP_DEFINE_VISITABLE();

private:

    index_map_type M_eid;
    std::vector<range_type> M_pt_to_entity;

    points_type makePoints( uint16_type topo_dim, uint16_type __id, int interior = 1 )
    {
        // vertices
        if ( topo_dim == 0 )
        {
            points_type G( RefConv.vertices().size1(), 1 );
            ublas::column( G, 0 ) = ublas::column( RefConv.vertices(), __id );
            return G;
        }

        // interior points of the convex
        else if ( topo_dim == topological_dimension )
        {
            if ( __id == 0 )
                return makeLattice<Shape>( interior );

            throw std::logic_error( "cannot make those points" );
            return points_type();
        }

        // all the other points
        else
        {
            points_type G;
            points_type Gret;

            if ( topo_dim == 1 )
            {
                G = makeLattice<SHAPE_LINE>( 1 );
                Gret.resize( nRealDim, G.size2() );

                if ( is_simplex )
                {
                    pt_to_entity_tetrahedron<Shape, 1> p_to_e( __id );

                    for ( size_type i = 0; i < G.size2(); ++i )
                        ublas::column( Gret, i ) = p_to_e( ublas::column( G, i ) );
                }

                else
                {
                    pt_to_entity_hexahedron<Shape, 1> p_to_e( __id );

                    for ( size_type i = 0; i < G.size2(); ++i )
                        ublas::column( Gret, i ) = p_to_e( ublas::column( G, i ) );
                }

                return Gret;
            }

            else if ( topo_dim == 2 )
            {
                if ( is_simplex )
                {
                    G = makeLattice<SHAPE_TRIANGLE>( 1 );
                    Gret.resize( nRealDim, G.size2() );
                    pt_to_entity_tetrahedron<Shape, 2> p_to_e( __id );

                    for ( size_type i = 0; i < G.size2(); ++i )
                        ublas::column( Gret, i ) = p_to_e( ublas::column( G, i ) );
                }

                else
                {
                    G = makeLattice<SHAPE_QUAD>( 1 );
                    Gret.resize( nRealDim, G.size2() );
                    pt_to_entity_hexahedron<Shape, 2> p_to_e( __id );

                    for ( size_type i = 0; i < G.size2(); ++i )
                        ublas::column( Gret, i ) = p_to_e( ublas::column( G, i ) );
                }

                return Gret;
            }
        }

        return points_type();
    }

    template<size_type shape>
    points_type makeLattice( uint16_type interior = 0 )
    {
        points_type G;

        if ( Order > 0 )
        {
            if ( shape == SHAPE_LINE )
                G = make_line_points( interior );

            else if ( shape == SHAPE_TRIANGLE )
                G = make_triangle_points( interior );

            else if ( shape == SHAPE_TETRA )
                G = make_tetrahedron_points( interior );

            else if ( shape == SHAPE_QUAD )
                return make_quad_points( interior );

            else if ( shape == SHAPE_HEXA )
                return make_hexa_points( interior );
        }

        else if ( Order == 0 )
            G = glas::average( RefConv.vertices() );

        return G;
    }

    //---------------------------------------------------------------------------------------------
    int n_line_points( int interior = 0 )
    {
        return std::max( 0, int( Order )+1-2*interior );
    }
    int n_triangle_points( int interior = 0 )
    {
        if ( interior == 1 )
            return std::max( 0, ( int( Order )+1-2*interior )*( int( Order )-2*interior )/2 );

        return ( Order+1 )*( Order+2 )/2;
    }
    int n_tetrahedron_points( int interior = 0 )
    {
        if ( interior == 1 )
            return std::max( 0, ( int( Order )+1-2*interior )*( int( Order )-2*interior )*( int( Order )-1-2*interior )/6 );

        return ( Order+1 )*( Order+2 )*( Order+3 )/6;
    }

    int n_quad_points( int interior = 0 ) const
    {
        if ( interior == 1 )
            return std::max( 0, ( int( Order )+1-2*interior )*( int( Order )+1-2*interior ) );

        return ( Order+1 )*( Order+1 );
    }

    int n_hexa_points( int interior = 0 ) const
    {
        if ( interior == 1 )
            return std::max( 0, ( int( Order )+1-2*interior )*( int( Order )+1-2*interior )*( int( Order )+1-2*interior ) );

        return ( Order+1 )*( Order+1 )*( Order+1 );
    }

    points_type
    make_line_points( int interior = 0 )
    {
        points_type G;

        if ( Order > 0 )
        {
            ublas::vector<node_type> h ( 1 );
            h( 0 ) = RefConv.vertex( 1 ) - RefConv.vertex( 0 );

            G.resize( Dim, n_line_points( interior ) );

            for ( int i = interior, indp = 0; i < int( Order )+1-interior; ++i, ++indp )
            {
                ublas::column( G, indp ) = RefConv.vertex( 0 ) + ( h( 0 ) * value_type( i ) )/value_type( Order );
            }
        }

        else
            G = glas::average( RefConv.vertices() );

        return G;

    }

    points_type
    make_triangle_points( int interior = 0 )
    {
        points_type G;

        if ( Order > 0 )
        {
            ublas::vector<node_type> h ( 2 );
            h( 0 ) = RefConv.vertex( 1 ) - RefConv.vertex( 0 );
            h( 1 ) = RefConv.vertex( 2 ) - RefConv.vertex( 0 );

            G.resize( Dim, n_triangle_points( interior ) );

            for ( int i = interior, p = 0; i < int( Order )+1-interior; ++i )
            {
                for ( int j = interior; j < int( Order ) + 1 - i-interior; ++j, ++p )
                {
                    ublas::column( G, p ) = RefConv.vertex( 0 ) + ( value_type( i ) * h( 1 )  +
                                            value_type( j ) * h( 0 ) )/ value_type( Order );
                }
            }
        }

        else
            G = glas::average( RefConv.vertices() );

        return G;
    }

    points_type
    make_tetrahedron_points( int interior = 0 )
    {
        points_type G;

        if ( Order > 0 )
        {
            ublas::vector<node_type> h ( 3 );
            h( 0 ) = RefConv.vertex( 1 ) - RefConv.vertex( 0 );
            h( 1 ) = RefConv.vertex( 2 ) - RefConv.vertex( 0 );
            h( 2 ) = RefConv.vertex( 3 ) - RefConv.vertex( 0 );

            G.resize( Dim, n_tetrahedron_points( interior ) );

            for ( int i = interior, p = 0; i < int( Order )+1-interior; ++i )
            {
                for ( int j = interior; j < int( Order ) + 1 - i - interior; ++j )
                {
                    for ( int k = interior; k < int( Order ) + 1 - i - j - interior; ++k, ++p )
                    {
                        ublas::column( G, p ) = RefConv.vertex( 0 ) + ( value_type( i ) * h( 2 ) +
                                                value_type( j ) * h( 1 ) +
                                                value_type( k ) * h( 0 ) ) / value_type( Order );

                    }
                }
            }
        }

        else
            G = glas::average( RefConv.vertices() );

        return G;
    }

    points_type
    make_quad_points( int interior = 0 )
    {
        if ( Order > 0 )
        {
            ublas::vector<node_type> h ( 2 );
            h( 0 ) = RefConv.vertex( 1 ) - RefConv.vertex( 0 );
            h( 1 ) = RefConv.vertex( 3 ) - RefConv.vertex( 0 );

            DVLOG(2) << "n quad pts = " << n_quad_points( interior ) << "\n";
            points_type G( Dim, n_quad_points( interior ) );

            for ( int i = interior, p = 0; i < int( Order )+1-interior; ++i )
            {
                for ( int j = interior; j < int( Order ) + 1 -interior; ++j, ++p )
                {
                    ublas::column( G, p ) = RefConv.vertex( 0 ) + ( value_type( i ) * h( 0 )  +
                                            value_type( j ) * h( 1 ) )/ value_type( Order );
                }
            }

            return G;
        }

        else
            return glas::average( RefConv.vertices() );
    }

    points_type
    make_hexa_points( int interior = 0 )
    {
        if ( Order > 0 )
        {
            ublas::vector<node_type> h ( 3 );
            h( 0 ) = RefConv.vertex( 1 ) - RefConv.vertex( 0 );
            h( 1 ) = RefConv.vertex( 3 ) - RefConv.vertex( 0 );
            h( 2 ) = RefConv.vertex( 4 ) - RefConv.vertex( 0 );

            points_type G( Dim, n_hexa_points( interior ) );
            DVLOG(2) << "n hexa pts = " << n_hexa_points( interior ) << "\n";

            for ( int i = interior, p = 0; i < int( Order )+1-interior; ++i )
            {
                for ( int j = interior; j < int( Order ) + 1 - interior; ++j )
                {
                    for ( int k = interior; k < int( Order ) + 1 - interior; ++k, ++p )
                    {
                        ublas::column( G, p ) = RefConv.vertex( 0 ) + ( value_type( i ) * h( 0 ) +
                                                value_type( j ) * h( 1 ) +
                                                value_type( k ) * h( 2 ) ) / value_type( Order );

                    }
                }
            }

            return G;
        }

        else
            return glas::average( RefConv.vertices() );
    }

    template<size_type shape>
    struct pt_to_edge
    {
        pt_to_edge( std::vector<uint16_type> vert_ids )
            :
            h( 1.0 ),
            a( Entity<SHAPE_LINE, value_type>().vertex( 0 ) ),
            b( Entity<SHAPE_LINE, value_type>().vertex( 1 ) ),
            u( Entity<shape, value_type>().vertex( vert_ids[ 0 ] ) ),
            v( Entity<shape, value_type>().vertex( vert_ids[ 1 ] ) ),
            diff( v-u )
        {
            h = 1.0/( b[0]-a[0] );
        }
        node_type
        operator()( node_type const& x ) const
        {
            return u + h * ( x[ 0 ] - a[ 0 ] ) * diff;
        }
        value_type h;
        node_type a, b;
        node_type u, v, diff;
    };

    //
    // pt_to_face tetrahedron
    //
    template<size_type shape>
    struct pt_to_face_tetrahedron
    {
        pt_to_face_tetrahedron( std::vector<uint16_type> vert_ids )
            :
            u( Entity<shape, value_type>().vertex( vert_ids[ 0 ] ) ),
            v( Entity<shape, value_type>().vertex( vert_ids[ 1 ] ) ),
            w( Entity<shape, value_type>().vertex( vert_ids[ 2 ] ) ),
            diff( 2 )
        {
            diff[0] = v-u;
            diff[1] = w-u;
        }
        node_type
        operator()( node_type const& x ) const
        {
            return u + 0.5*( x[ 0 ]+1.0 ) * diff[ 0 ] + 0.5*( x[ 1 ]+1.0 ) * diff[ 1 ];
        }
        node_type u, v, w;
        ublas::vector<node_type> diff;
    };

    //
    // pt_to_face hexa
    //
    template<size_type shape>
    struct pt_to_face_hexahedron
    {
        pt_to_face_hexahedron( std::vector<uint16_type> vert_ids )
            :
            u( Entity<shape, value_type>().vertex( vert_ids[ 0 ] ) ),
            v( Entity<shape, value_type>().vertex( vert_ids[ 1 ] ) ),
            w( Entity<shape, value_type>().vertex( vert_ids[ 3 ] ) ),
            diff( 2 )
        {
            diff[0] = v-u;
            diff[1] = w-u;
        }
        node_type
        operator()( node_type const& x ) const
        {
            return u + 0.5*( x[ 0 ]+1.0 ) * diff[ 0 ] + 0.5*( x[ 1 ]+1.0 ) * diff[ 1 ];
        }
        node_type u, v, w;
        ublas::vector<node_type> diff;
    };

    template<size_type shape>
    struct pt_to_element
    {
        pt_to_element() {}
        pt_to_element( std::vector<uint16_type> const& ) {}
        node_type operator()( node_type const& x ) const
        {
            return x;
        }
    };

    template<size_type shape, uint16_type topo_dim>
    struct pt_to_entity_tetrahedron
    {
        typedef typename mpl::if_<mpl::equal_to<mpl::size_t<shape>, mpl::size_t<SHAPE_LINE> >,
                mpl::identity<mpl::vector<boost::none_t,pt_to_edge<shape>,pt_to_edge<shape> > >,
                typename mpl::if_<mpl::equal_to<mpl::size_t<shape>, mpl::size_t<SHAPE_TRIANGLE> >,
                mpl::identity<mpl::vector<boost::none_t, pt_to_edge<shape>, pt_to_element<shape> > >,
                mpl::identity<mpl::vector<boost::none_t, pt_to_edge<shape>, pt_to_face_tetrahedron<shape>, pt_to_element<shape> > >
                >::type // 2
                >::type::type _type;
        typedef typename mpl::at<_type, mpl::int_<topo_dim> >::type mapping_type;
        typedef mpl::vector<boost::none_t, edge_to_point_t, face_to_point_t> list_v;

        pt_to_entity_tetrahedron( uint16_type entity_id )
            :
            mapping( typename mpl::at<list_v, mpl::int_<topo_dim> >::type().entity( topo_dim, entity_id ) )
        {}

        node_type operator()( node_type const& x ) const
        {
            return mapping( x );
        }
        mapping_type mapping;
    };

    template<size_type shape,uint16_type topo_dim>
    struct pt_to_entity_hexahedron
    {
        typedef typename mpl::if_<mpl::equal_to<mpl::size_t<shape>, mpl::size_t<SHAPE_LINE> >,
                mpl::identity<mpl::vector<boost::none_t,pt_to_edge<shape>,pt_to_edge<shape> > >,
                typename mpl::if_<mpl::equal_to<mpl::size_t<shape>, mpl::size_t<SHAPE_QUAD> >,
                mpl::identity<mpl::vector<boost::none_t, pt_to_edge<shape>, pt_to_element<shape> > >,
                mpl::identity<mpl::vector<boost::none_t, pt_to_edge<shape>, pt_to_face_hexahedron<shape>, pt_to_element<shape> > >
                >::type // 2
                >::type::type _type;
        typedef typename mpl::at<_type, mpl::int_<topo_dim> >::type mapping_type;
        typedef mpl::vector<boost::none_t, edge_to_point_t, face_to_point_t> list_v;

        pt_to_entity_hexahedron( uint16_type entity_id )
            :
            mapping( typename mpl::at<list_v, mpl::int_<topo_dim> >::type().entity( topo_dim, entity_id ) )
        {}

        node_type operator()( node_type const& x ) const
        {
            return mapping( x );
        }
        mapping_type mapping;
    };

};

} // Feel
#endif /* __PointSetEquiSpaced_H */
back to top