Commit 2696c6a9 authored by Fabian's avatar Fabian
Browse files

Rough solution implemented (works like DataSet and GridDataSet from...

Rough solution implemented (works like DataSet and GridDataSet from ethGenericGrid). Still misses a factory
parent 3f7d485c
......@@ -25,7 +25,7 @@
#include "utils/static_iterate.hpp"
#include "fe/fe_enumerators.hpp"
#include "ex_data_set.hpp"
#include "num_dof_data_set.hpp"
namespace betl2 {
namespace fe {
......@@ -101,7 +101,12 @@ namespace betl2 {
//! Type of eth::grid::IndexSet
typedef eth::grid::IndexSet<gridTraits_t , typename viewTraits_t::indexSet_t>
indexSet_t;
typedef std::array<std::vector<unsigned>, gridTraits_t::dimMesh+2> set_t;
// typedef std::array<std::vector<unsigned>, gridTraits_t::dimMesh+2> set_t;
typedef NumDofDataSet<unsigned, gridViewFactory_t, eth::base::RefElType::QUAD,
eth::base::RefElType::TRIA,
eth::base::RefElType::SEGMENT,
eth::base::RefElType::POINT > set_t;
/*! Constructor
......@@ -109,18 +114,16 @@ namespace betl2 {
* @param gridViewFactory A grid view factory.
*/
FEBasis(gridViewFactory_t gridViewFactory) :
gridViewFactory_( gridViewFactory ),
gridView_( gridViewFactory_.getView() ),
indexSet_( &gridView_.indexSet() )
multiplicities_( std::move(gridViewFactory) )
{
// Resize (and set to zero) multiplicities for all entities in this mesh
typedef betl2::utils::static_iterate< gridTraits_t::dimMesh,
ResizeMultiplcities_,
const decltype( gridView_ )&,
set_t&> static_iterate;
static_iterate()( gridView_, multiplicities_);
// typedef betl2::utils::static_iterate< gridTraits_t::dimMesh,
// ResizeMultiplcities_,
// const decltype( gridView_ )&,
// set_t&> static_iterate;
// static_iterate()( gridView_, multiplicities_);
std::get<3>(multiplicities_).resize(indexSet_->size(eth::base::RefElType::QUAD));
//std::get<3>(multiplicities_).resize(indexSet_->size(eth::base::RefElType::QUAD));
}
//! @attention needed for interpolation (set to Lagrange)
......@@ -137,10 +140,11 @@ std::get<3>(multiplicities_).resize(indexSet_->size(eth::base::RefElType::QUAD))
template< int CODIM >
void setMult(const eth::grid::Entity<gridTraits_t, CODIM>& ent,
const size_type mult) {
if( ent.refElType() == eth::base::RefElType::QUAD)
multiplicities_[3].at(gridView_.indexSet().index(ent)) = mult;
else
multiplicities_[CODIM].at(gridView_.indexSet().index(ent)) = mult;
// if( ent.refElType() == eth::base::RefElType::QUAD)
// multiplicities_[3].at(gridView_.indexSet().index(ent)) = mult;
// else
// multiplicities_[CODIM].at(gridView_.indexSet().index(ent)) = mult;
multiplicities_.setData(ent, mult);
}
......@@ -151,10 +155,11 @@ std::get<3>(multiplicities_).resize(indexSet_->size(eth::base::RefElType::QUAD))
*/
template< int CODIM >
size_type multiplicity(const eth::grid::Entity<gridTraits_t, CODIM>& ent) const {
if( ent.refElType() == eth::base::RefElType::QUAD)
return multiplicities_[3].at(gridView_.indexSet().index(ent));
else
return multiplicities_[CODIM].at(gridView_.indexSet().index(ent));
// if( ent.refElType() == eth::base::RefElType::QUAD)
// return multiplicities_[3].at(gridView_.indexSet().index(ent));
// else
// return multiplicities_[CODIM].at(gridView_.indexSet().index(ent));
return multiplicities_.data(ent);
}
/*! @return total number of degrees of freedom for an element.
......@@ -166,21 +171,15 @@ std::get<3>(multiplicities_).resize(indexSet_->size(eth::base::RefElType::QUAD))
size_type numDofs(const eth::grid::Entity<gridTraits_t,0>& elem) const
{
// Get degrees of freedom for this element (without its subentities)
size_type dofs = 0;
if( elem.refElType() == eth::base::RefElType::QUAD)
dofs += multiplicities_[3].at(gridView_.indexSet().index(elem));
else
dofs += multiplicities_[0].at( gridView_.indexSet().index(elem) );
size_type dofs = multiplicity(elem);
// Retrieve all degrees of freedom of the subentities of this element
typedef betl2::utils::static_iterate< gridTraits_t::dimMesh-1,
GetDofs_,
const decltype( gridView_ )&,
const set_t&,
const FEBasis&,
const eth::grid::Entity<gridTraits_t,0>&,
size_type&> static_iterate;
static_iterate()( gridView_, multiplicities_, elem, dofs);
static_iterate()(*this, elem, dofs);
return dofs;
}
......@@ -190,7 +189,7 @@ std::get<3>(multiplicities_).resize(indexSet_->size(eth::base::RefElType::QUAD))
// -------------------------------------------------------------------------
/*------------------------- BEGIN DOXYGEN HIDING -------------------------*/
//! @cond
/*
// Helper struct for resizing all entities in mesh
template< int CODIM >
struct ResizeMultiplcities_
......@@ -202,28 +201,24 @@ std::get<3>(multiplicities_).resize(indexSet_->size(eth::base::RefElType::QUAD))
std::get<CODIM>(data).resize(gridView.size(CODIM));
}
}; // end struct ResizeMultiplicities_
*/
// Helper struct for retrieving the degrees of freedom of all entities
// given a codimension
template< int CODIM >
struct GetDofs_
{
template< typename GRID_VIEW, typename DATA_SET_T, typename ELEMENT_T>
void operator()( const GRID_VIEW& gridView,
const DATA_SET_T& data,
const ELEMENT_T& elem,
template< typename ELEMENT_T>
void operator()( const FEBasis& febasis, const ELEMENT_T& elem,
size_type& dofs) const
{
const auto& multSet = std::get<CODIM+1>(data);
// Get number of subentities of this elment with codimension=CODIM
const size_type numSubEnt = elem.template countSubEntities<CODIM+1>( );
// Loop over subentities and add their degrees of freedom
for(size_type i = 0; i < numSubEnt; ++i)
dofs += multSet[ gridView.indexSet().template subIndex<CODIM+1>(elem, i) ];
dofs += febasis.multiplicity( *(elem.template subEntity<CODIM+1>(i)) );
}
}; // end struct GetDofs_
//! @endcond
/*-------------------------- END DOXYGEN HIDING --------------------------*/
// -------------------------------------------------------------------------
......@@ -231,12 +226,6 @@ std::get<3>(multiplicities_).resize(indexSet_->size(eth::base::RefElType::QUAD))
private:
//! Storage for multiplicities
set_t multiplicities_;
//! Underlying GridViewFactory
const gridViewFactory_t gridViewFactory_;
//! Underlying GridView used for indices
gridView_t gridView_;
//! Pointer to underlying IndexSet
const indexSet_t* indexSet_;
}; // end class FEBasis
......
......@@ -8,8 +8,8 @@
//! @date 2017
#ifndef BETL2_FE_EX_DOF_DATA_SET_FACTORIES_HPP
#define BETL2_FE_EX_DOF_DATA_SET_FACTORIES_HPP
#ifndef BETL2_FE_EX_DOF_DATA_SET_FACTORIES_HPP_T
#define BETL2_FE_EX_DOF_DATA_SET_FACTORIES_HPP_T
// eth includes ----------------------------------------------------------------
#include <eth_base/ref_el_types.hpp>
......@@ -29,6 +29,33 @@ namespace betl2 {
namespace fe {
namespace ex{
// Forward declaration
template< typename DATA_TYPE, class GRID_VIEW_FACTORY_T,
enum eth::base::RefElType... REFS >
class NumDofDataSet;
namespace detail {
template< typename DATA_TYPE, class GRID_VIEW_FACTORY_T,
enum eth::base::RefElType... REFS >
struct NumDofDataSetTraits;
//! @brief Provides some types for \ref NumDofDataSet
/*
template< typename DATA_TYPE, class GRID, eth::grid::GridViewTypes GV_T,
enum eth::base::RefElType... REFS >
struct NumDofDataSetTraits< DATA_TYPE,
eth::grids::utils::GridViewFactory<GRID,GV_T>,
REFS... >
{
//! View traits of GridViewFactory
typedef typename eth::grid::utils::GridViewFactory<GRID,GV_T>::viewTraits_t
viewTraits_t;
};
*/
} // end namespace detail
/*! WANT: Storage for all reference types (REFS...)' multiplicity
* MEANS: NumDofDataSet will be build like:
......@@ -40,7 +67,7 @@ namespace betl2 {
* DataSet<dof*, GVT_T, TRIA, QUAD>
*/
template< typename DATA_TYPE, class GRID_VIEW_FACTORY_T,
enum eth::base::RefElType REFS... >
enum eth::base::RefElType... REFS >
class NumDofDataSet
{
public:
......@@ -49,13 +76,14 @@ namespace betl2 {
//! Type of grid view factory
typedef GRID_VIEW_FACTORY_T gridViewFactory_t;
//! Type of traits
typedef detail::NumDofDataSetTraits<dataType_t,gridViewFactory_t,REFS...>
traits_t;
// typedef detail::NumDofDataSetTraits<dataType_t,gridViewFactory_t,REFS...>
// traits_t;
//! Type of view traits
typedef typename traits_t::viewTraits_t viewTraits_t;
// typedef typename traits_t::viewTraits_t viewTraits_t;
typedef typename gridViewFactory_t::viewTraits_t viewTraits_t;
//! Type of grid traits
typedef typename viewTrais_t::gridTraits_t gridTraits_t;
typedef eth::grid::IndexSet<gridTraits_t, typename viewTraits::indexSet_t>
typedef typename viewTraits_t::gridTraits_t gridTraits_t;
typedef eth::grid::IndexSet<gridTraits_t, typename viewTraits_t::indexSet_t>
indexSet_t;
//! List of reference types
typedef typename eth::base::RefElList<REFS...> refElList_t;
......@@ -67,11 +95,14 @@ namespace betl2 {
//! Constructor
NumDofDataSet(gridViewFactory_t gridViewFactory)
: gridviewFactory_( std::move(gridViewFactory) ),
gridView_( std::move(gridViewFactory_.getView()) ),
: gridViewFactory_( gridViewFactory ),
gridView_( gridViewFactory_.getView() ),
indexSet_( &gridView_.indexSet() )
{
// Resizing StorageHelpers (done via indexSet_)
std::cout << "Resizing StorageHelpers...\n";
resizeStorageHelper<REFS...>();
std::cout << "Done resizing StorageHelpers.\n";
}
/*! @return the number of degrees of freedom associated with an entity.
......@@ -79,13 +110,13 @@ namespace betl2 {
* @param ent Entity.
*/
template<int CODIM>
dataType_t mult(const entity_t<CODIM>& ent) const
const dataType_t& data(const entity_t<CODIM>& ent) const
{
static constexpr int dim = gridTraits_t::dimMesh-CODIM;
return eth::base::ReferenceElements::applyUniversal< /*TODO*/,
return eth::base::ReferenceElements::applyUniversal< DataFunctor,
typename refElList_t::template onlyDim_t<dim>,
NumDofDataSet&,
const entity_t<CODIM>& >( ent.refElType(), *this, ent);
const NumDofDataSet&,
const entity_t<CODIM>& >( ent.refElType(), *this, ent );
} // end mult()
......@@ -93,39 +124,236 @@ namespace betl2 {
*
* @param elem Element.
*/
dataType_t numDofs(const entity_t<0>& elem) const
const dataType_t& sumData(const entity_t<0>& elem) const
{
static constexpr int dim = gridTraits_t::dimMesh-CODIM;
return eth::base::ReferenceElements::applyUniversal< /*TODO*/,
// TODO
static constexpr int dim = gridTraits_t::dimMesh;
return eth::base::ReferenceElements::applyUniversal<
DataFunctor,
typename refElList_t::template onlyDim_t<dim>,
NumDofDataSet&,
const entity_t<CODIM>& >( elem.refElType(), *this, ent);
const NumDofDataSet&,
const entity_t<0>& >( elem.refElType(), *this, elem );
} // end numDofs()
/*! @brief Sets the number of degree of freedom for an entity.
*
* @param ent Entity.
* @param ent Entity.
* @param data Data that will be set.
*/
template<int CODIM>
void setMult(const entity_t<CODIM>& ent)
void setData(const entity_t<CODIM>& ent, dataType_t data)
{
static constexpr int dim = gridTraits_t::dimMesh-CODIM;
return eth::base::ReferenceElements::applyUniversal< /*TODO*/,
return eth::base::ReferenceElements::applyUniversal<
SetDataFunctor,
typename refElList_t::template onlyDim_t<dim>,
NumDofDataSet&,
const entity_t<CODIM>& >( ent.refElType(), *this, ent);
const entity_t<CODIM>& >( ent.refElType(), *this, ent, data );
} // end setMult()
private:
// TODO Structs for member functions
// Structs that fulfil the interface of applyUniversal
//! @brief Struct that allows to use applyUniversal to retrieve data.
template< eth::base::RefElType RET >
struct DataFunctor
{
//! @brief Need to define a returnType_t
typedef const dataType_t& returnType_t;
/*! @brief Need to define static function invoke
*
* @return reference to data stored at an entity of reference type RET.
*
* @param nds NumDofDataSet.
* @param ent Entity.
*/
static returnType_t invoke(const NumDofDataSet& nds,
const entity_t<gridTraits_t::dimMesh
-eth::base::ReferenceElement<RET>::dimension>& ent)
{
// Employ getStorageHelper to retrieve correct storage helper
// then cast it to make it the right type (it's otherwise base class),
// then use data functon of StorageHelper to get the data.
return static_cast< const StorageHelper<RET>* >(
nds.getStorageHelper<RET, REFS...>()
)->data(ent);
}
}; // end DataFunctor
//! @brief Struct that allows to use applyUniversal to set data.
template< eth::base::RefElType RET >
struct SetDataFunctor
{
//! @brief Need to define a returnType_t
typedef void returnType_t;
/*! @brief Need to define static function invoke
*
* @param nds NumDofDataSet.
* @param ent Entity.
* @param data Data.
*/
static returnType_t invoke(NumDofDataSet& nds,
const entity_t<gridTraits_t::dimMesh
-eth::base::ReferenceElement<RET>::dimension>& ent,
const dataType_t& data)
{
// Employ getStorageHelper to retrieve correct storage helper
// then cast it to make it the right type (it's otherwise base class),
// then use setData function of StorageHelper to set the data.
static_cast< StorageHelper<RET>* >( nds.getStorageHelper<RET, REFS...>()
)->setData(ent, data);
}
}; // end DataFunctor
//----------------------------------------------------------------------
//! @brief A mock base class that allows for non-templated pointers to
//! \ref StorageHelper.
class StorageHelperBase {};
// A note for developers: Those {} are needed (otherwise type is incomplete).
/*! @brief Helper class for storage.
*
* This class acts as a container for data for entities of one reference type.
*
* @tparam RET Reference element type.
*/
template< enum eth::base::RefElType RET >
class StorageHelper : public StorageHelperBase
{
private:
//! Pointer to index set
const indexSet_t* indexSet_;
//! The data that is stored of all entities of reference type RET
std::vector< dataType_t > data_;
public:
//! Reference element type associated with this container.
static const eth::base::RefElType refElType = RET;
//! Co-dimension of these entities.
static const int codim = gridTraits_t::dimMesh
-eth::base::ReferenceElement<RET>::dimension;
//! Default constructor
StorageHelper() : indexSet_( nullptr ) {}
/*! @brief Resizes the data vector to a size given by an index set
*
* @param indexSet Pointer to an index set.
*
* @note The pointer to the index set passed is stored. \n
* The new values are initialized with 0.
*/
void resize( const indexSet_t* indexSet )
{
indexSet_ = indexSet;
std::cout << "Resizing data for " << RET << " to " << indexSet_->size(RET) << '\n';
data_.resize( indexSet_->size(RET) );
}
/*! @return the value stored for an entity.
*
* @param ent Entity.
*/
const dataType_t& data( const entity_t<codim>& ent ) const {
return data_[ indexSet_->index(ent) ];
}
/*! @brief Sets the value of an entity to a given input.
*
* @param ent Entity.
* @param data Data to be stored.
*/
void setData( const entity_t<codim>& ent, const dataType_t& data ) {
data_[ indexSet_->index(ent) ] = data;
}
}; // end class StorageHelper
//----------------------------------------------------------------------
//----------------------------------------------------------------------
// Some functions for dealing with StorageHelper
//! @brief Resizes storage for a given lists of reference types.
//! @note Only the number of template arguments matter, not their order.
template< eth::base::RefElType RET_1, eth::base::RefElType RET_2,
eth::base::RefElType... RETS >
void resizeStorageHelper()
{
// Get the last reference element type of list and invoke
// the in StorageHelper provided resize function to adjust vector.
std::get<sizeof...(RETS)+1>( multiplicities_ ).resize(indexSet_);
// Then invoke recursion
resizeStorageHelper<RET_2, RETS...>();
}
//! @brief Base case of resizeStorageHelper
template< eth::base::RefElType RET >
void resizeStorageHelper() {
std::get<0>( multiplicities_ ).resize(indexSet_);
}
//----------------------------------------------------------------------
/*! @return a pointer for the StorageHelper object whose reference type
* match the given one.
*
* @note The return type is a pointer of the base class of StorageHelper.
* This is because we need a non-templated return type.
*
* @tparam REF The reference element type that is searched.
* @tparam RET_1 Reference element types to compare against.
* @tparam RET_2 Reference element types to compare against.
* @tparam RETS Reference element types to compare against.
*/
template< eth::base::RefElType REF, eth::base::RefElType RET_1,
eth::base::RefElType RET_2, eth::base::RefElType... RETS >
StorageHelperBase* getStorageHelper()
{
// First check if the first tuple entry of multiplicities_ matches
// (-2 due to RET_1 and RET_2) if yes, return it!
// If no, check next entry of tuple.
return std::get<sizeof...(REFS)-sizeof...(RETS)-2>( multiplicities_ ).refElType
== REF ? &std::get<sizeof...(REFS)-sizeof...(RETS)-2>( multiplicities_ )
: getStorageHelper< REF, RET_2, RETS... >();
}
//! @brief Base case of getStorageHelper
template< eth::base::RefElType REF, eth::base::RefElType RET >
StorageHelperBase* getStorageHelper()
{
return std::get<sizeof...(REFS)-1>( multiplicities_ ).refElType == REF
? &std::get< sizeof...(REFS)-1 >( multiplicities_ )
: throw std::out_of_range("RefElType not in NumDofDataSet.");
}
template< eth::base::RefElType REF, eth::base::RefElType RET_1,
eth::base::RefElType RET_2, eth::base::RefElType... RETS >
const StorageHelperBase* getStorageHelper() const
{
// First check if the first tuple entry of multiplicities_ matches
// (-2 due to RET_1 and RET_2) if yes, return it!
// If no, check next entry of tuple.
return std::get<sizeof...(REFS)-sizeof...(RETS)-2>( multiplicities_ ).refElType
== REF ? &std::get<sizeof...(REFS)-sizeof...(RETS)-2>( multiplicities_ )
: getStorageHelper< REF, RET_2, RETS... >();
}
//! @brief Base case of getStorageHelper
template< eth::base::RefElType REF, eth::base::RefElType RET >
const StorageHelperBase* getStorageHelper() const
{
return std::get<sizeof...(REFS)-1>( multiplicities_ ).refElType == REF
? &std::get< sizeof...(REFS)-1 >( multiplicities_ )
: throw std::out_of_range("RefElType not in NumDofDataSet.");
}
// TODO Class for storage
//----------------------------------------------------------------------
//----------------------------------------------------------------------
private:
// TODO
//! De facto storage of multiplicities
std::tuple< StorageHelper<REFS>... > multiplicities_;
//! Grid view factory
......@@ -134,7 +362,8 @@ namespace betl2 {
eth::grid::GridView<viewTraits_t> gridView_;
//! Pointer to index set of gridView_
const indexSet_t* indexSet_;
};
}; // end class NumDofDataSet
//------------------------------------------------------------------------
//------------------------------------------------------------------------
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment