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

assembler clened up, functors added

parent 3db71639
cmake_minimum_required(VERSION 3.1) cmake_minimum_required(VERSION 3.1)
project(dune-amdis CXX) project(dune-amdis CXX)
set(CXX_MAX_STANDARD 14 CACHE BOOL "" FORCE) #set(CXX_MAX_STANDARD 14 CACHE BOOL "" FORCE)
if(NOT (dune-common_DIR OR dune-common_ROOT OR if(NOT (dune-common_DIR OR dune-common_ROOT OR
"${CMAKE_PREFIX_PATH}" MATCHES ".*dune-common.*")) "${CMAKE_PREFIX_PATH}" MATCHES ".*dune-common.*"))
...@@ -20,11 +20,34 @@ include(DuneMacros) ...@@ -20,11 +20,34 @@ include(DuneMacros)
# start a dune project with information from dune.module # start a dune project with information from dune.module
dune_project() dune_project()
dune_enable_all_packages() dune_enable_all_packages(MODULE_LIBRARIES amdis)
include(AmdisMacros)
add_subdirectory("src") add_subdirectory("src")
add_subdirectory("dune") add_subdirectory("dune")
add_subdirectory("doc") add_subdirectory("doc")
add_subdirectory("cmake/modules") add_subdirectory("cmake/modules")
# some additional packages and flags
add_dune_alberta_flags("amdis" OBJECT USE_GENERIC)
target_compile_definitions("amdis" PUBLIC AMDIS_BACKEND_MTL=1)
target_compile_options("amdis" PUBLIC -ftemplate-backtrace-limit=0 -Wall -pedantic -Wno-unused-parameter)
find_package(MTL REQUIRED
PATHS /usr/local/lib/mtl4 /opt/sources/mtl4 /opt/development/mtl4)
if (MTL_FOUND)
target_include_directories("amdis" PUBLIC ${MTL_INCLUDE_DIRS})
set (CXX_ELEVEN_FEATURE_LIST "MOVE" "AUTO" "RANGEDFOR" "INITLIST" "STATICASSERT" "DEFAULTIMPL")
foreach (feature ${CXX_ELEVEN_FEATURE_LIST})
target_compile_definitions("amdis" PUBLIC MTL_WITH_${feature})
endforeach ()
if (HAVE_UMFPACK OR ENABLE_SUITESPARSE OR SuiteSparse_FOUND)
target_compile_definitions("amdis" PUBLIC MTL_HAS_UMFPACK)
endif ()
endif (MTL_FOUND)
# finalize the dune project, e.g. generating config.h etc. # finalize the dune project, e.g. generating config.h etc.
finalize_dune_project(GENERATE_CONFIG_H_CMAKE) finalize_dune_project(GENERATE_CONFIG_H_CMAKE)
#include(CheckIncludeFileCXX)
include(CheckCXXSourceCompiles)
#include(CheckCXXSymbolExists)
# fold expressions (a + ...)
check_cxx_source_compiles("
template <class... Args>
int f(Args... args)
{
return (args + ...);
}
int main()
{
f(0,1,2,3,4,5);
}
" AMDIS_HAS_CXX_FOLD_EXPRESSION
)
check_cxx_source_compiles("
template <int I>
auto f()
{
if constexpr(I == 0)
return double{1.0};
else
return int{0};
}
int main()
{
return f<1>();
}
" AMDIS_HAS_CXX_CONSTEXPR_IF
)
\ No newline at end of file
# File for module specific CMake tests. # File for module specific CMake tests.
include(AMDiSCXXFeatures)
\ No newline at end of file
...@@ -40,6 +40,12 @@ ...@@ -40,6 +40,12 @@
/* Define to the revision of amdis */ /* Define to the revision of amdis */
#define AMDIS_VERSION_REVISION @AMDIS_VERSION_REVISION@ #define AMDIS_VERSION_REVISION @AMDIS_VERSION_REVISION@
/* end amdis
/* some detected compiler features may be used in AMDiS */
#cmakedefine AMDIS_HAS_CXX_FOLD_EXPRESSIONS 1
#cmakedefine AMDIS_HAS_CXX_CONSTEXPR_IF 1
/* end dune-amdis
Everything below here will be overwritten Everything below here will be overwritten
*/ */
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
// AMDiS includes // AMDiS includes
#include <dune/amdis/Output.hpp> #include <dune/amdis/Output.hpp>
#include <dune/amdis/Math.hpp> #include <dune/amdis/common/Math.hpp>
namespace AMDiS namespace AMDiS
{ {
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
#include <dune/amdis/utility/TreePath.hpp> #include <dune/amdis/utility/TreePath.hpp>
#include <dune/amdis/utility/Visitor.hpp> #include <dune/amdis/utility/Visitor.hpp>
#include <dune/amdis/Math.hpp> #include <dune/amdis/common/Math.hpp>
namespace AMDiS { namespace AMDiS {
......
#install headers #install headers
dune_add_library("duneamdis" NO_EXPORT dune_library_add_sources(amdis SOURCES
AdaptBase.cpp AdaptBase.cpp
AdaptInfo.cpp AdaptInfo.cpp
AdaptInstationary.cpp AdaptInstationary.cpp
...@@ -11,33 +11,7 @@ dune_add_library("duneamdis" NO_EXPORT ...@@ -11,33 +11,7 @@ dune_add_library("duneamdis" NO_EXPORT
# ProblemInstat.cpp # ProblemInstat.cpp
ProblemStat.cpp ProblemStat.cpp
StandardProblemIteration.cpp StandardProblemIteration.cpp
#linear_algebra/istl/SystemMatrix.cpp )
#linear_algebra/istl/SystemVector.cpp
linear_algebra/mtl/SystemMatrix.cpp
linear_algebra/mtl/SystemVector.cpp
utility/Filesystem.cpp
)
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 -Wall -pedantic -Wno-unused-parameter)
find_package(MTL REQUIRED
PATHS /usr/local/lib/mtl4)
if (MTL_FOUND)
target_include_directories("duneamdis" PUBLIC ${MTL_INCLUDE_DIRS})
# target_link_libraries("duneamdis" PUBLIC ${MTL_LIBRARIES})
# target_compile_options("duneamdis" PUBLIC ${MTL_CXX_DEFINITIONS})
set (CXX_ELEVEN_FEATURE_LIST "MOVE" "AUTO" "RANGEDFOR" "INITLIST" "STATICASSERT" "DEFAULTIMPL")
foreach (feature ${CXX_ELEVEN_FEATURE_LIST})
target_compile_definitions("duneamdis" PUBLIC MTL_WITH_${feature})
endforeach ()
if (HAVE_UMFPACK OR ENABLE_SUITESPARSE OR SuiteSparse_FOUND)
target_compile_definitions("duneamdis" PUBLIC MTL_HAS_UMFPACK)
endif ()
endif (MTL_FOUND)
install(FILES install(FILES
AdaptBase.hpp AdaptBase.hpp
...@@ -45,73 +19,40 @@ install(FILES ...@@ -45,73 +19,40 @@ install(FILES
AdaptInstationary.hpp AdaptInstationary.hpp
AdaptStationary.hpp AdaptStationary.hpp
AMDiS.hpp AMDiS.hpp
Assembler.hpp
Assembler.inc.hpp
ContextGeometry.hpp
CreatorInterface.hpp CreatorInterface.hpp
CreatorMap.hpp CreatorMap.hpp
DirichletBC.hpp DirichletBC.hpp
DirichletBC.inc.hpp DirichletBC.inc.hpp
FileWriter.hpp FileWriter.hpp
Flag.hpp Flag.hpp
GridFunctionOperator.hpp
GridFunctions.hpp
Initfile.hpp Initfile.hpp
LinearAlgebra.hpp LinearAlgebra.hpp
Log.hpp LocalAssembler.hpp
Math.hpp LocalAssemblerBase.hpp
Mesh.hpp Mesh.hpp
OperatorEvaluation.hpp Operators.hpp
Operator.hpp Output.hpp
Operator.inc.hpp
OperatorTermBase.hpp
OperatorTerm.hpp
ProblemInstatBase.hpp
ProblemInstat.hpp ProblemInstat.hpp
ProblemInstat.inc.hpp ProblemInstat.inc.hpp
ProblemInstatBase.hpp
ProblemInterationInterface.hpp ProblemInterationInterface.hpp
ProblemStatBase.hpp
ProblemStat.hpp ProblemStat.hpp
ProblemStat.inc.hpp ProblemStat.inc.hpp
ProblemStatBase.hpp
ProblemStatTraits.hpp
ProblemTimeInterface.hpp ProblemTimeInterface.hpp
StandardProblemIteration.hpp StandardProblemIteration.hpp
TermGenerator.hpp
common/ConceptsBase.hpp
common/ClonablePtr.hpp
common/IndexSeq.hpp
common/Literals.hpp
common/Loops.hpp
common/Mpl.hpp
common/ScalarTypes.hpp
common/Timer.hpp
common/Traits.hpp
common/TupleUtility.hpp
common/Utility.hpp
common/ValueCategory.hpp
linear_algebra/LinearAlgebraBse.hpp
linear_algebra/LinearSolverInterface.hpp
linear_algebra/PreconditionerInterface.hpp
linear_algebra/RunnerInterface.hpp
linear_algebra/SolverInfo.hpp
linear_algebra/istl/DOFMatrix.hpp
linear_algebra/istl/DOFVector.hpp
linear_algebra/istl/ISTL_Preconditioner.hpp
linear_algebra/istl/ISTLRunner.hpp
linear_algebra/istl/ISTL_Solver.hpp
linear_algebra/istl/LinearSolver.hpp
linear_algebra/istl/Preconditioner.hpp
linear_algebra/istl/SystemMatrix.hpp
linear_algebra/istl/SystemVector.hpp
linear_algebra/mtl/BITL_Preconditioner.hpp
linear_algebra/mtl/BITL_Solver.hpp
linear_algebra/mtl/BlockMTLMatrix.hpp
linear_algebra/mtl/BlockMTLVector.hpp
linear_algebra/mtl/Copy.hpp
linear_algebra/mtl/DOFMatrix.hpp
linear_algebra/mtl/DOFVector.hpp
linear_algebra/mtl/ITL_Preconditioner.hpp
linear_algebra/mtl/ITL_Solver.hpp
linear_algebra/mtl/KrylovRunner.hpp
linear_algebra/mtl/LinearSolver.hpp
linear_algebra/mtl/Mapper.hpp
linear_algebra/mtl/MTLDenseVector.hpp
linear_algebra/mtl/Preconditioner.hpp
linear_algebra/mtl/SystemMatrix.hpp
linear_algebra/mtl/SystemVector.hpp
linear_algebra/mtl/UmfpackRunner.hpp
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dune/amdis) DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dune/amdis)
add_subdirectory("assembler")
add_subdirectory("common")
add_subdirectory("gridfunctions")
add_subdirectory("io")
add_subdirectory("linear_algebra")
add_subdirectory("operations")
add_subdirectory("utility")
\ No newline at end of file
#pragma once #pragma once
#include <cassert> #include <cassert>
#include <type_traits>
#include <dune/amdis/terms/TermGenerator.hpp> #include <dune/amdis/gridfunctions/GridFunctionConcepts.hpp>
#include <dune/amdis/utility/GetDegree.hpp> #include <dune/amdis/utility/GetDegree.hpp>
namespace AMDiS namespace AMDiS
{ {
template <class Expr> template <class GridFunction>
class ExpressionOperatorBase class GridFunctionOperatorBase
{ {
using LocalFunction = decltype(localFunction(std::declval<GridFunction>()));
using Element = typename GridFunction::EntitySet::Element;
using Geometry = typename Element::Geometry;
using LocalCoordinate = typename GridFunction::EntitySet::LocalCoordinate;
public: public:
/// \brief Constructor. Stores a copy of `expr`. /// \brief Constructor. Stores a copy of `expr`.
/** /**
...@@ -17,8 +24,9 @@ namespace AMDiS ...@@ -17,8 +24,9 @@ namespace AMDiS
* \ref ExpressionBase, and stores a copy. Additionally, it gets the * \ref ExpressionBase, and stores a copy. Additionally, it gets the
* differentiation order, to calculate the quadrature degree in \ref getDegree. * differentiation order, to calculate the quadrature degree in \ref getDegree.
**/ **/
ExpressionOperatorBase(Expr const& expr, int order) GridFunctionOperatorBase(GridFunction const& gridFct, int order)
: expr_(expr) : gridFct_(gridFct)
, localFct_(localFunction(gridFct_))
, order_(order) , order_(order)
{} {}
...@@ -28,13 +36,12 @@ namespace AMDiS ...@@ -28,13 +36,12 @@ namespace AMDiS
* Since all operators need geometry information, the `Element::Geometry` * Since all operators need geometry information, the `Element::Geometry`
* object `geometry` is created once, during grid traversal, and passed in. * object `geometry` is created once, during grid traversal, and passed in.
* *
* By default, it binds the \ref expr_ to the `element`. * By default, it binds the \ref localFct_ to the `element`.
**/ **/
template <class Element, class Geometry>
void bind(Element const& element, Geometry const& geometry) void bind(Element const& element, Geometry const& geometry)
{ {
if (!bound_) { if (!bound_) {
expr_.bind(element); localFct_.bind(element);
isSimplex_ = geometry.type().isSimplex(); isSimplex_ = geometry.type().isSimplex();
isAffine_ = geometry.affine(); isAffine_ = geometry.affine();
bound_ = true; bound_ = true;
...@@ -45,32 +52,14 @@ namespace AMDiS ...@@ -45,32 +52,14 @@ namespace AMDiS
void unbind() void unbind()
{ {
bound_ = false; bound_ = false;
initSize_ = 0; localFct_.unbind();
expr_.unbind();
}
/// \brief Evaluate expression at quadrature points.
/**
* Initialization at all points `quad[iq].position()` where
* `iq` in `[0, quad.size())`.
*
* \param context Container for localContext, localGeometry and geometry, see \ref LocalAssembler
* \param quad Liste of evaluations points. Follows interface of \ref Dune::QuadratureRule
**/
template <class Context, class Quad>
void init(Context const& context, Quad const& quad)
{
if (initSize_ != quad.size()) {
expr_.init(context, quad);
initSize_ = quad.size();
}
} }
/// Return expressions iq'th value. Must be initialized in \ref init before. /// Return expressions iq'th value. Must be initialized in \ref init before.
auto eval(std::size_t iq) const auto coefficient(LocalCoordinate const& local) const
{ {
assert( initSize_ > 0u ); assert( bound_ );
return expr_[iq]; return localFct_(local);
} }
...@@ -86,9 +75,9 @@ namespace AMDiS ...@@ -86,9 +75,9 @@ namespace AMDiS
assert( bound_ ); assert( bound_ );
int psiDegree = getPolynomialDegree(node); int psiDegree = getPolynomialDegree(node);
int termDegree = expr_.getDegree(); int coeffDegree = order(localFct_);
int degree = psiDegree + termDegree; int degree = psiDegree + coeffDegree;
if (isSimplex_) if (isSimplex_)
degree -= order_; degree -= order_;
if (isAffine_) if (isAffine_)
...@@ -111,9 +100,9 @@ namespace AMDiS ...@@ -111,9 +100,9 @@ namespace AMDiS
int psiDegree = getPolynomialDegree(rowNode); int psiDegree = getPolynomialDegree(rowNode);
int phiDegree = getPolynomialDegree(colNode); int phiDegree = getPolynomialDegree(colNode);
int termDegree = expr_.getDegree(); int coeffDegree = order(localFct_);
int degree = psiDegree + phiDegree + termDegree; int degree = psiDegree + phiDegree + coeffDegree;
if (isSimplex_) if (isSimplex_)
degree -= order_; degree -= order_;
if (isAffine_) if (isAffine_)
...@@ -122,45 +111,31 @@ namespace AMDiS ...@@ -122,45 +111,31 @@ namespace AMDiS
return degree; return degree;
} }
protected:
Expr& expr()
{
return expr_;
}
Expr const& expr() const
{
return expr_;
}
private: private:
GridFunction gridFct_;
LocalFunction localFct_;
Expr expr_; //< the stores expression, see \ref ExpressionBase
int order_; //< the derivative order of this operator int order_; //< the derivative order of this operator
bool isSimplex_ = false; //< the bound element is a simplex bool isSimplex_ = false; //< the bound element is a simplex
bool isAffine_ = false; //< the bound geometry is affine bool isAffine_ = false; //< the bound geometry is affine
bool bound_ = false; //< an element is bound to the operator bool bound_ = false; //< an element is bound to the operator
std::size_t initSize_ = 0; //< number of quadrature points, the expression was evaluated at.
}; };
/// A default implementation of an ExpressionOperator if no specialization is available. /// A default implementation of an GridFunctionOperator if no specialization is available.
/** /**
* An operator must implement either \ref calculateElementVector, or * An operator must implement either \ref calculateElementVector, or
* \ref calculateElementMatrix, if it is a vector or matrix operator, * \ref calculateElementMatrix, if it is a vector or matrix operator,
* respectively. * respectively.
**/ **/
template <class Tag, class Expr> template <class Tag, class GridFct>
class ExpressionOperator class GridFunctionOperator
: public ExpressionOperatorBase<Expr> : public GridFunctionOperatorBase<GridFct>
{ {
public: public:
ExpressionOperator(Tag, Expr const& expr) GridFunctionOperator(Tag, GridFct const& gridFct)
: ExpressionOperatorBase<Expr>(expr, 0) : GridFunctionOperatorBase<GridFct>(gridFct, 0)
{} {}
/// Assemble a local element vector on the element that is bound. /// Assemble a local element vector on the element that is bound.
...@@ -191,21 +166,50 @@ namespace AMDiS ...@@ -191,21 +166,50 @@ namespace AMDiS
} }
}; };
template <class Tag, class Expr>
struct ExpressionPreOperator
{
Tag tag;
Expr expr;
};
/// Store tag and expression in struct
template <class Tag, class Expr>
auto makeOperator(Tag t, Expr const& expr)
{
return ExpressionPreOperator<Tag, Expr>{t, expr};
}
/// Generate an \ref GridFunctionOperator from a PreOperator (tag, expr).
template <class Tag, class Expr, class GridView>
auto makeGridOperator(ExpressionPreOperator<Tag, Expr> const& op, GridView const& gridView)
{
auto gridFct = makeGridFunction(op.expr, gridView, Dune::PriorityTag<42>{});
return GridFunctionOperator<Tag, decltype(gridFct)>{op.tag, gridFct};
}
template <class Tag, class Expr, class GridView>
auto makeGridOperator(std::reference_wrapper<ExpressionPreOperator<Tag, Expr>> op, GridView const& gridView)
{
ExpressionPreOperator<Tag, Expr> const& op_ref = op;
auto gridFct = makeGridFunction(std::ref(op_ref.expr), gridView, Dune::PriorityTag<42>{});
return GridFunctionOperator<Tag, decltype(gridFct)>{op_ref.tag, gridFct};
}
/// Generate an \ref ExpressionOperator with a given tag `t` and pre-expression `epxr`. /// Generate a shared_ptr to \ref GridFunctionOperator from a PreOperator (tag, expr).
template <class Tag, class PreExpr> template <class Tag, class Expr, class GridView>
auto makeOperator(Tag t, PreExpr const& expr) auto makeGridOperatorPtr(ExpressionPreOperator<Tag, Expr> const& op, GridView const& gridView)
{ {
using Expr = ToTerm_t<PreExpr>; auto gridFct = makeGridFunction(op.expr, gridView, Dune::PriorityTag<42>{});
return ExpressionOperator<Tag, Expr>{t, toTerm(expr)}; return std::make_shared<GridFunctionOperator<Tag, decltype(gridFct)>>(op.tag, gridFct);
} }
/// Generate a shared_ptr to \ref ExpressionOperator with a given tag `t` and pre-expression `epxr`. template <class Tag, class Expr, class GridView>
template <class Tag, class PreExpr> auto makeGridOperatorPtr(std::reference_wrapper<ExpressionPreOperator<Tag, Expr>> op, GridView const& gridView)
auto makeOperatorPtr(Tag t, PreExpr const& expr)
{ {
using Expr = ToTerm_t<PreExpr>; ExpressionPreOperator<Tag, Expr> const& op_ref = op;
return std::make_shared<ExpressionOperator<Tag, Expr>>(t, toTerm(expr)); auto gridFct = makeGridFunction(std::ref(op_ref.expr), gridView, Dune::PriorityTag<42>{});
return std::make_shared<GridFunctionOperator<Tag, decltype(gridFct)>>(op_ref.tag, gridFct);
} }
} // end namespace AMDiS } // end namespace AMDiS
#pragma once
#include <dune/amdis/gridfunctions/AnalyticGridFunction.hpp>
#include <dune/amdis/gridfunctions/ConstantGridFunction.hpp>
#include <dune/amdis/gridfunctions/CoordsGridFunction.hpp>
#include <dune/amdis/gridfunctions/DerivativeGridFunction.hpp>
#include <dune/amdis/gridfunctions/FunctorGridFunction.hpp>
#include <dune/amdis/gridfunctions/OperationsGridFunction.hpp>
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#include <dune/common/fvector.hh> #include <dune/common/fvector.hh>
#include <dune/amdis/Output.hpp> #include <dune/amdis/Output.hpp>
#include <dune/amdis/Math.hpp> #include <dune/amdis/common/Math.hpp>
namespace AMDiS namespace AMDiS
{ {
......
...@@ -189,7 +189,7 @@ namespace AMDiS ...@@ -189,7 +189,7 @@ namespace AMDiS
private: private:
std::unique_ptr<Operator> storage_; //< the stored operator, implementing \ref ExpressionOperatorBase std::unique_ptr