Commit 36b5ce4d authored by wagnandr's avatar wagnandr
Browse files

Merge branch 'master' into wagnandr/dg-enriched

parents b3993b3f 474976d2
Pipeline #39023 failed with stages
in 32 minutes and 45 seconds
......@@ -197,6 +197,7 @@ endif()
string( TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_UPPER )
set ( HYTEG_BUILD_TYPE ${CMAKE_BUILD_TYPE} )
set ( HYTEG_COMPILER_INFO "${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}" )
set ( HYTEG_COMPILER_FLAGS "${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE_UPPER}} ${CMAKE_CXX_FLAGS}" )
string ( REPLACE "\"" "\\\"" HYTEG_COMPILER_FLAGS ${HYTEG_COMPILER_FLAGS} )
......
......@@ -24,7 +24,7 @@
namespace hyteg {
std::string buildFlavour()
std::string buildType()
{
return "@HYTEG_BUILD_TYPE@";
}
......@@ -34,11 +34,17 @@ std::string compilerFlags()
return "@HYTEG_COMPILER_FLAGS@";
}
std::string compilerInfo()
{
return "@HYTEG_COMPILER_INFO@";
}
void printBuildInfo()
{
WALBERLA_LOG_INFO_ON_ROOT( "Build info:" )
WALBERLA_LOG_INFO_ON_ROOT( " - flavour: " << buildFlavour() );
WALBERLA_LOG_INFO_ON_ROOT( " - compiler flags: " << compilerFlags() );
WALBERLA_LOG_INFO_ON_ROOT( " - build type ....... " << buildType() );
WALBERLA_LOG_INFO_ON_ROOT( " - compiler ......... " << compilerInfo() );
WALBERLA_LOG_INFO_ON_ROOT( " - compiler flags ... " << compilerFlags() );
}
}
......@@ -45,15 +45,19 @@ enum class CellType : uint_t
GREEN_DOWN
};
const std::map< CellType, std::string > CellTypeToStr = {{CellType::WHITE_UP, "WHITE_UP"},
{CellType::BLUE_UP, "BLUE_UP"},
{CellType::GREEN_UP, "GREEN_UP"},
{CellType::WHITE_DOWN, "WHITE_DOWN"},
{CellType::BLUE_DOWN, "BLUE_DOWN"},
{CellType::GREEN_DOWN, "GREEN_DOWN"}};
const std::array< CellType, 6 > allCellTypes = {
{CellType::WHITE_UP, CellType::BLUE_UP, CellType::GREEN_UP, CellType::WHITE_DOWN, CellType::BLUE_DOWN, CellType::GREEN_DOWN}};
const std::map< CellType, std::string > CellTypeToStr = { { CellType::WHITE_UP, "WHITE_UP" },
{ CellType::BLUE_UP, "BLUE_UP" },
{ CellType::GREEN_UP, "GREEN_UP" },
{ CellType::WHITE_DOWN, "WHITE_DOWN" },
{ CellType::BLUE_DOWN, "BLUE_DOWN" },
{ CellType::GREEN_DOWN, "GREEN_DOWN" } };
const std::array< CellType, 6 > allCellTypes = { { CellType::WHITE_UP,
CellType::BLUE_UP,
CellType::GREEN_UP,
CellType::WHITE_DOWN,
CellType::BLUE_DOWN,
CellType::GREEN_DOWN } };
namespace macrocell {
......@@ -78,6 +82,27 @@ inline constexpr uint_t numCellsPerRowByType( const uint_t& level, const CellTyp
}
}
inline constexpr uint_t numCellsPerRowByTypeFromWidth( const uint_t& width, const CellType& cellType )
{
switch ( cellType )
{
case CellType::WHITE_UP:
return levelinfo::num_microedges_per_edge_from_width( width );
case CellType::BLUE_UP:
return levelinfo::num_microedges_per_edge_from_width( width ) - 1;
case CellType::GREEN_UP:
return levelinfo::num_microedges_per_edge_from_width( width ) - 1;
case CellType::WHITE_DOWN:
return levelinfo::num_microedges_per_edge_from_width( width ) - 2;
case CellType::BLUE_DOWN:
return levelinfo::num_microedges_per_edge_from_width( width ) - 1;
case CellType::GREEN_DOWN:
return levelinfo::num_microedges_per_edge_from_width( width ) - 1;
default:
return std::numeric_limits< uint_t >::max();
}
}
inline constexpr uint_t numMicroCellsPerMacroCell( const uint_t& level, const CellType& cellType )
{
return levelinfo::num_microvertices_per_cell_from_width( numCellsPerRowByType( level, cellType ) );
......@@ -135,35 +160,35 @@ inline std::array< Index, 4 > getMicroVerticesFromMicroCell( const Index& microC
switch ( microCellType )
{
case CellType::WHITE_UP:
return std::array< Index, 4 >( {{Index( cellX, cellY, cellZ ),
Index( cellX + 1, cellY, cellZ ),
Index( cellX, cellY + 1, cellZ ),
Index( cellX, cellY, cellZ + 1 )}} );
return std::array< Index, 4 >( { { Index( cellX, cellY, cellZ ),
Index( cellX + 1, cellY, cellZ ),
Index( cellX, cellY + 1, cellZ ),
Index( cellX, cellY, cellZ + 1 ) } } );
case CellType::BLUE_UP:
return std::array< Index, 4 >( {{Index( cellX + 1, cellY, cellZ ),
Index( cellX + 1, cellY + 1, cellZ ),
Index( cellX, cellY + 1, cellZ ),
Index( cellX + 1, cellY, cellZ + 1 )}} );
return std::array< Index, 4 >( { { Index( cellX + 1, cellY, cellZ ),
Index( cellX + 1, cellY + 1, cellZ ),
Index( cellX, cellY + 1, cellZ ),
Index( cellX + 1, cellY, cellZ + 1 ) } } );
case CellType::GREEN_UP:
return std::array< Index, 4 >( {{Index( cellX + 1, cellY, cellZ ),
Index( cellX, cellY + 1, cellZ ),
Index( cellX + 1, cellY, cellZ + 1 ),
Index( cellX, cellY, cellZ + 1 )}} );
return std::array< Index, 4 >( { { Index( cellX + 1, cellY, cellZ ),
Index( cellX, cellY + 1, cellZ ),
Index( cellX + 1, cellY, cellZ + 1 ),
Index( cellX, cellY, cellZ + 1 ) } } );
case CellType::WHITE_DOWN:
return std::array< Index, 4 >( {{Index( cellX + 1, cellY + 1, cellZ ),
Index( cellX + 1, cellY + 1, cellZ + 1 ),
Index( cellX, cellY + 1, cellZ + 1 ),
Index( cellX + 1, cellY, cellZ + 1 )}} );
return std::array< Index, 4 >( { { Index( cellX + 1, cellY + 1, cellZ ),
Index( cellX + 1, cellY + 1, cellZ + 1 ),
Index( cellX, cellY + 1, cellZ + 1 ),
Index( cellX + 1, cellY, cellZ + 1 ) } } );
case CellType::BLUE_DOWN:
return std::array< Index, 4 >( {{Index( cellX + 1, cellY, cellZ + 1 ),
Index( cellX, cellY + 1, cellZ + 1 ),
Index( cellX, cellY, cellZ + 1 ),
Index( cellX, cellY + 1, cellZ )}} );
return std::array< Index, 4 >( { { Index( cellX + 1, cellY, cellZ + 1 ),
Index( cellX, cellY + 1, cellZ + 1 ),
Index( cellX, cellY, cellZ + 1 ),
Index( cellX, cellY + 1, cellZ ) } } );
case CellType::GREEN_DOWN:
return std::array< Index, 4 >( {{Index( cellX, cellY + 1, cellZ ),
Index( cellX + 1, cellY + 1, cellZ ),
Index( cellX + 1, cellY, cellZ + 1 ),
Index( cellX, cellY + 1, cellZ + 1 )}} );
return std::array< Index, 4 >( { { Index( cellX, cellY + 1, cellZ ),
Index( cellX + 1, cellY + 1, cellZ ),
Index( cellX + 1, cellY, cellZ + 1 ),
Index( cellX, cellY + 1, cellZ + 1 ) } } );
default:
WALBERLA_ABORT( "Not implemented for this cell type." );
break;
......
......@@ -47,23 +47,19 @@ void VTKDGWriter::write( const VTKOutput& mgr, std::ostream& output, const uint_
auto storage = mgr.storage_;
WALBERLA_CHECK( !storage->hasGlobalCells(), "DG VTK output not implemented for 3D" );
const std::map< uint_t, uint_t > degreeToEvalPoints2D = {
{ 1, 3 },
{ 2, 6 },
};
const uint_t numberOfPoints2D = storage->getNumberOfLocalFaces() * levelinfo::num_microfaces_per_face( level ) * 3;
const uint_t numberOfCells2D = storage->getNumberOfLocalFaces() * levelinfo::num_microfaces_per_face( level );
const uint_t numberOfPoints3D = storage->getNumberOfLocalCells() * levelinfo::num_microcells_per_cell( level ) * 4;
const uint_t numberOfCells3D = storage->getNumberOfLocalCells() * levelinfo::num_microcells_per_cell( level );
if ( mgr.write2D_ )
{
vtk::writePieceHeader( output, numberOfPoints2D, numberOfCells2D );
}
else
{
// TODO
vtk::writePieceHeader( output, numberOfPoints3D, numberOfCells3D );
}
output << "<Points>\n";
......@@ -157,7 +153,27 @@ void VTKDGWriter::writeScalarFunction( std::ostream&
}
else
{
WALBERLA_ABORT( "DGFunction VTK not implemented in 3D." );
for ( const auto& it : storage->getCells() )
{
const PrimitiveID cellID = it.first;
const Cell& cell = *it.second;
for ( auto cellType : celldof::allCellTypes )
{
for ( const auto& idxIt : celldof::macrocell::Iterator( level, cellType ) )
{
const std::array< indexing::Index, 4 > vertexIndices =
celldof::macrocell::getMicroVerticesFromMicroCell( idxIt, cellType );
for ( uint_t i = 0; i < 4; i++ )
{
const auto vtkPoint = vertexdof::macrocell::coordinateFromIndex( level, cell, vertexIndices[i] );
value_t value;
function.evaluateOnMicroElement( vtkPoint, level, cellID, idxIt, cellType, value );
streamWriter << value;
}
}
}
}
}
streamWriter.toStream( output );
......
......@@ -99,7 +99,25 @@ void VTKMeshWriter::writePointsForMicroVertices( const VTKOutput&
{
if ( discontinuous )
{
WALBERLA_ABORT( "Discontinuous points not implemented for 3D." );
for ( const auto& it : storage->getCells() )
{
const Cell& cell = *it.second;
for ( auto cellType : celldof::allCellTypes )
{
for ( const auto& idxIt : celldof::macrocell::Iterator( level, cellType ) )
{
auto vertexIndices = celldof::macrocell::getMicroVerticesFromMicroCell( idxIt, cellType );
for ( auto vIdx : vertexIndices )
{
const Point3D vtkPoint = vertexdof::macrocell::coordinateFromIndex( level, cell, vIdx );
Point3D xBlend;
cell.getGeometryMap()->evalF( vtkPoint, xBlend );
streamWriter << xBlend[0] << xBlend[1] << xBlend[2];
}
}
}
}
}
else
{
......@@ -368,8 +386,6 @@ void VTKMeshWriter::writeCells3D( const VTKOutput& mgr
uint_t width,
bool discontinuous )
{
WALBERLA_CHECK( !discontinuous, "Discontinuous VTK cells not implemented in 3D." );
using CellIdx_T = int32_t;
output << "<Cells>\n";
......@@ -381,8 +397,9 @@ void VTKMeshWriter::writeCells3D( const VTKOutput& mgr
auto calcVTKPointArrayPosition = [width]( const indexing::Index& vertexIndex ) -> uint_t {
const uint_t zOffset = levelinfo::num_microvertices_per_cell_from_width( width ) -
levelinfo::num_microvertices_per_cell_from_width( width - uint_c( vertexIndex.z() ) );
const uint_t yOffset = levelinfo::num_microvertices_per_face_from_width( width - uint_c( vertexIndex.z() ) ) -
levelinfo::num_microvertices_per_face_from_width( width - uint_c( vertexIndex.z() ) - uint_c( vertexIndex.y() ) );
const uint_t yOffset =
levelinfo::num_microvertices_per_face_from_width( width - uint_c( vertexIndex.z() ) ) -
levelinfo::num_microvertices_per_face_from_width( width - uint_c( vertexIndex.z() ) - uint_c( vertexIndex.y() ) );
const uint_t xOffset = uint_c( vertexIndex.x() );
return xOffset + yOffset + zOffset;
};
......@@ -390,67 +407,90 @@ void VTKMeshWriter::writeCells3D( const VTKOutput& mgr
const uint_t numberOfVertices = levelinfo::num_microvertices_per_cell_from_width( width );
const uint_t numberOfCells = levelinfo::num_microcells_per_cell_from_width( width );
CellIdx_T offset = 0;
for ( uint_t macroCellIdx = 0; macroCellIdx < storage->getNumberOfLocalCells(); macroCellIdx++ )
{
for ( const auto& it : indexing::CellIterator( width - 1 ) )
if ( discontinuous )
{
const auto spanningVertexIndices = celldof::macrocell::getMicroVerticesFromMicroCell( it, celldof::CellType::WHITE_UP );
for ( const auto& spanningVertexIndex : spanningVertexIndices )
for ( auto cellType : celldof::allCellTypes )
{
streamWriterCells << macroCellIdx * numberOfVertices + calcVTKPointArrayPosition( spanningVertexIndex );
celldof::macrocell::numCellsPerRowByTypeFromWidth( width, cellType );
const uint_t numMicroCellsAtBoundary = celldof::macrocell::numCellsPerRowByTypeFromWidth( width, cellType );
for ( const auto& idxIt : indexing::CellIterator( numMicroCellsAtBoundary ) )
{
streamWriterCells << offset << offset + 1 << offset + 2 << offset + 3;
offset += 4;
WALBERLA_UNUSED( idxIt );
}
}
}
for ( const auto& it : indexing::CellIterator( width - 2 ) )
else
{
const auto spanningVertexIndices = celldof::macrocell::getMicroVerticesFromMicroCell( it, celldof::CellType::BLUE_UP );
for ( const auto& spanningVertexIndex : spanningVertexIndices )
for ( const auto& it : indexing::CellIterator( width - 1 ) )
{
streamWriterCells << macroCellIdx * numberOfVertices + calcVTKPointArrayPosition( spanningVertexIndex );
}
}
const auto spanningVertexIndices =
celldof::macrocell::getMicroVerticesFromMicroCell( it, celldof::CellType::WHITE_UP );
for ( const auto& it : indexing::CellIterator( width - 2 ) )
{
const auto spanningVertexIndices = celldof::macrocell::getMicroVerticesFromMicroCell( it, celldof::CellType::GREEN_UP );
for ( const auto& spanningVertexIndex : spanningVertexIndices )
{
streamWriterCells << macroCellIdx * numberOfVertices + calcVTKPointArrayPosition( spanningVertexIndex );
}
}
for ( const auto& spanningVertexIndex : spanningVertexIndices )
for ( const auto& it : indexing::CellIterator( width - 2 ) )
{
streamWriterCells << macroCellIdx * numberOfVertices + calcVTKPointArrayPosition( spanningVertexIndex );
}
}
const auto spanningVertexIndices =
celldof::macrocell::getMicroVerticesFromMicroCell( it, celldof::CellType::BLUE_UP );
for ( const auto& it : indexing::CellIterator( width - 3 ) )
{
const auto spanningVertexIndices =
celldof::macrocell::getMicroVerticesFromMicroCell( it, celldof::CellType::WHITE_DOWN );
for ( const auto& spanningVertexIndex : spanningVertexIndices )
{
streamWriterCells << macroCellIdx * numberOfVertices + calcVTKPointArrayPosition( spanningVertexIndex );
}
}
for ( const auto& spanningVertexIndex : spanningVertexIndices )
for ( const auto& it : indexing::CellIterator( width - 2 ) )
{
streamWriterCells << macroCellIdx * numberOfVertices + calcVTKPointArrayPosition( spanningVertexIndex );
}
}
const auto spanningVertexIndices =
celldof::macrocell::getMicroVerticesFromMicroCell( it, celldof::CellType::GREEN_UP );
for ( const auto& it : indexing::CellIterator( width - 2 ) )
{
const auto spanningVertexIndices = celldof::macrocell::getMicroVerticesFromMicroCell( it, celldof::CellType::BLUE_DOWN );
for ( const auto& spanningVertexIndex : spanningVertexIndices )
{
streamWriterCells << macroCellIdx * numberOfVertices + calcVTKPointArrayPosition( spanningVertexIndex );
}
}
for ( const auto& spanningVertexIndex : spanningVertexIndices )
for ( const auto& it : indexing::CellIterator( width - 3 ) )
{
streamWriterCells << macroCellIdx * numberOfVertices + calcVTKPointArrayPosition( spanningVertexIndex );
const auto spanningVertexIndices =
celldof::macrocell::getMicroVerticesFromMicroCell( it, celldof::CellType::WHITE_DOWN );
for ( const auto& spanningVertexIndex : spanningVertexIndices )
{
streamWriterCells << macroCellIdx * numberOfVertices + calcVTKPointArrayPosition( spanningVertexIndex );
}
}
}
for ( const auto& it : indexing::CellIterator( width - 2 ) )
{
const auto spanningVertexIndices =
celldof::macrocell::getMicroVerticesFromMicroCell( it, celldof::CellType::GREEN_DOWN );
for ( const auto& it : indexing::CellIterator( width - 2 ) )
{
const auto spanningVertexIndices =
celldof::macrocell::getMicroVerticesFromMicroCell( it, celldof::CellType::BLUE_DOWN );
for ( const auto& spanningVertexIndex : spanningVertexIndices )
for ( const auto& spanningVertexIndex : spanningVertexIndices )
{
streamWriterCells << macroCellIdx * numberOfVertices + calcVTKPointArrayPosition( spanningVertexIndex );
}
}
for ( const auto& it : indexing::CellIterator( width - 2 ) )
{
streamWriterCells << macroCellIdx * numberOfVertices + calcVTKPointArrayPosition( spanningVertexIndex );
const auto spanningVertexIndices =
celldof::macrocell::getMicroVerticesFromMicroCell( it, celldof::CellType::GREEN_DOWN );
for ( const auto& spanningVertexIndex : spanningVertexIndices )
{
streamWriterCells << macroCellIdx * numberOfVertices + calcVTKPointArrayPosition( spanningVertexIndex );
}
}
}
}
......@@ -465,7 +505,7 @@ void VTKMeshWriter::writeCells3D( const VTKOutput& mgr
VTKOutput::VTKStreamWriter< OffsetType > streamWriterOffsets( mgr.vtkDataFormat_ );
// offsets
uint_t offset = 4;
offset = 4;
for ( const auto& it : storage->getCells() )
{
WALBERLA_UNUSED( it );
......
......@@ -3,8 +3,10 @@ target_sources( hyteg
DGBasisInfo.hpp
DGBasisLinearLagrange_Example.hpp
DGDiffusionForm_Example.hpp
DGDiffusionForm_Example.cpp
DGForm.hpp
DGForm2D.hpp
DGFormVolume.hpp
DGFunction.cpp
DGFunction.hpp
DGMassForm_Example.hpp
......
......@@ -42,8 +42,8 @@ class DGBasisInfo
/// \brief Returns the maximum polynomial degree for which basis functions are implemented.
virtual uint_t maxPolynomialDegree() const = 0;
/// \brief Returns the number of DoFs per element for the passed polynomial degree.
virtual uint_t numDoFsPerElement( uint_t degree ) const = 0;
/// \brief Returns the number of DoFs per element for the passed polynomial degree and type of the element.
virtual uint_t numDoFsPerElement( uint_t dim, uint_t degree ) const = 0;
/// \brief Returns the degree of the quadrature rule that is used for the evaluation of the linear functional \f$\int_T f \phi_i\f$.
virtual uint_t quadratureDegreeForLinearFunctional() const = 0;
......@@ -59,13 +59,24 @@ class DGBasisInfo
const std::vector< real_t >& dofs,
real_t& value ) const = 0;
/// \brief Evaluates the polynomial on the reference tetrahedron.
///
/// \param degree degree of the piecewise polynomials
/// \param pos where to evaluate on the micro-element (in reference space)
/// \param dofs DoFs that correspond to the basis functions
/// \param value value of the polynomial
virtual void evaluate( uint_t degree,
const Eigen::Matrix< real_t, 3, 1 >& pos,
const std::vector< real_t >& dofs,
real_t& value ) const = 0;
/// \brief Evaluates the linear functional
///
/// \f{align*}{
/// l( v ) = \int_T f v
/// \f}
///
/// by quadrature over the passed element \f$T\f$ for all basis functions, i.e. it returns an approximation to
/// by quadrature over the passed face element \f$T\f$ for all basis functions, i.e. it returns an approximation to
///
/// \f{align*}{
/// \int_T f \phi_i.
......@@ -79,6 +90,27 @@ class DGBasisInfo
const std::array< Eigen::Matrix< real_t, 2, 1 >, 3 >& coords,
const std::function< real_t( const Point3D& ) >& f,
std::vector< real_t >& values ) = 0;
/// \brief Evaluates the linear functional
///
/// \f{align*}{
/// l( v ) = \int_T f v
/// \f}
///
/// by quadrature over the passed cell element \f$T\f$ for all basis functions, i.e. it returns an approximation to
///
/// \f{align*}{
/// \int_T f \phi_i.
/// \f}
///
/// \param degree degree of the piecewise polynomials
/// \param coords coordinates of the affine element (computational space)
/// \param f function to multiply with the basis functions
/// \param value result of the integration (all DoFs)
virtual void integrateBasisFunction( uint_t degree,
const std::array< Eigen::Matrix< real_t, 3, 1 >, 4 >& coords,
const std::function< real_t( const Point3D& ) >& f,
std::vector< real_t >& values ) = 0;
};
} // namespace dg
......
......@@ -39,11 +39,24 @@ class DGBasisLinearLagrange_Example : public DGBasisInfo
virtual uint_t maxPolynomialDegree() const { return 1; }
virtual uint_t numDoFsPerElement( uint_t degree ) const
virtual uint_t numDoFsPerElement( uint_t dim, uint_t degree ) const
{
WALBERLA_CHECK_LESS_EQUAL( degree, 1, "Only const or linear elements supported." );
const std::map< uint_t, uint_t > ndofs = { { 0, 1 }, { 1, 3 } };
return ndofs.at( degree );
if ( dim == 2 )
{
WALBERLA_CHECK_LESS_EQUAL( degree, 1, "Only const or linear elements supported." );
const std::map< uint_t, uint_t > ndofs = { { 0, 1 }, { 1, 3 } };
return ndofs.at( degree );
}
else if ( dim == 3 )
{
WALBERLA_CHECK_LESS_EQUAL( degree, 1, "Only const or linear elements supported." );
const std::map< uint_t, uint_t > ndofs = { { 0, 1 }, { 1, 4 } };
return ndofs.at( degree );
}
else
{
WALBERLA_ABORT( "Dimensionality invalid." );
}
}
virtual uint_t quadratureDegreeForLinearFunctional() const { return 4; }
......@@ -51,7 +64,7 @@ class DGBasisLinearLagrange_Example : public DGBasisInfo
virtual void
evaluate( uint_t degree, const Eigen::Matrix< real_t, 2, 1 >& pos, const std::vector< real_t >& dofs, real_t& value ) const
{
WALBERLA_CHECK_EQUAL( dofs.size(), numDoFsPerElement( degree ), "Number of DoFs does not match degree." );
WALBERLA_CHECK_EQUAL( dofs.size(), numDoFsPerElement( 2, degree ), "Number of DoFs does not match degree." );
switch ( degree )
{
......@@ -104,12 +117,43 @@ class DGBasisLinearLagrange_Example : public DGBasisInfo
}
};
virtual void
evaluate( uint_t degree, const Eigen::Matrix< real_t, 3, 1 >& pos, const std::vector< real_t >& dofs, real_t& value ) const
{
WALBERLA_CHECK_EQUAL( dofs.size(), numDoFsPerElement( 3, degree ), "Number of DoFs does not match degree." );
switch ( degree )
{
case 0: {
value = dofs[0];
break;
}
case 1: {
const auto dof_0 = dofs[0];
const auto dof_1 = dofs[1];
const auto dof_2 = dofs[2];
const auto dof_3 = dofs[3];
// ref space
const auto x_ref_0 = pos( 0 );
const auto x_ref_1 = pos( 1 );
const auto x_ref_2 = pos( 2 );
real_t a_0_0 = dof_0 * ( -x_ref_0 - x_ref_1 - x_ref_2 + 1 ) + dof_1 * x_ref_0 + dof_2 * x_ref_1 + dof_3 * x_ref_2;
value = a_0_0;
}
}
};
virtual void integrateBasisFunction( uint_t degree,
const std::array< Eigen::Matrix< real_t, 2, 1 >, 3 >& coords,
const std::function< real_t( const Point3D& ) >& f,
std::vector< real_t >& values )
{
values.resize( numDoFsPerElement( degree ) );
values.resize( numDoFsPerElement( 2, degree ) );
const auto p_affine_0_0 = coords[0]( 0 );
const auto p_affine_0_1 = coords[0]( 1 );
......@@ -188,13 +232,237 @@ class DGBasisLinearLagrange_Example : public DGBasisInfo
}
}
virtual void integrateBasisFunction( uint_t degree,
const std::array< Eigen::Matrix< real_t, 3, 1 >, 4 >& coords,
const std::function< real_t( const Point3D& ) >& f,
std::vector< real_t >& values )
{
values.resize( numDoFsPerElement( 3, degree ) );
const auto p_affine_0_0 = coords[0]( 0 );
const auto p_affine_0_1 = coords[0]( 1 );
const auto p_affine_0_2 = coords[0]( 2 );
const auto p_affine_1_0 = coords[1]( 0 );
const auto p_affine_1_1 = coords[1]( 1 );