Commit 5de54da3 authored by Praetorius, Simon's avatar Praetorius, Simon

Assembler and LocalFiniteElement added, to separate assembling from problemStat

parent 36eb33e4
#pragma once
// std c++ headers
#include <memory>
#include <tuple>
// AMDiS includes
#include <dune/amdis/QuadratureRules.hpp>
#include <dune/amdis/common/TypeDefs.hpp>
#include <dune/common/fmatrix.hh>
#include <dune/common/fvector.hh>
#include <dune/amdis/LinearAlgebra.hpp>
#include <dune/amdis/LocalFiniteElemenet.hpp>
#include <dune/amdis/common/Mpl.hpp>
namespace AMDiS
{
// the LocalContext is either an Codim=0-EntityType or an IntersectionType
template <class GridView, class LocalContext>
template <class FeSpaces>
class Assembler
{
static constexpr int dim = GridView::dimension;
using ctype = typename GridView::ctype;
/// Number of problem components
static constexpr int nComponents = std::tuple_size<FeSpaces>::value;
using SystemMatrixType = SystemMatrix<FeSpaces>;
using SystemVectorType = SystemVector<FeSpaces>;
template <class T>
using MatrixEntries = Dune::FieldMatrix<T, nComponents, nComponents>;
using LocalQuadratureRules = Dune::QuadratureRules<ctype, LocalContext::mydimension>;
using QuadratureRule = QuadratureRuleFactory_t<LocalContext, ctype, dim>;
using Geometry = typename Impl::Get<LocalContext>::Geometry;
template <class T>
using VectorEntries = Dune::FieldVector<T, nComponents>;
public:
/// Constructor, initializes the geometry of the element and a
/// quadrature-rule wrapper
template <class Operator>
Assembler(Operator& op, LocalContext const& element, int degree, FirstOrderType type = GRD_PHI)
: geometry(get_geometry(element))
/// Constructor, stores a shared-pointer to the feSpaces
Assembler(std::shared_ptr<FeSpaces> const& feSpaces_)
: feSpaces(feSpaces_)
{
int order = op.getQuadratureDegree(geometry.type(), geometry, degree, type);
auto const& quad = LocalQuadratureRules::rule(geometry.type(), order);
auto gridView = std::get<0>(*feSpaces).gridView();
quadrature.reset(new QuadratureRule(element, quad));
forEach(range_<0, nComponents>, [&,this](auto const _r) {
static const std::size_t R = decltype(_r)::value;
std::get<R>(*feSpaces).update(gridView);
});
}
/// \brief Returns reference to the transformed quadrature rule
/**
* For intersections this corresponds to the points in the intersection
* geometry, but coordinates extended to the whole inside-entity. For
* elements this is a wrapper around the classical element quadrature rule.
* Access the underlying dune-quadrature rule, with `quadrature->getRule()`.
**/
QuadratureRule const& getQuadrature() const
/// Assemble the linear system
template <class Operators>
void assemble(SystemMatrixType& matrix,
SystemVectorType& solution,
SystemVectorType& rhs,
MatrixEntries<Operators>& matrix_operators,
VectorEntries<Operators>& rhs_operators,
bool asmMatrix_, bool asmVector_);
private:
// Return whether the matrix-block needs to be assembled
template <int R, int C, class Operators>
bool assembleMatrix(const index_t<R>, const index_t<C>,
MatrixEntries<Operators> const& matrix_operators, bool asmMatrix_) const
{
return *quadrature;
return asmMatrix_ && (!matrix_operators[R][C].assembled || matrix_operators[R][C].changing);
}
/// Return the geometry of the Object
/**
* The geometry is either the element geometry, or the geometry of the
* inside-element for intersections.
**/
Geometry const& getGeometry() const
// Return whether the vector-block needs to be assembled
template <int R, class Operators>
bool assembleVector(const index_t<R>, VectorEntries<Operators> const& rhs_operators, bool asmVector_) const
{
return geometry;
return asmVector_ && (!rhs_operators[R].assembled || rhs_operators[R].changing);
}
protected:
// Sets the system to zero and initializes all operators and boundary conditions
template <class Operators>
void initMatrixVector(SystemMatrixType& matrix,
SystemVectorType& solution,
SystemVectorType& rhs,
MatrixEntries<Operators>& matrix_operators,
VectorEntries<Operators>& rhs_operators,
bool asmMatrix_, bool asmVector_);
// transform coords from intersection coords to element coords
template <class Coordinate>
decltype(auto) map(Coordinate const& p) const
{
return get_position<LocalContext>(geometry, p);
}
private:
/// transformed quadrature rule
std::shared_ptr<QuadratureRule const> quadrature;
/// 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,
LocalFiniteElement<FeSpaces> const& localFiniteElem,
bool asmMatrix_);
/// 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,
LocalFiniteElement<FeSpaces> const& localFiniteElem,
bool asmVector_);
/// 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
/// Assemble one block of the block-element-matrix
// The MatrixData argument stores all matrix-operators
template <class Operators, class RowView, class ColView>
bool assembleElementMatrix(Operators& operators,
ElementMatrix& elementMatrix,
RowView const& rowLocalView, ColView const& colLocalView);
/// 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);
/// Add the block-element-matrix to the system-matrix
void addElementMatrices(SystemMatrixType& dofmatrix,
LocalFiniteElement<FeSpaces> const& localFiniteElem,
MatrixEntries<bool> const& addMat,
MatrixEntries<ElementMatrix> const& elementMatrix);
/// Add the block-element-vector to the system-vector
void addElementVectors(SystemVectorType& dofvector,
LocalFiniteElement<FeSpaces> const& localFiniteElem,
VectorEntries<bool> const& addVec,
VectorEntries<ElementVector> const& elementVector);
/// Finish insertion into the matrix and assembles boundary conditions
/// Return the number of nonzeros assembled into the matrix
template <class Operators>
std::size_t finishMatrixVector(SystemMatrixType& matrix,
SystemVectorType& solution,
SystemVectorType& rhs,
MatrixEntries<Operators>& matrix_operators,
VectorEntries<Operators>& rhs_operators,
bool asmMatrix_, bool asmVector_);
private:
std::shared_ptr<FeSpaces> feSpaces;
};
} // end namespace AMDiS
#include "Assembler.inc.hpp"
This diff is collapsed.
......@@ -2,7 +2,7 @@
#include <vector>
#include <dune/amdis/Assembler.hpp>
#include <dune/amdis/LocalAssembler.hpp>
#include <dune/amdis/common/Mpl.hpp>
#include <dune/amdis/common/TypeDefs.hpp>
#include <dune/amdis/utility/GetEntity.hpp>
......@@ -11,9 +11,9 @@ namespace AMDiS
{
template <class GridView, class LocalContext, FirstOrderType type>
class FirstOrderAssembler
: public Assembler<GridView, LocalContext>
: public LocalAssembler<GridView, LocalContext>
{
using Super = Assembler<GridView, LocalContext>;
using Super = LocalAssembler<GridView, LocalContext>;
static constexpr int dim = GridView::dimension;
static constexpr int dow = GridView::dimensionworld;
......
#pragma once
// std c++ headers
#include <memory>
// AMDiS includes
#include <dune/amdis/QuadratureRules.hpp>
#include <dune/amdis/common/TypeDefs.hpp>
namespace AMDiS
{
// the LocalContext is either an Codim=0-EntityType or an IntersectionType
template <class GridView, class LocalContext>
class LocalAssembler
{
static constexpr int dim = GridView::dimension;
using ctype = typename GridView::ctype;
using LocalQuadratureRules = Dune::QuadratureRules<ctype, LocalContext::mydimension>;
using QuadratureRule = QuadratureRuleFactory_t<LocalContext, ctype, dim>;
using Geometry = typename Impl::Get<LocalContext>::Geometry;
public:
/// Constructor, initializes the geometry of the element and a
/// quadrature-rule wrapper
template <class Operator>
LocalAssembler(Operator& op, LocalContext const& element, int degree, FirstOrderType type = GRD_PHI)
: geometry(get_geometry(element))
{
int order = op.getQuadratureDegree(geometry.type(), geometry, degree, type);
auto const& quad = LocalQuadratureRules::rule(geometry.type(), order);
quadrature.reset(new QuadratureRule(element, quad));
}
/// \brief Returns reference to the transformed quadrature rule
/**
* For intersections this corresponds to the points in the intersection
* geometry, but coordinates extended to the whole inside-entity. For
* elements this is a wrapper around the classical element quadrature rule.
* Access the underlying dune-quadrature rule, with `quadrature->getRule()`.
**/
QuadratureRule const& getQuadrature() const
{
return *quadrature;
}
/// Return the geometry of the Object
/**
* The geometry is either the element geometry, or the geometry of the
* inside-element for intersections.
**/
Geometry const& getGeometry() const
{
return geometry;
}
protected:
// transform coords from intersection coords to element coords
template <class Coordinate>
decltype(auto) map(Coordinate const& p) const
{
return get_position<LocalContext>(geometry, p);
}
private:
/// transformed quadrature rule
std::shared_ptr<QuadratureRule const> quadrature;
/// 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
#pragma once
#include <tuple>
#include <dune/amdis/common/IndexSeq.hpp>
namespace AMDiS
{
namespace Impl
{
template <template<class> class Base, class Tuple, class Indices> struct MakeTupleType;
template <template<class> class Base, class Tuple, std::size_t... I>
struct MakeTupleType<Base, Tuple, Indices<I...>>
{
using type = std::tuple<typename Base<std::tuple_element_t<I, Tuple>>::type...>;
};
/// Constructs tuple type, by wrapping Base around the tuple elements.
/// Returns tuple type tuple<Base<tuple_element_t<0>>::type, Base<tuple_element_t<1>>::type, ...>
template <template<class> class Base, class Tuple>
using MakeTupleType_t =
typename MakeTupleType<Base, Tuple, MakeSeq_t<std::tuple_size<Tuple>::value>>::type;
template <class Functor, class Tuple, std::size_t... I>
auto makeTupleType(Functor f, Tuple&& tuple, Indices<I...>)
{
return std::make_tuple(f(std::get<I>(std::forward<Tuple>(tuple>)))...);
}
// construction method to construct a tuple of DOFVectors
template <class Functor, class Tuple>
auto makeTupleType(Functor f, Tuple&& tuple)
{
return makeTupleType(f, std::forward<Tuple>(tuple), MakeSeq_t<std::tuple_size<Tuple>::value>{});
}
} // end namespace Impl
template <class FeSpace>
struct LocalView
{
using type = typename FeSpace::LocalView;
};
template <class FeSpace>
struct LocalIndexSet
{
using type = typename FeSpace::LocalIndexSet;
};
template <class FeSpaces>
class LocalFiniteElement
{
template <std::size_t I>
using FeSpace = std::tuple_element_t<I, FeSpaces>;
static constexpr int nComponents = std::tuple_size<FeSpaces>::value;
using LocalViews = Impl::MakeTupleType_t<LocalView, FeSpaces>;
using LocalIndexSets = Impl::MakeTupleType_t<LocalIndexSet, FeSpaces>;
/// The grid view the global FE basis lives on
using GridView = typename FeSpace<0>::GridView;
/// Type of the grid element we are bound to
using Element = typename GridView::template Codim<0>::Entity;
public:
LocalFiniteElement(FeSpaces const& feSpaces)
: localViews(Impl::makeTupleType([](auto const& basis) { return basis.localView(); }, feSpaces))
, localIndexSets(Impl::makeTupleType([](auto const& basis) { return basis.localIndexSet(); }, feSpaces))
{}
/// Bind the \ref localViews and \ref localIndexSets to a grid element
void bind(Element const& element)
{
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(localView);
});
// NOTE: maybe create element-geometry here
}
/// Unbind from the current element
void unbind()
{
forEach(range_<0, nComponents>, [&,this](auto const _i)
{
static const int I = decltype(_i)::value;
std::get<I>(localIndexSets).unbind();
std::get<I>(localViews).unbind();
});
}
template <std::size_t I>
auto const& localView(const index_t<I> _i = {}) const
{
return std::get<I>(localViews);
}
template <std::size_t I>
auto const& localIndexSet(const index_t<I> _i = {}) const
{
return std::get<I>(localIndexSets);
}
private:
/// tuple of localView objects, obtained from the tuple of global bases
LocalViews localViews;
// tuple of localIndexSet objects, obtained from the tuple of global bases
LocalIndexSets localIndexSets;
};
} // end namespace AMDiS
......@@ -442,52 +442,33 @@ namespace AMDiS
template <class T>
using VectorEntries = Dune::FieldVector<T, nComponents>;
using BoundaryCondition = std::list<std::shared_ptr<DirichletBC<WorldVector>>>;
// A map (i,j) -> list<DirichleBC> string a boundary conditions for
// each matrix block
MatrixEntries<BoundaryCondition> dirichletBc;
// A map (i,j) -> list<ElementOperator> string the differential operators for
// each matrix block
MatrixEntries<std::list<Scaled<ElementOperator>>> matrixOperators;
MatrixEntries<std::list<Scaled<IntersectionOperator>>> matrixBoundaryOperators;
MatrixEntries<std::list<Scaled<IntersectionOperator>>> matrixIntersectionOperators;
MatrixEntries<bool> matrixAssembled; // if false, do reassemble
MatrixEntries<bool> matrixChanging; // if true, or vectorAssembled false, do reassemble
// A map (i) -> list<ElementOperator> string the differential operators for
// each rhs block
VectorEntries<std::list<Scaled<ElementOperator>>> vectorOperators;
VectorEntries<std::list<Scaled<IntersectionOperator>>> vectorBoundaryOperators;
VectorEntries<std::list<Scaled<IntersectionOperator>>> vectorIntersectionOperators;
VectorEntries<bool> vectorAssembled; // if false, do reassemble
VectorEntries<bool> vectorChanging; // if true, or vectorAssembled false, do reassemble
template <int R, int C>
struct MatrixData
/// Helper class to store an operator with optionally factors and
/// a boundary indicator
template <class OperatorType>
struct Scaled
{
using DOFMatrixType =
std::tuple_element_t<C, std::tuple_element_t<R, typename SystemMatrixType::DOFMatrices>>;
DOFMatrixType& matrix;
std::list<Scaled<ElementOperator>>& operators;
std::list<Scaled<IntersectionOperator>>& boundary_operators;
std::list<Scaled<IntersectionOperator>>& intersection_operators;
bool assemble = true;
std::shared_ptr<OperatorType> op;
double* factor = nullptr;
double* estFactor = nullptr;
BoundaryType b = {0};
};
template <int I>
struct VectorData
// lists of operators on elements, boundary and intersection
struct Operators
{
using DOFVectorType = std::tuple_element_t<I, typename SystemVectorType::DOFVectors>;
std::list<Scaled<ElementOperator>> element;
std::list<Scaled<IntersectionOperator>> boundary;
std::list<Scaled<IntersectionOperator>> intersection;
DOFVectorType& vector;
std::list<Scaled<ElementOperator>>& operators;
std::list<Scaled<IntersectionOperator>>& boundary_operators;
std::list<Scaled<IntersectionOperator>>& intersection_operators;
bool assemble = true;
std::list<std::shared_ptr<DirichletBC<WorldVector>>> dirichlet; // boundary conditions
bool assembled = false; // if false, do reassemble
bool changing = false; // if true, or vectorAssembled false, do reassemble
};
MatrixEntries<Operators> matrixOperators;
VectorEntries<Operators> rhsOperators;
};
......
This diff is collapsed.
......@@ -2,7 +2,7 @@
#include <vector>
#include <dune/amdis/Assembler.hpp>
#include <dune/amdis/LocalAssembler.hpp>
#include <dune/amdis/common/Mpl.hpp>
#include <dune/amdis/common/TypeDefs.hpp>
#include <dune/amdis/utility/GetEntity.hpp>
......@@ -11,9 +11,9 @@ namespace AMDiS
{
template <class GridView, class LocalContext>
class SecondOrderAssembler
: public Assembler<GridView, LocalContext>
: public LocalAssembler<GridView, LocalContext>
{
using Super = Assembler<GridView, LocalContext>;
using Super = LocalAssembler<GridView, LocalContext>;
static constexpr int dim = GridView::dimension;
static constexpr int dow = GridView::dimensionworld;
......
......@@ -2,7 +2,7 @@
#include <vector>
#include <dune/amdis/Assembler.hpp>
#include <dune/amdis/LocalAssembler.hpp>
#include <dune/amdis/common/Mpl.hpp>
#include <dune/amdis/common/TypeDefs.hpp>
#include <dune/amdis/utility/GetEntity.hpp>
......@@ -12,9 +12,9 @@ namespace AMDiS
/// Assembler for zero-order operators
template <class GridView, class LocalContext>
class ZeroOrderAssembler
: public Assembler<GridView, LocalContext>
: public LocalAssembler<GridView, LocalContext>
{
using Super = Assembler<GridView, LocalContext>;
using Super = LocalAssembler<GridView, LocalContext>;
static constexpr int dim = GridView::dimension;
......
Markdown is supported
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