Commit f9a757d2 authored by Praetorius, Simon's avatar Praetorius, Simon

started to rewrite Assembler using dune-functions globalBasis

parent beb6bd46
......@@ -7,6 +7,8 @@ if(NOT (dune-common_DIR OR dune-common_ROOT OR
${PROJECT_BINARY_DIR})
endif()
set(CXX_MAX_STANDARD 14)
#find dune-common and set the module path
find_package(dune-common REQUIRED)
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/modules"
......
......@@ -6,139 +6,89 @@
#include <dune/common/fmatrix.hh>
#include <dune/common/fvector.hh>
#include <dune/amdis/FiniteElementSpaces.hpp>
#include <dune/amdis/LinearAlgebra.hpp>
#include <dune/amdis/common/Mpl.hpp>
#include <dune/amdis/common/TypeDefs.hpp>
namespace AMDiS
{
template <class FeSpaces>
template <class GlobalBasis>
class Assembler
{
template <std::size_t I>
using FeSpace = std::tuple_element_t<I, FeSpaces>;
/// Number of problem components
static constexpr int nComponents = std::tuple_size<FeSpaces>::value;
/// The grid view the global FE basis lives on
using GridView = typename FeSpace<0>::GridView;
using SystemMatrixType = SystemMatrix<FeSpaces>;
using SystemVectorType = SystemVector<FeSpaces>;
template <class T>
using MatrixEntries = Dune::FieldMatrix<T, nComponents, nComponents>;
using GridView = typename GlobalBasis::GridView;
template <class T>
using VectorEntries = Dune::FieldVector<T, nComponents>;
using SystemMatrixType = SystemMatrix<GlobalBasis>;
using SystemVectorType = SystemVector<GlobalBasis>;
using ElementVector = Impl::ElementVector;
using ElementMatrix = Impl::ElementMatrix;
using TypeTree = typename GlobalBasis::LocalView::Tree;
using
public:
/// Constructor, stores a shared-pointer to the feSpaces
Assembler(std::shared_ptr<FeSpaces> const& feSpaces, bool asmMatrix, bool asmVector)
: globalBases_(feSpaces)
Assembler(std::shared_ptr<GlobalBasis> const& globalBasis, bool asmMatrix, bool asmVector)
: globalBasis_(globalBasis)
, asmMatrix_(asmMatrix)
, asmVector_(asmVector)
{}
/// Assemble the linear system
template <class Operators>
template <class MatrixOperators, class VectorOperators>
void assemble(
GridView const& gv,
SystemMatrixType& matrix,
SystemVectorType& solution,
SystemVectorType& rhs,
MatrixEntries<Operators>& matrix_operators,
VectorEntries<Operators>& rhs_operators);
MatrixOperators& matrixOperators,
VectorOperators& rhsOperators);
private:
/// Sets the system to zero and initializes all operators and boundary conditions
template <class Operators>
template <class MatrixOperators, class VectorOperators>
void initMatrixVector(
SystemMatrixType& matrix,
SystemVectorType& solution,
SystemVectorType& rhs,
MatrixEntries<Operators>& matrix_operators,
VectorEntries<Operators>& rhs_operators) const;
MatrixOperators& matrixOperators,
VectorOperators& rhsOperators) const;
/// Assemble a block-matrix of element-matrices and return a matrix of flags, whether
/// a given block has received some entries.
template <class Operators>
MatrixEntries<bool> assembleElementMatrices(
MatrixEntries<Operators>& operators,
MatrixEntries<ElementMatrix>& elementMatrix) const;
/// Assemble a block-vector of element-vectors and return a vector of flags, whether
/// a given block has received some entries.
template <class Operators>
VectorEntries<bool> assembleElementVectors(
VectorEntries<Operators>& operators,
VectorEntries<ElementVector>& elementVector) const;
template <class MatrixOperators, class VectorOperators>
void assembleElement(
SystemMatrixType& matrix,
SystemVectorType& rhs,
MatrixOperators& matrixOperators,
VectorOperators& rhsOperators) const;
/// Assemble one block of the block-element-matrix
// The MatrixData argument stores all matrix-operators
template <class Operators, class RowView, class ColView>
bool assembleElementMatrix(
template <class ElementContainer, class Container, class Operators, class... Bases>
void assembleElementOperators(
ElementContainer& elementContainer,
Container& container,
Operators& operators,
ElementMatrix& elementMatrix,
RowView const& rowLocalView,
ColView const& colLocalView) const;
/// Assemble one block of the block-element-vector
// The VectorData argument stores all vector-operators
template <class Operators, class RowView>
bool assembleElementVector(
Operators& operators,
ElementVector& elementVector,
RowView const& rowLocalView) const;
/// Add the block-element-matrix to the system-matrix
void addElementMatrices(
SystemMatrixType& dofmatrix,
MatrixEntries<bool> const& addMat,
MatrixEntries<ElementMatrix> const& elementMatrix) const;
Bases const&... subBases) const;
/// Add the block-element-vector to the system-vector
void addElementVectors(
SystemVectorType& dofvector,
VectorEntries<bool> const& addVec,
VectorEntries<ElementVector> const& elementVector) const;
/// Finish insertion into the matrix and assembles boundary conditions
/// Return the number of nonzeros assembled into the matrix
template <class Operators>
template <class MatrixOperators, class VectorOperators>
std::size_t finishMatrixVector(
SystemMatrixType& matrix,
SystemVectorType& solution,
SystemVectorType& rhs,
MatrixEntries<Operators>& matrix_operators,
VectorEntries<Operators>& rhs_operators) const;
MatrixOperators& matrixOperators,
VectorOperators& rhsOperators) const;
/// Return whether the matrix-block needs to be assembled
template <std::size_t R, std::size_t C, class Operators>
bool assembleMatrix(const index_t<R>, const index_t<C>,
MatrixEntries<Operators> const& matrix_operators) const
{
return asmMatrix_ && (!matrix_operators[R][C].assembled || matrix_operators[R][C].changing);
}
/// Return whether the vector-block needs to be assembled
template <std::size_t R, class Operators>
bool assembleVector(const index_t<R>, VectorEntries<Operators> const& rhs_operators) const
template <class Basis0, class... Bases>
auto getElement(Basis0 const& basis0, Bases const&... bases) const
{
return asmVector_ && (!rhs_operators[R].assembled || rhs_operators[R].changing);
return basis0.localView().element();
}
private:
FiniteElementSpaces<FeSpaces> globalBases_;
std::shared_ptr<GlobalBasis> globalBasis_;
bool asmMatrix_;
bool asmVector_;
};
......
This diff is collapsed.
......@@ -19,7 +19,7 @@ dune_add_library("duneamdis" NO_EXPORT
)
add_dune_alberta_flags("duneamdis" OBJECT USE_GENERIC)
target_compile_definitions("duneamdis" PUBLIC AMDIS_BACKEND_MTL=1)
target_compile_options("duneamdis" PUBLIC -ftemplate-backtrace-limit=0)
target_compile_options("duneamdis" PUBLIC -ftemplate-backtrace-limit=0 -Wall -pedantic -Wno-unused-parameter)
find_package(MTL REQUIRED
PATHS /usr/local/lib/mtl4)
......
......@@ -12,7 +12,7 @@ namespace AMDiS
// All classes that need creators must specialize this class and implement
// a static void init() method.
template <class BaseClass>
struct DefaultCreators;
class DefaultCreators;
/** \ingroup Common
......
......@@ -28,7 +28,7 @@ namespace AMDiS
static constexpr int dim = Traits::dim;
/// Dimension of the world
static constexpr int dow = Traits::dimworld;
static constexpr int dow = Traits::dow;
/// Number of problem components
static constexpr int nComponents = Traits::nComponents;
......
......@@ -2,6 +2,7 @@
#include <dune/amdis/common/TupleUtility.hpp>
#include <dune/amdis/common/IndexSeq.hpp>
#include <dune/amdis/common/Loops.hpp>
namespace AMDiS
{
......@@ -61,10 +62,15 @@ namespace AMDiS
forEach(range_<0, nComponents>, [&,this](auto const _i)
{
static const int I = decltype(_i)::value;
std::get<I>(localViews_).bind(element);
std::get<I>(localIndexSets_).bind(std::get<I>(localViews_));
auto& localView = std::get<I>(localViews_);
localView.bind(element);
auto& localIndexSet = std::get<I>(localIndexSets_);
localIndexSet.bind(localView);
});
// NOTE: maybe create element-geometry here
bound_ = true;
}
/// Unbind from the current element
......@@ -76,10 +82,11 @@ namespace AMDiS
std::get<I>(localIndexSets_).unbind();
std::get<I>(localViews_).unbind();
});
bound_ = false;
}
template <std::size_t I>
auto const& basis(const index_t<I> _i = {}) const
auto const& feSpace(const index_t<I> _i = {}) const
{
return std::get<I>(*feSpaces_);
}
......@@ -87,28 +94,40 @@ namespace AMDiS
template <std::size_t I>
auto const& localView(const index_t<I> _i = {}) const
{
assert( bound_ && "localViews must be bound to an element." );
return std::get<I>(localViews_);
}
template <std::size_t I>
auto const& localIndexSet(const index_t<I> _i = {}) const
{
assert( bound_ && "localIndexSets must be bound to a localView." );
return std::get<I>(localIndexSets_);
}
auto const& element() const
{
assert( bound_ && "localViews must be bound to an element." );
return std::get<0>(localViews_).element();
}
auto const& gridView() const
{
return std::get<0>(*feSpaces_).gridView();
}
private:
/// Tuple of global functionspace bases
std::shared_ptr<FeSpaces> feSpaces_;
/// tuple of localView objects, obtained from the tuple of global bases
/// Tuple of localView objects, obtained from the tuple of global bases
LocalViews localViews_;
// tuple of localIndexSet objects, obtained from the tuple of global bases
/// Tuple of localIndexSet objects, obtained from the tuple of global bases
LocalIndexSets localIndexSets_;
/// True, if localViews and localIndexSets are bound to an element
bool bound_ = false;
};
} // end namespace AMDiS
......@@ -70,8 +70,6 @@ namespace AMDiS
/// geometry() for entities or geometryInInside() for intersections
Geometry geometry;
// TODO: create geometry just once for each element, e.g. in ProblemStat when traversing the grid
};
} // end namespace AMDiS
......@@ -18,17 +18,12 @@ namespace AMDiS
{
// the LocalContext is either an Codim=0-EntityType or an IntersectionType
template <class MeshView, class LocalContext>
template <class GridView, class LocalContext>
class Operator
{
using Self = Operator;
using OperatorTermType = OperatorTerm<LocalContext>;
using ElementVector = Impl::ElementVector;
using ElementMatrix = Impl::ElementMatrix;
using IdType = typename MeshView::Grid::LocalIdSet::IdType;
template <class, class> friend class ZeroOrderAssembler;
template <class, class, FirstOrderType> friend class FirstOrderAssembler;
template <class, class> friend class SecondOrderAssembler;
......@@ -114,13 +109,13 @@ namespace AMDiS
public: // initialize and assemble operator on element
/// Extract the polynomial degree from \p rowFeSpace and \p colFeSpace.
template <class RowFeSpace, class ColFeSpace>
void init(RowFeSpace const& rowFeSpace,
ColFeSpace const& colFeSpace);
/// Extract the polynomial degree from \p rowBasis and \p colBasis.
template <class RowBasis, class ColBasis>
void init(RowBasis const& rowBasis,
ColBasis const& colBasis);
template <class RowFeSpace>
void init(RowFeSpace const& rowFeSpace);
template <class RowBasis>
void init(RowBasis const& rowBasis);
/// Calculates the needed quadrature degree for the given term-order \p order.
......@@ -131,16 +126,22 @@ namespace AMDiS
FirstOrderType firstOrderType = GRD_PHI);
template <class RowView, class ColView>
bool getElementMatrix(LocalContext const& element,
// assemble matrix operator
template <class RowView, class ColView, class ElementMatrix>
bool assemble(
GridView const& gv,
LocalContext const& element,
RowView const& rowView,
ColView const& colView,
ElementMatrix& elementMatrix,
double* factor = NULL);
template <class RowView>
bool getElementVector(LocalContext const& element,
RowView const& rowView,
// assemble vector operator
template <class LocalView, class ElementVector>
bool assemble(
GridView const& gv,
LocalContext const& element,
LocalView const& localView,
ElementVector& elementVector,
double* factor = NULL);
......@@ -228,7 +229,10 @@ namespace AMDiS
private:
template <class LocalView>
IdType getElementId(LocalView const& localView);
std::size_t getElementIndex(GridView const& gridView, LocalView const& localView) const
{
return gridView.indexSet().index(localView.element());
}
private:
......@@ -248,13 +252,154 @@ namespace AMDiS
int psiDegree = 1;
int phiDegree = 1;
IdType lastMatrixId = 0;
IdType lastVectorId = 0;
std::size_t lastMatrixIndex = 0;
std::size_t lastVectorIndex = 0;
ElementMatrix cachedElementMatrix;
ElementVector cachedElementVector;
};
template <class GlobalBasis>
class TreeOperators
{
protected:
using GridView = typename GlobalBasis::GridView;
using Element = GridView::template Codim<0>::Entity;
using ElementOperator = Operator<GridView, Element>;
using IntersectionOperator = Operator<GridView, typename GridView::Intersection>;
using Tree = typename Basis::LocalView::Tree;
template <class OperatorType>
struct Scaled
{
std::shared_ptr<OperatorType> op;
double* factor = nullptr;
double* estFactor = nullptr;
BoundaryType b = {0};
};
template <class Node>
struct NodeData
{
std::list<Scaled<ElementOperator>> element;
std::list<Scaled<IntersectionOperator>> boundary;
std::list<Scaled<IntersectionOperator>> intersection;
bool assembled = false; // if false, do reassemble
bool changing = false; // if true, or assembled false, do reassemble
template <class.. Bases>
void init(Bases&&... bases)
{
for (auto scaled : element)
scaled.op->init(std::forward<Bases>(bases)...);
for (auto scaled : boundary)
scaled.op->init(std::forward<Bases>(bases)...);
for (auto scaled : intersection)
scaled.op->init(std::forward<Bases>(bases)...);
}
bool empty() const
{
return element.empty() && boundary.empty() && intersection.empty();
}
bool assemble(bool flag) const
{
return flag && (!assembled || changing);
}
};
};
template <class GlobalBasis>
class MatrixOperators
: public TreeOperators<GlobalBasis>
{
using Tree = typename TreeOperators<GlobalBasis>::Tree;
using NodeData = typename TreeOperators<GlobalBasis>::NodeData;
template <class Node>
using RowNodeData = Dune::Functions::TreeData<Tree, NodeData, false>;
using Data = Dune::Functions::TreeData<Tree, RowNodeData, false>;
public:
MatrixOperators(GlobalBasis const& globalBasis)
{
auto localView = globalBasis.localView();
data_.init(localView.tree());
forEachNode(localView.tree(), [&,this](auto const& node, auto const treePath)
{
data_[node].init(localView.tree());
});
}
template <class Node>
auto& operator[](Node const& node)
{
return data_[node];
}
template <class Node>
auto const& operator[](Node const& node) const
{
return data_[node];
}
template <class RowNode, class ColNode>
auto& operator()(RowNode const& rowNode, ColNode const& colNode)
{
return data_[rowNode][colNode];
}
template <class RowNode, class ColNode>
auto const& operator()(RowNode const& rowNode, ColNode const& colNode) const
{
return data_[rowNode][colNode];
}
private:
Data data_;
};
template <class GlobalBasis>
class VectorOperators
: public TreeOperators<GlobalBasis>
{
using Tree = typename TreeOperators<GlobalBasis>::Tree;
using NodeData = typename TreeOperators<GlobalBasis>::NodeData;
using Data = Dune::Functions::TreeData<Tree, NodeData, false>;
public:
VectorOperators(GlobalBasis const& globalBasis)
{
auto localView = globalBasis.localView();
data_.init(localView.tree());
}
template <class Node>
auto& operator[](Node const& node)
{
return data_[node];
}
template <class Node>
auto const& operator[](Node const& node) const
{
return data_[node];
}
private:
Data data_;
};
} // end namespace AMDiS
#include "Operator.inc.hpp"
#pragma once
namespace AMDiS
namespace AMDiS {
template <class GridView, class Element>
template <class RowBasis, class ColBasis>
void Operator<GridView, Element>::
init(RowBasis const& rowBasis, ColBasis const& colBasis)
{
template <class MeshView, class Element>
template <class RowFeSpace, class ColFeSpace>
void Operator<MeshView, Element>::
init(RowFeSpace const& rowFeSpace, ColFeSpace const& colFeSpace)
{
using IdType = typename Operator<MeshView, Element>::IdType;
lastMatrixId = std::numeric_limits<IdType>::max();
lastVectorId = std::numeric_limits<IdType>::max();
lastMatrixIndex = std::numeric_limits<std::size_t>::max();
lastVectorIndex = std::numeric_limits<std::size_t>::max();
// auto const& rowFE = rowView.tree().finiteElement();
// auto const& colFE = colView.tree().finiteElement();
......@@ -17,30 +16,28 @@ namespace AMDiS
// psiDegree = rowFE.localBasis().order();
// phiDegree = colFE.localBasis().order();
psiDegree = getPolynomialDegree<RowFeSpace>;
phiDegree = getPolynomialDegree<ColFeSpace>;
psiDegree = getPolynomialDegree<RowBasis>;
phiDegree = getPolynomialDegree<ColBasis>;
// TODO: calc quadrature degree here.
}
}
template <class MeshView, class Element>
template <class RowFeSpace>
void Operator<MeshView, Element>::
init(RowFeSpace const& rowFeSpace)
{
using IdType = typename Operator<MeshView, Element>::IdType;
lastVectorId = std::numeric_limits<IdType>::max();
psiDegree = getPolynomialDegree<RowFeSpace>;
}
template <class GridView, class Element>
template <class RowBasis>
void Operator<GridView, Element>::
init(RowBasis const& rowBasis)
{
lastVectorIndex = std::numeric_limits<std::size_t>::max();
psiDegree = getPolynomialDegree<RowBasis>;
}
template <class MeshView, class Element>
template <class GridView, class Element>
template <class Geometry>
int Operator<MeshView, Element>::
getQuadratureDegree(Dune::GeometryType t, Geometry const& geometry, int order, FirstOrderType type)
{
int Operator<GridView, Element>::
getQuadratureDegree(Dune::GeometryType t, Geometry const& geometry, int order, FirstOrderType type)
{
std::list<OperatorTermType*>* terms = NULL;
switch(order)
......@@ -71,41 +68,29 @@ namespace AMDiS
degree += 1; // oder += (order+1)
return degree;
}
}
template <class MeshView, class Element>
template <class LocalView>
typename Operator<MeshView, Element>::IdType
Operator<MeshView, Element>::getElementId(LocalView const& localView)
{
auto const& element = localView.element();
auto const& grid = localView.globalBasis().gridView().grid();
auto const& idSet = grid.localIdSet();
return idSet.id(element);
}
template <class MeshView, class Element>
template <class RowView, class ColView>
bool Operator<MeshView, Element>::
getElementMatrix(Element const& element,
template <class GridView, class Element>