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 ...@@ -7,6 +7,8 @@ if(NOT (dune-common_DIR OR dune-common_ROOT OR
${PROJECT_BINARY_DIR}) ${PROJECT_BINARY_DIR})
endif() endif()
set(CXX_MAX_STANDARD 14)
#find dune-common and set the module path #find dune-common and set the module path
find_package(dune-common REQUIRED) find_package(dune-common REQUIRED)
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/modules" list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/modules"
......
...@@ -6,139 +6,89 @@ ...@@ -6,139 +6,89 @@
#include <dune/common/fmatrix.hh> #include <dune/common/fmatrix.hh>
#include <dune/common/fvector.hh> #include <dune/common/fvector.hh>
#include <dune/amdis/FiniteElementSpaces.hpp>
#include <dune/amdis/LinearAlgebra.hpp> #include <dune/amdis/LinearAlgebra.hpp>
#include <dune/amdis/common/Mpl.hpp> #include <dune/amdis/common/Mpl.hpp>
#include <dune/amdis/common/TypeDefs.hpp> #include <dune/amdis/common/TypeDefs.hpp>
namespace AMDiS namespace AMDiS
{ {
template <class FeSpaces> template <class GlobalBasis>
class Assembler 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 /// The grid view the global FE basis lives on
using GridView = typename FeSpace<0>::GridView; using GridView = typename GlobalBasis::GridView;
using SystemMatrixType = SystemMatrix<FeSpaces>;
using SystemVectorType = SystemVector<FeSpaces>;
template <class T>
using MatrixEntries = Dune::FieldMatrix<T, nComponents, nComponents>;
template <class T> using SystemMatrixType = SystemMatrix<GlobalBasis>;
using VectorEntries = Dune::FieldVector<T, nComponents>; using SystemVectorType = SystemVector<GlobalBasis>;
using ElementVector = Impl::ElementVector; using TypeTree = typename GlobalBasis::LocalView::Tree;
using ElementMatrix = Impl::ElementMatrix; using
public: public:
/// Constructor, stores a shared-pointer to the feSpaces /// Constructor, stores a shared-pointer to the feSpaces
Assembler(std::shared_ptr<FeSpaces> const& feSpaces, bool asmMatrix, bool asmVector) Assembler(std::shared_ptr<GlobalBasis> const& globalBasis, bool asmMatrix, bool asmVector)
: globalBases_(feSpaces) : globalBasis_(globalBasis)
, asmMatrix_(asmMatrix) , asmMatrix_(asmMatrix)
, asmVector_(asmVector) , asmVector_(asmVector)
{} {}
/// Assemble the linear system /// Assemble the linear system
template <class Operators> template <class MatrixOperators, class VectorOperators>
void assemble( void assemble(
GridView const& gv, GridView const& gv,
SystemMatrixType& matrix, SystemMatrixType& matrix,
SystemVectorType& solution, SystemVectorType& solution,
SystemVectorType& rhs, SystemVectorType& rhs,
MatrixEntries<Operators>& matrix_operators, MatrixOperators& matrixOperators,
VectorEntries<Operators>& rhs_operators); VectorOperators& rhsOperators);
private: private:
/// Sets the system to zero and initializes all operators and boundary conditions /// Sets the system to zero and initializes all operators and boundary conditions
template <class Operators> template <class MatrixOperators, class VectorOperators>
void initMatrixVector( void initMatrixVector(
SystemMatrixType& matrix, SystemMatrixType& matrix,
SystemVectorType& solution, SystemVectorType& solution,
SystemVectorType& rhs, SystemVectorType& rhs,
MatrixEntries<Operators>& matrix_operators, MatrixOperators& matrixOperators,
VectorEntries<Operators>& rhs_operators) const; VectorOperators& rhsOperators) const;
/// Assemble a block-matrix of element-matrices and return a matrix of flags, whether template <class MatrixOperators, class VectorOperators>
/// a given block has received some entries. void assembleElement(
template <class Operators> SystemMatrixType& matrix,
MatrixEntries<bool> assembleElementMatrices( SystemVectorType& rhs,
MatrixEntries<Operators>& operators, MatrixOperators& matrixOperators,
MatrixEntries<ElementMatrix>& elementMatrix) const; VectorOperators& rhsOperators) 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;
/// Assemble one block of the block-element-matrix template <class ElementContainer, class Container, class Operators, class... Bases>
// The MatrixData argument stores all matrix-operators void assembleElementOperators(
template <class Operators, class RowView, class ColView> ElementContainer& elementContainer,
bool assembleElementMatrix( Container& container,
Operators& operators, Operators& operators,
ElementMatrix& elementMatrix, Bases const&... subBases) const;
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;
/// 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 /// Finish insertion into the matrix and assembles boundary conditions
/// Return the number of nonzeros assembled into the matrix /// Return the number of nonzeros assembled into the matrix
template <class Operators> template <class MatrixOperators, class VectorOperators>
std::size_t finishMatrixVector( std::size_t finishMatrixVector(
SystemMatrixType& matrix, SystemMatrixType& matrix,
SystemVectorType& solution, SystemVectorType& solution,
SystemVectorType& rhs, SystemVectorType& rhs,
MatrixEntries<Operators>& matrix_operators, MatrixOperators& matrixOperators,
VectorEntries<Operators>& rhs_operators) const; VectorOperators& rhsOperators) const;
/// Return whether the matrix-block needs to be assembled /// Return whether the matrix-block needs to be assembled
template <std::size_t R, std::size_t C, class Operators> template <class Basis0, class... Bases>
bool assembleMatrix(const index_t<R>, const index_t<C>, auto getElement(Basis0 const& basis0, Bases const&... bases) const
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
{ {
return asmVector_ && (!rhs_operators[R].assembled || rhs_operators[R].changing); return basis0.localView().element();
} }
private: private:
FiniteElementSpaces<FeSpaces> globalBases_; std::shared_ptr<GlobalBasis> globalBasis_;
bool asmMatrix_; bool asmMatrix_;
bool asmVector_; bool asmVector_;
}; };
......
This diff is collapsed.
...@@ -19,7 +19,7 @@ dune_add_library("duneamdis" NO_EXPORT ...@@ -19,7 +19,7 @@ dune_add_library("duneamdis" NO_EXPORT
) )
add_dune_alberta_flags("duneamdis" OBJECT USE_GENERIC) add_dune_alberta_flags("duneamdis" OBJECT USE_GENERIC)
target_compile_definitions("duneamdis" PUBLIC AMDIS_BACKEND_MTL=1) 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 find_package(MTL REQUIRED
PATHS /usr/local/lib/mtl4) PATHS /usr/local/lib/mtl4)
......
...@@ -12,7 +12,7 @@ namespace AMDiS ...@@ -12,7 +12,7 @@ namespace AMDiS
// All classes that need creators must specialize this class and implement // All classes that need creators must specialize this class and implement
// a static void init() method. // a static void init() method.
template <class BaseClass> template <class BaseClass>
struct DefaultCreators; class DefaultCreators;
/** \ingroup Common /** \ingroup Common
......
...@@ -28,7 +28,7 @@ namespace AMDiS ...@@ -28,7 +28,7 @@ namespace AMDiS
static constexpr int dim = Traits::dim; static constexpr int dim = Traits::dim;
/// Dimension of the world /// Dimension of the world
static constexpr int dow = Traits::dimworld; static constexpr int dow = Traits::dow;
/// Number of problem components /// Number of problem components
static constexpr int nComponents = Traits::nComponents; static constexpr int nComponents = Traits::nComponents;
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#include <dune/amdis/common/TupleUtility.hpp> #include <dune/amdis/common/TupleUtility.hpp>
#include <dune/amdis/common/IndexSeq.hpp> #include <dune/amdis/common/IndexSeq.hpp>
#include <dune/amdis/common/Loops.hpp>
namespace AMDiS namespace AMDiS
{ {
...@@ -61,10 +62,15 @@ namespace AMDiS ...@@ -61,10 +62,15 @@ namespace AMDiS
forEach(range_<0, nComponents>, [&,this](auto const _i) forEach(range_<0, nComponents>, [&,this](auto const _i)
{ {
static const int I = decltype(_i)::value; 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 // NOTE: maybe create element-geometry here
bound_ = true;
} }
/// Unbind from the current element /// Unbind from the current element
...@@ -76,10 +82,11 @@ namespace AMDiS ...@@ -76,10 +82,11 @@ namespace AMDiS
std::get<I>(localIndexSets_).unbind(); std::get<I>(localIndexSets_).unbind();
std::get<I>(localViews_).unbind(); std::get<I>(localViews_).unbind();
}); });
bound_ = false;
} }
template <std::size_t I> 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_); return std::get<I>(*feSpaces_);
} }
...@@ -87,28 +94,40 @@ namespace AMDiS ...@@ -87,28 +94,40 @@ namespace AMDiS
template <std::size_t I> template <std::size_t I>
auto const& localView(const index_t<I> _i = {}) const auto const& localView(const index_t<I> _i = {}) const
{ {
assert( bound_ && "localViews must be bound to an element." );
return std::get<I>(localViews_); return std::get<I>(localViews_);
} }
template <std::size_t I> template <std::size_t I>
auto const& localIndexSet(const index_t<I> _i = {}) const auto const& localIndexSet(const index_t<I> _i = {}) const
{ {
assert( bound_ && "localIndexSets must be bound to a localView." );
return std::get<I>(localIndexSets_); 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 auto const& gridView() const
{ {
return std::get<0>(*feSpaces_).gridView(); return std::get<0>(*feSpaces_).gridView();
} }
private: private:
/// Tuple of global functionspace bases
std::shared_ptr<FeSpaces> feSpaces_; 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_; 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_; LocalIndexSets localIndexSets_;
/// True, if localViews and localIndexSets are bound to an element
bool bound_ = false;
}; };
} // end namespace AMDiS } // end namespace AMDiS
...@@ -70,8 +70,6 @@ namespace AMDiS ...@@ -70,8 +70,6 @@ namespace AMDiS
/// geometry() for entities or geometryInInside() for intersections /// geometry() for entities or geometryInInside() for intersections
Geometry geometry; Geometry geometry;
// TODO: create geometry just once for each element, e.g. in ProblemStat when traversing the grid
}; };
} // end namespace AMDiS } // end namespace AMDiS
...@@ -18,20 +18,15 @@ namespace AMDiS ...@@ -18,20 +18,15 @@ namespace AMDiS
{ {
// the LocalContext is either an Codim=0-EntityType or an IntersectionType // the LocalContext is either an Codim=0-EntityType or an IntersectionType
template <class MeshView, class LocalContext> template <class GridView, class LocalContext>
class Operator class Operator
{ {
using Self = Operator; using Self = Operator;
using OperatorTermType = OperatorTerm<LocalContext>; using OperatorTermType = OperatorTerm<LocalContext>;
using ElementVector = Impl::ElementVector; template <class, class> friend class ZeroOrderAssembler;
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, FirstOrderType> friend class FirstOrderAssembler;
template <class, class> friend class SecondOrderAssembler; template <class, class> friend class SecondOrderAssembler;
public: public:
/// \brief Add coefficients for zero-order operator < C(phi), psi >. /// \brief Add coefficients for zero-order operator < C(phi), psi >.
...@@ -114,13 +109,13 @@ namespace AMDiS ...@@ -114,13 +109,13 @@ namespace AMDiS
public: // initialize and assemble operator on element public: // initialize and assemble operator on element
/// Extract the polynomial degree from \p rowFeSpace and \p colFeSpace. /// Extract the polynomial degree from \p rowBasis and \p colBasis.
template <class RowFeSpace, class ColFeSpace> template <class RowBasis, class ColBasis>
void init(RowFeSpace const& rowFeSpace, void init(RowBasis const& rowBasis,
ColFeSpace const& colFeSpace); ColBasis const& colBasis);
template <class RowFeSpace> template <class RowBasis>
void init(RowFeSpace const& rowFeSpace); void init(RowBasis const& rowBasis);
/// Calculates the needed quadrature degree for the given term-order \p order. /// Calculates the needed quadrature degree for the given term-order \p order.
...@@ -131,18 +126,24 @@ namespace AMDiS ...@@ -131,18 +126,24 @@ namespace AMDiS
FirstOrderType firstOrderType = GRD_PHI); FirstOrderType firstOrderType = GRD_PHI);
template <class RowView, class ColView> // assemble matrix operator
bool getElementMatrix(LocalContext const& element, template <class RowView, class ColView, class ElementMatrix>
RowView const& rowView, bool assemble(
ColView const& colView, GridView const& gv,
ElementMatrix& elementMatrix, LocalContext const& element,
double* factor = NULL); RowView const& rowView,
ColView const& colView,
ElementMatrix& elementMatrix,
double* factor = NULL);
template <class RowView> // assemble vector operator
bool getElementVector(LocalContext const& element, template <class LocalView, class ElementVector>
RowView const& rowView, bool assemble(
ElementVector& elementVector, GridView const& gv,
double* factor = NULL); LocalContext const& element,
LocalView const& localView,
ElementVector& elementVector,
double* factor = NULL);
private: // implementation details private: // implementation details
...@@ -228,7 +229,10 @@ namespace AMDiS ...@@ -228,7 +229,10 @@ namespace AMDiS
private: private:
template <class LocalView> 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: private:
...@@ -248,13 +252,154 @@ namespace AMDiS ...@@ -248,13 +252,154 @@ namespace AMDiS
int psiDegree = 1; int psiDegree = 1;
int phiDegree = 1; int phiDegree = 1;
IdType lastMatrixId = 0; std::size_t lastMatrixIndex = 0;
IdType lastVectorId = 0; std::size_t lastVectorIndex = 0;
ElementMatrix cachedElementMatrix; ElementMatrix cachedElementMatrix;
ElementVector cachedElementVector; 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];
}