Commit ca27d54f authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

Merge branch 'issue/cleanup_matrix_vector_base_bi_linearform' into 'master'

Cleanup the constructors of MatrixBase, VectorBase, BiLinearForm, and LinearForm

See merge request !113
parents 3eb1830e 600cf9d3
......@@ -45,10 +45,12 @@ namespace AMDiS
using ElementMatrix = FlatMatrix<CoefficientType>;
public:
/// Constructor. Wraps the reference into a non-destroying shared_ptr or moves the basis into a new shared_ptr.
template <class RB_, class CB_, class Comm_>
BiLinearForm(RB_&& rowBasis, CB_&& colBasis, Comm_&& comm)
: Super(FWD(rowBasis), FWD(colBasis), FWD(comm))
/// Constructor. Wraps the reference into a non-destroying shared_ptr or moves
/// the basis into a new shared_ptr. The additional arguments can be the communication
/// object. If not provided, a new communication is created.
template <class RB_, class CB_, class... Args>
BiLinearForm(RB_&& rowBasis, CB_&& colBasis, Args&&... args)
: Super(FWD(rowBasis), FWD(colBasis), FWD(args)...)
{
operators_.init(*Super::rowBasis(), *Super::colBasis());
}
......@@ -63,7 +65,7 @@ namespace AMDiS
elementMatrix_.resize(rowSize, colSize);
}
/// \brief Associate a local operator with this DOFMatrix
/// \brief Associate a local operator with this BiLinearForm
/**
* Stores an operator in a list that gets assembled during a call to \ref assemble().
* The operator may be assigned to a specific context, i.e. either an element
......@@ -72,20 +74,36 @@ namespace AMDiS
* functions the operator is applied to.
*
* \tparam ContextTag One of \ref tag::element_operator, \ref tag::intersection_operator
* or \ref tag::boundary_operator indicating where to assemble this operator.
* or \ref tag::boundary_operator indicating where to assemble
* this operator.
* \tparam Expr An pre-operator that can be bound to a gridView, or a valid
* GridOperator.
* \tparam row A tree-path for the RowBasis
* \tparam col A tree-path for the ColBasis
* GridOperator.
* \tparam row A tree-path for the RowBasis
* \tparam col A tree-path for the ColBasis
*
* [[expects: row is valid tree-path in RowBasis]]
* [[expects: col is valid tree-path in ColBasis]]
* @{
**/
// TODO: add method without contextTag.
template <class ContextTag, class Expr,
class RowTreePath = RootTreePath, class ColTreePath = RootTreePath>
void addOperator(ContextTag contextTag, Expr const& expr,
RowTreePath row = {}, ColTreePath col = {});
template <class ContextTag, class Expr, class Row, class Col>
void addOperator(ContextTag contextTag, Expr const& expr, Row row, Col col);
// Add an operator to be assembled on the elements of the grid
template <class Expr, class Row = RootTreePath, class Col = RootTreePath>
void addOperator(Expr const& expr, Row row = {}, Col col = {})
{
using E = typename RowLocalView::Element;
addOperator(tag::element_operator<E>{}, expr, row, col);
}
// Add an operator to be assembled on the intersections of the grid
template <class Expr, class Row = RootTreePath, class Col = RootTreePath>
void addIntersectionOperator(Expr const& expr, Row row = {}, Col col = {})
{
using I = typename RowLocalView::GridView::Intersection;
addOperator(tag::intersection_operator<I>{}, expr, row, col);
}
/// @}
/// Assemble the matrix operators on the bound element.
void assemble(RowLocalView const& rowLocalView,
......@@ -103,6 +121,20 @@ namespace AMDiS
MatrixOperators<RowBasis,ColBasis,ElementMatrix> operators_;
};
#if DUNE_HAVE_CXX_CLASS_TEMPLATE_ARGUMENT_DEDUCTION
template <class RB, class CB, class... Args>
BiLinearForm(RB&&, CB&&, Args&&...)
-> BiLinearForm<Underlying_t<RB>, Underlying_t<CB>>;
#endif
template <class RB, class CB, class... Args>
auto makeBiLinearForm(RB&& rowBasis, CB&& colBasis, Args&&... args)
{
using BLF = BiLinearForm<Underlying_t<RB>, Underlying_t<CB>>;
return BLF{FWD(rowBasis), FWD(colBasis), FWD(args)...};
}
} // end namespace AMDiS
#include <amdis/BiLinearForm.inc.hpp>
......@@ -75,7 +75,7 @@ assemble(SymmetryStructure symmetry)
this->assemble(rowLocalView, colLocalView);
colLocalView.unbind();
}
rowLocalView.unbind(element);
rowLocalView.unbind();
}
this->finish();
}
......
......@@ -21,6 +21,7 @@ namespace AMDiS
: public VectorBase<GB, VectorBackend<BackendTraits<GB,T>>>
{
using Super = VectorBase<GB, VectorBackend<BackendTraits<GB,T>>>;
using Self = LinearForm;
public:
using Backend = VectorBackend<BackendTraits<GB,T>>;
......@@ -28,6 +29,7 @@ namespace AMDiS
/// The type of the functionspace basis associated to this linearform
using GlobalBasis = GB;
using LocalView = typename GlobalBasis::LocalView;
/// A traits class collecting several parameters of the linear algebra backend
using Traits = typename Backend::Traits;
......@@ -40,9 +42,12 @@ namespace AMDiS
public:
/// Constructor. Stores the shared_ptr of the basis and creates a new DataTransfer.
template <class GB_, class Comm_>
LinearForm(GB_&& basis, Comm_&& comm)
: Super(FWD(basis), FWD(comm))
/// The additional arguments can be the communication object. If not provided,
/// a new communication is created.
template <class GB_, class... Args,
Dune::disableCopyMove<Self, GB_, Args...> = 0>
explicit LinearForm(GB_&& basis, Args&&... args)
: Super(FWD(basis), FWD(args)...)
{
operators_.init(*Super::basis());
}
......@@ -57,12 +62,47 @@ namespace AMDiS
elementVector_.resize(localSize);
}
/// Associate a local operator with this LinearForm
template <class ContextTag, class Expr, class TreePath = RootTreePath>
void addOperator(ContextTag contextTag, Expr const& expr, TreePath path = {});
/// \brief Associate a local operator with this LinearForm
/**
* Stores an operator in a list that gets assembled during a call to \ref assemble().
* The operator may be assigned to a specific context, i.e. either an element
* operator, an intersection operator, or a boundary operator.
* The \p path tree paths specify the sub-basis for test functions the operator
* is applied to.
*
* \tparam ContextTag One of \ref tag::element_operator, \ref tag::intersection_operator
* or \ref tag::boundary_operator indicating where to assemble
* this operator.
* \tparam Expr An pre-operator that can be bound to a gridView, or a valid
* GridOperator.
* \tparam path A tree-path for the Basis
*
* [[expects: path is valid tree-path in Basis]]
* @{
**/
template <class ContextTag, class Expr, class TreePath>
void addOperator(ContextTag contextTag, Expr const& expr, TreePath path);
// Add an operator to be assembled on the elements of the grid
template <class Expr, class TreePath = RootTreePath>
void addOperator(Expr const& expr, TreePath path = {})
{
using E = typename LocalView::Element;
addOperator(tag::element_operator<E>{}, expr, path);
}
// Add an operator to be assembled on the intersections of the grid
template <class Expr, class TreePath = RootTreePath>
void addIntersectionOperator(Expr const& expr, TreePath path = {})
{
using I = typename LocalView::GridView::Intersection;
addOperator(tag::intersection_operator<I>{}, expr, path);
}
/// @}
/// Assemble the vector operators on the bound element.
void assemble(typename GB::LocalView const& localView);
void assemble(LocalView const& localView);
/// Assemble all vector operators added by \ref addOperator().
void assemble();
......@@ -75,12 +115,20 @@ namespace AMDiS
VectorOperators<GlobalBasis,ElementVector> operators_;
};
#if DUNE_HAVE_CXX_CLASS_TEMPLATE_ARGUMENT_DEDUCTION
template <class GB, class C>
LinearForm(GB&& basis, C const& comm)
-> LinearForm<Underlying_t<GB>, VectorBackend<BackendTraits<Underlying_t<GB>>> >;
template <class GB, class... Args>
LinearForm(GB&& basis, Args&&... args)
-> LinearForm<Underlying_t<GB>, double>;
#endif
template <class T = double, class GB, class... Args>
auto makeLinearForm(GB&& basis, Args&&... args)
{
using LF = LinearForm<Underlying_t<GB>, T>;
return LF{FWD(basis), FWD(args)...};
}
} // end namespace AMDiS
#include <amdis/LinearForm.inc.hpp>
......@@ -36,25 +36,41 @@ namespace AMDiS
using ColBasis = CB;
using ColLocalView = typename ColBasis::LocalView;
/// The Linear-Aglebra backend used to store the assembled coefficients
/// The Linear-Algebra backend used to store the assembled coefficients
using Backend = B;
private:
using Comm = typename B::Traits::Comm;
public:
/// Constructor. Stores the shared_ptr to the bases.
MatrixBase(std::shared_ptr<RowBasis> rowBasis, std::shared_ptr<ColBasis> colBasis, std::shared_ptr<Comm> comm)
/// (1) Constructor. Stores the shared_ptr to the bases and the communication object.
MatrixBase(std::shared_ptr<RB> rowBasis, std::shared_ptr<CB> colBasis,
std::shared_ptr<Comm> comm)
: rowBasis_(std::move(rowBasis))
, colBasis_(std::move(colBasis))
, backend_(std::move(comm))
{}
/// Constructor. Wraps the reference into a non-destroying shared_ptr or moves the basis into a new shared_ptr.
/// (2) Constructor. Forwards to (1) by wraping reference into non-destroying
/// shared_ptr, see \ref Dune::wrap_or_move.
template <class RB_, class CB_, class Comm_,
REQUIRES(Concepts::Similar<RB_,RB> && Concepts::Similar<CB_,CB> && Concepts::Similar<Comm_,Comm>)>
REQUIRES(Concepts::Similar<Types<RB_,CB_,Comm_>, Types<RB,CB,Comm>>)>
MatrixBase(RB_&& rowBasis, CB_&& colBasis, Comm_&& comm)
: MatrixBase(Dune::wrap_or_move(FWD(rowBasis)), Dune::wrap_or_move(FWD(colBasis)), Dune::wrap_or_move(FWD(comm)))
: MatrixBase(Dune::wrap_or_move(FWD(rowBasis)),
Dune::wrap_or_move(FWD(colBasis)),
Dune::wrap_or_move(FWD(comm)))
{}
/// (3) Constructor. Forwards to (1) by creating a new communicator
MatrixBase(std::shared_ptr<RB> const& rowBasis, std::shared_ptr<CB> const& colBasis)
: MatrixBase(rowBasis, colBasis,
std::shared_ptr<Comm>(CommunicationCreator<Comm>::create(*rowBasis)))
{}
/// (4) Constructor. Forwards to (3) by wrapping references into non-destroying
/// shared_ptr, see \ref Dune::wrap_or_move.
template <class RB_, class CB_,
REQUIRES(Concepts::Similar<Types<RB_,CB_>, Types<RB,CB>>)>
MatrixBase(RB_&& rowBasis, CB_&& colBasis)
: MatrixBase(Dune::wrap_or_move(FWD(rowBasis)), Dune::wrap_or_move(FWD(colBasis)))
{}
/// Return the row-basis \ref rowBasis of the matrix
......@@ -69,20 +85,15 @@ namespace AMDiS
return colBasis_;
}
Backend& backend()
{
return backend_;
}
Backend const& backend() const
{
return backend_;
}
/// Return the underlying linear algebra backend
Backend const& backend() const { return backend_; }
Backend& backend() { return backend_; }
/// \brief Initialize the matrix for insertion, i.e. allocate the non-zero pattern
/**
* With the optional parameter \p symmetry some additional information about the
* structure of the values or the sparsity pattern can be provided. See \ref SymmetryStructure.
* structure of the values or the sparsity pattern can be provided.
* See \ref SymmetryStructure.
**/
void init(SymmetryStructure symmetry = SymmetryStructure::unknown)
{
......@@ -111,7 +122,9 @@ namespace AMDiS
assert(r.size() == localMatrix.rows());
assert(c.size() == localMatrix.cols());
const bool optimized = std::is_same<RowLocalView,ColLocalView>::value && r.tree().treeIndex() == c.tree().treeIndex();
const bool optimized = std::is_same<RowLocalView,ColLocalView>::value
&& r.tree().treeIndex() == c.tree().treeIndex();
if (optimized)
backend_.scatter(nodeIndices(r), localMatrix);
else
......
......@@ -26,8 +26,8 @@ namespace AMDiS
{
/// \brief The basic container that stores a base vector and a corresponding basis
/**
* A vector storing all the assembled Operators indexed with DOF indices. The vector
* data is associated to a global basis.
* A vector storing all the assembled Operators indexed with DOF indices. The
* vector data is associated to a global basis.
*
* \tparam GB Basis of the vector
* \tparam B A linear algebra backend implementing the storage and operations.
......@@ -42,16 +42,15 @@ namespace AMDiS
using GlobalBasis = GB;
using LocalView = typename GlobalBasis::LocalView;
/// The Linear-Aglebra backend used to store the assembled coefficients
/// The Linear-Algebra backend used to store the assembled coefficients
using Backend = B;
using Comm = typename B::Traits::Comm;
private:
// proxy class redirecting the mutable element access to the inserValue method
// proxy class redirecting the mutable element access to the insertValue method
template <class Index>
struct AccessProxy;
using Comm = typename B::Traits::Comm;
enum class VectorState
{
unknown = 0,
......@@ -66,7 +65,7 @@ namespace AMDiS
std::integral_constant<VectorState, VectorState::insert_values>>;
public:
/// Constructor. Stores the shared_ptr of the basis and creates a new DataTransfer.
/// (1) Constructor. Stores the shared_ptr of the basis and communication object.
VectorBase(std::shared_ptr<GB> basis, std::shared_ptr<Comm> comm)
: basis_(std::move(basis))
, comm_(std::move(comm))
......@@ -75,15 +74,27 @@ namespace AMDiS
resizeZero();
}
/// Constructor. Wraps the reference into a non-destroying shared_ptr or moves
/// the basis into a new shared_ptr.
/// (2) Constructor. Forwards to (1) by wraping reference into non-destroying
/// shared_ptr.
template <class GB_, class Comm_,
REQUIRES(Concepts::Similar<GB_,GB>),
REQUIRES(Concepts::Similar<Comm_,Comm>)>
REQUIRES(Concepts::Similar<Types<GB_,Comm_>, Types<GB,Comm>>)>
VectorBase(GB_&& basis, Comm_&& comm)
: VectorBase(Dune::wrap_or_move(FWD(basis)), Dune::wrap_or_move(FWD(comm)))
{}
/// (3) Constructor. Forwards to (1) by creating a new communicator
explicit VectorBase(std::shared_ptr<GB> const& basis)
: VectorBase(basis, std::shared_ptr<Comm>(CommunicationCreator<Comm>::create(*basis)))
{}
/// (4) Constructor. Forwards to (3) by wrapping references into non-destroying
/// shared_ptr, see \ref Dune::wrap_or_move.
template <class GB_,
REQUIRES(Concepts::Similar<GB_,GB>)>
explicit VectorBase(GB_&& basis)
: VectorBase(Dune::wrap_or_move(FWD(basis)))
{}
/// Return the basis \ref basis_ associated to the vector
std::shared_ptr<GlobalBasis> const& basis() const { return basis_; }
std::shared_ptr<GlobalBasis> const& basis() { return basis_; }
......@@ -157,7 +168,8 @@ namespace AMDiS
return at(idx);
}
/// Access the entry \p i of the \ref vector with write-access. Uses a proxy class the redirects to \ref insertValue.
/// Access the entry \p i of the \ref vector with write-access. Uses a proxy
/// class the redirects to \ref insertValue.
template <class Index>
AccessProxy<Index> DUNE_DEPRECATED_MSG("Do not use element-wise vector access")
operator[](Index const& idx)
......@@ -176,10 +188,10 @@ namespace AMDiS
/// \brief Insert a single value into the matrix (add or overwrite to existing value)
/**
* Inserts or adds a value into a certain location \p dof (given as dof multi-index) of a vector.
* The insertion mode is determined by the \p assign functor. Use \ref Assigner::plus_assign for
* adding values (default) or \ref Assigner::assign for overwriting (setting) values. Different
* insertion modes can not be mixed!
* Inserts or adds a value into a certain location \p dof (given as dof multi-index)
* of a vector. The insertion mode is determined by the \p assign functor. Use
* \ref Assigner::plus_assign for adding values (default) or \ref Assigner::assign
* for overwriting (setting) values. Different insertion modes can not be mixed!
*
* Insertion must be closed with a call to \ref finish().
*
......@@ -214,13 +226,15 @@ namespace AMDiS
}
/// \brief Extract values from the vector referring to the given local indices and store it into a buffer
/// \brief Extract values from the vector referring to the given local indices
/// and store it into a buffer
/**
* Collect value of indices and store them into a buffer. The buffer must be a vector-like container
* with `buffer.resize()` and `buffer.begin()`. The indices must be stored in an iterable container.
* Collect value of indices and store them into a buffer. The buffer must be
* a vector-like container with `buffer.resize()` and `buffer.begin()`. The
* indices must be stored in an iterable container.
*
* If the vector is not in synchronized state, collects all necessary values possibly from
* neighbouring processors.
* If the vector is not in synchronized state, collects all necessary values
* possibly from neighbouring processors.
*
* [[expects: localView is bound to an element]]
* [[expects: node is in localView.tree()]]
......@@ -249,18 +263,19 @@ namespace AMDiS
/// Insert a block of values into the vector (add or overwrite to existing values)
/**
* Inserts or adds values into certain locations of a vector. Insertion indices are extracted from
* the given \p localView. The insertion mode is determined by the \p assign functor. Use
* \ref Assigner::plus_assign for adding values (default) or \ref Assigner::assign for overwriting
* (setting) values. Different insertion modes can not be mixed! The \p localVector is assumed
* to be a continuous memory container with a `data()` method to get a pointer to the beginning.
* Inserts or adds values into certain locations of a vector. Insertion indices
* are extracted from the given \p localView. The insertion mode is determined
* by the \p assign functor. Use \ref Assigner::plus_assign for adding values
* (default) or \ref Assigner::assign for overwriting (setting) values. Different
* insertion modes can not be mixed! The \p localVector is assumed to be a continuous
* memory container with a `data()` method to get a pointer to the beginning.
*
* The \p mask models a boolean range with at least a `begin()` method. Must be forward iterable
* for at least `localVector.size()` elements. Does not need an `end()` method. See, e.g.
* \ref FakeContainer.
* The \p mask models a boolean range with at least a `begin()` method. Must
* be forward iterable for at least `localVector.size()` elements. Does not
* need an `end()` method. See, e.g. \ref FakeContainer.
*
* Insertion must be closed with a call to \ref finish(). It is not allowed to switch insertion
* mode before calling `finish()`.
* Insertion must be closed with a call to \ref finish(). It is not allowed
* to switch insertion mode before calling `finish()`.
*
* [[expects: localView is bound to an element]]
* [[expects: node is in localView.tree()]]
......@@ -338,8 +353,8 @@ namespace AMDiS
/// Apply \p func to each value at given indices \p localInd
/**
* First, synchronizes the values of the vector, then applies the functor to each local value
* associated to the local indices \p localInd.
* First, synchronizes the values of the vector, then applies the functor to
* each local value associated to the local indices \p localInd.
*
* [[mutable]]
**/
......@@ -361,8 +376,8 @@ namespace AMDiS
/// Apply \p func to each value at given indices \p localInd
/**
* First, synchronizes the values of the vector, then applies the functor to each local value
* associated to the local indices \p localInd.
* First, synchronizes the values of the vector, then applies the functor to
* each local value associated to the local indices \p localInd.
*
* [[const]]
**/
......@@ -414,7 +429,8 @@ namespace AMDiS
/// Data backend
Backend backend_;
/// The current state of the vector, one of {synchronized, insert_values, add_values, unknown}
/// The current state of the vector, one of {synchronized, insert_values,
/// add_values, unknown}
VectorState state_ = VectorState::unknown;
};
......
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