Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • lisa_julia.nebel_at_tu-dresden.de/dune-solvers
  • patrick.jaap_at_tu-dresden.de/dune-solvers
  • burchardt_at_igpm.rwth-aachen.de/dune-solvers
  • agnumpde/dune-solvers
4 results
Select Git revision
Show changes
Commits on Source (283)
Showing
with 148 additions and 581 deletions
# ignore all build folders
# / /build*/
/configure # ignore backup files
/Makefile.in *~
/Makefile # ignore Python files
/config.* *.pyc
/dune-solvers.pc
/depcomp
/ltmain.sh
/dependencies.m4
/stamp-h1
/am
/libtool
/autom4te.cache
/missing
/aclocal.m4
/install-sh
/compile
/test-driver
# /cmake/
/cmake/Makefile.in
/cmake/Makefile
/cmake/modules/Makefile.in
/cmake/modules/Makefile
# /doc/
/doc/Makefile.in
/doc/Makefile
# /doc/doxygen/
/doc/doxygen/doxygen-tag
/doc/doxygen/doxygen.log
/doc/doxygen/doxyerr.log
/doc/doxygen/html
/doc/doxygen/Makefile.in
/doc/doxygen/Makefile
/doc/doxygen/Doxyfile
/doc/doxygen/Doxyfile.in
# /dune/
/dune/Makefile.in
/dune/Makefile
# /dune/solvers/
/dune/solvers/Makefile.in
/dune/solvers/Makefile
# /dune/solvers/common/
/dune/solvers/common/Makefile.in
/dune/solvers/common/Makefile
# /dune/solvers/iterationsteps/
/dune/solvers/iterationsteps/Makefile.in
/dune/solvers/iterationsteps/Makefile
# /dune/solvers/norms/
/dune/solvers/norms/Makefile.in
/dune/solvers/norms/Makefile
# /dune/solvers/operators/
/dune/solvers/operators/Makefile.in
/dune/solvers/operators/Makefile
# /dune/solvers/solvers/
/dune/solvers/solvers/Makefile.in
/dune/solvers/solvers/Makefile
# /dune/solvers/test/
/dune/solvers/test/cgsteptest
/dune/solvers/test/genericvectortoolstest
/dune/solvers/test/lowrankoperatortest
/dune/solvers/test/mmgtest
/dune/solvers/test/multigridtest
/dune/solvers/test/nulloperatortest
/dune/solvers/test/quadraticipoptsolvertest
/dune/solvers/test/sumoperatortest
/dune/solvers/test/Makefile.in
/dune/solvers/test/Makefile
/dune/solvers/test/.deps
/dune/solvers/test/*.o
# /dune/solvers/transferoperators/
/dune/solvers/transferoperators/Makefile.in
/dune/solvers/transferoperators/Makefile
# /m4/
/m4/Makefile.in
/m4/Makefile
# /src/
/src/Makefile.in
/src/Makefile
/src/dune_solvers
/src/.deps
# Standard cmake build directory
/build-cmake
--- ---
# Install external dependencies # Install external dependencies
before_script:
- duneci-install-module https://git.imp.fu-berlin.de/agnumpde/dune-matrix-vector.git
dune:git--clang: # For release-based jobs, we use corresponding images,
image: duneci/dune:git # that already contain all core and staging dependencies.
.release_based_job:
before_script:
- duneci-install-module https://gitlab.dune-project.org/fufem/dune-matrix-vector.git
# For branch-based-based jobs, we need to install all dependencies manually.
.branch_base_job:
before_script:
- . /duneci/bin/duneci-init-job
- duneci-install-module https://gitlab.dune-project.org/core/dune-common.git
- duneci-install-module https://gitlab.dune-project.org/core/dune-geometry.git
- duneci-install-module https://gitlab.dune-project.org/core/dune-localfunctions.git
- duneci-install-module https://gitlab.dune-project.org/staging/dune-uggrid.git
- duneci-install-module https://gitlab.dune-project.org/core/dune-grid.git
- duneci-install-module https://gitlab.dune-project.org/core/dune-istl.git
- duneci-install-module https://gitlab.dune-project.org/fufem/dune-matrix-vector.git
# The 2.9 release is the one in Debian 12 ('bookworm', 'stable' at the time of writing)
dune:2.9 debian-11 gcc-10 C++20:
extends: .release_based_job
variables:
DUNECI_BRANCH: releases/2.9
image: registry.dune-project.org/docker/ci/dune:2.9-debian-11-gcc-10-20
script: duneci-standard-test
# The 2.10 release is the one in Debian 13 ('trixie', 'testing' at the time of writing)
# To test against 2.10 we need an image with the corresponding version of the core modules.
# Unfortunately, there is no 2.10 image with a recent enough compiler.
dune:2.10 debian-11 gcc-10 C++20:
extends: .release_based_job
variables:
DUNECI_BRANCH: releases/2.10
image: registry.dune-project.org/docker/ci/dune:2.10-debian-11-gcc-10-20
script: duneci-standard-test
# Also test with the current development branch
dune:git debian-11 clang-13 C++20:
extends: .branch_base_job
# image: registry.dune-project.org/docker/ci/dune:git-debian-11-clang-13-20
image: registry.dune-project.org/docker/ci/debian:11
variables:
DUNECI_TOOLCHAIN: clang-13-20
script: duneci-standard-test
dune:git debian-11 gcc-10 C++20:
extends: .branch_base_job
# image: registry.dune-project.org/docker/ci/dune:git-debian-11-gcc-10-20
image: registry.dune-project.org/docker/ci/debian:11
variables:
DUNECI_TOOLCHAIN: gcc-10-20
script: duneci-standard-test script: duneci-standard-test
dune:git--gcc: # Check for spelling mistakes in text
image: duneci/dune:git code-spelling-check:
script: duneci-standard-test --opts=/duneci/opts.clang stage: .pre
# Avoid the global 'before_script'
before_script: ""
image: registry.dune-project.org/docker/ci/debian:11
script:
- codespell
--ignore-words-list foo,bar
# Master (will become release 2.11)
- ...
# Release 2.10
- Deprecate the file `tuplevector.hh`. An equivalent file exists in `dune-common`
since 2016. Please use that from now on.
- `UMFPackSolver` accepts each correctly formed blocked matrix. The user has to make sure that the vector types of `x` and `rhs` are compatible to the matrix.
The main advantage is that it is now possible to use `MultiTypeBlockMatrix`.
- A new solver `ProximalNewtonSolver` is added which solves non-smooth minimization problems.
# Release 2.9
- The internal matrix of the`EnergyNorm` can now be accessed by `getMatrix()`.
- The default `BitVectorType` of the class `IterationStep` is now
`Solvers::DefaultBitVector_t<VectorType>` rather than `Dune::BitSetVector`.
This should do the right thing in more situations, while being fully
backward-compatible.
- `codespell` spell checker is now active for automated spell checking in the Gitlab CI.
To exclude false positives add the words to the `--ignore-words-list` in `.gitlab-ci.yml`.
# Release 2.8
- `UMFPackSolver` can now handle matrices and vectors with scalar entries.
- CholmodSolver: Added `errorCode_` member to report errors and warnings during the matrix decomposition
- CholmodSolver: `CholmodSolver` can be used with any blocked matrix/vector type supported by `flatMatrixForEach` and `flatVectorForEach` in dune-istl.
- CholmodSolver: There are now various new methods that allow to factorize the matrix once,
and use the factorization to solve linear systems with several right hand sides.
## Deprecations and removals
- The file `blockgsstep.hh` has been removed after four years of deprecation. Use the replacement
in `blockgssteps.hh` instead.
cmake_minimum_required(VERSION 2.8.6) if(dune-common_VERSION VERSION_GREATER_EQUAL 2.10.0)
cmake_minimum_required(VERSION 3.16)
else()
cmake_minimum_required(VERSION 3.13)
endif()
project(dune-solvers CXX) project(dune-solvers CXX)
if(NOT (dune-common_DIR OR dune-common_ROOT OR if(NOT (dune-common_DIR OR dune-common_ROOT OR
...@@ -22,10 +26,17 @@ dune_project() ...@@ -22,10 +26,17 @@ dune_project()
find_package(SuiteSparse OPTIONAL_COMPONENTS UMFPACK) find_package(SuiteSparse OPTIONAL_COMPONENTS UMFPACK)
include(AddSuiteSparseFlags) include(AddSuiteSparseFlags)
add_subdirectory("m4") # Create library target and export it as Dune::Solvers
dune_add_library(dunesolvers EXPORT_NAME Solvers LINK_LIBRARIES ${DUNE_LIBS})
dune_register_package_flags(LIBRARIES dunesolvers)
add_subdirectory("dune") add_subdirectory("dune")
add_subdirectory("doc") add_subdirectory("doc")
add_subdirectory("cmake/modules") add_subdirectory("cmake/modules")
# finalize the dune project, e.g. generating config.h etc. if(dune-common_VERSION VERSION_GREATER_EQUAL 2.10.0)
finalize_dune_project(GENERATE_CONFIG_H_CMAKE) finalize_dune_project()
else()
finalize_dune_project(GENERATE_CONFIG_H_CMAKE)
endif()
# $Id$
# we need the module file to be able to build via dunecontrol
EXTRA_DIST = dune.module \
CMakeLists.txt \
config.h.cmake
SUBDIRS = m4 dune doc cmake
if BUILD_DOCS
SUBDIRS += doc
endif
# don't follow the full GNU-standard
# we need automake 1.9 or newer
AUTOMAKE_OPTIONS = foreign 1.9
# pass most important options when "make distcheck" is used
# dune-geometry is a dependency of dune-grid.
DISTCHECK_CONFIGURE_FLAGS = --with-dune-common=$(DUNE_COMMON_ROOT) --with-dune-geometry=$(DUNE_GEOMETRY_ROOT) --with-dune-grid=$(DUNE_GRID_ROOT) --with-dune-istl=$(DUNE_ISTL_ROOT) --with-dune-localfunctions=$(DUNE_LOCALFUNCTIONS_ROOT) CXX="$(CXX)" CC="$(CC)"
include $(top_srcdir)/am/top-rules
include $(top_srcdir)/am/global-rules
# Generate package configuration files for finding
# installed modules with CMake
include $(top_srcdir)/am/cmake-pkg-config
SUBDIRS = modules
include $(top_srcdir)/am/global-rules
...@@ -7,7 +7,7 @@ function(add_dune_ipopt_flags _targets) ...@@ -7,7 +7,7 @@ function(add_dune_ipopt_flags _targets)
set_target_properties(${_target} PROPERTIES COMPILE_FLAGS set_target_properties(${_target} PROPERTIES COMPILE_FLAGS
"${_props} ${DUNE_IPOPT_CFLAGS}") "${_props} ${DUNE_IPOPT_CFLAGS}")
if(NOT ADD_DUNE_IPOPT_FLAGS_OBJECT) if(NOT ADD_DUNE_IPOPT_FLAGS_OBJECT)
target_link_libraries(${_target} ${IPOPT_LIBRARY}) target_link_libraries(${_target} PUBLIC ${IPOPT_LIBRARY})
endif() endif()
endforeach(_target ${_targets}) endforeach(_target ${_targets})
endif(IPOPT_FOUND) endif(IPOPT_FOUND)
......
...@@ -8,23 +8,39 @@ find_library(DL_LIBRARY dl) ...@@ -8,23 +8,39 @@ find_library(DL_LIBRARY dl)
find_path(IPOPT_INCLUDE_DIR find_path(IPOPT_INCLUDE_DIR
NAMES "IpNLP.hpp" NAMES "IpNLP.hpp"
PATH_SUFFIXES "include" "include/coin" PATHS ${IPOPT_ROOT}
PATH_SUFFIXES "include" "include/coin" "include/coin-or"
NO_DEFAULT_PATH
)
find_path(IPOPT_INCLUDE_DIR
NAMES "IpNLP.hpp"
PATH_SUFFIXES "include" "include/coin" "include/coin-or"
) )
find_library(IPOPT_LIBRARY find_library(IPOPT_LIBRARY
NAMES ipopt NAMES ipopt
PATHS ${IPOPT_ROOT}
PATH_SUFFIXES "lib" PATH_SUFFIXES "lib"
NO_DEFAULT_PATH
)
find_library(IPOPT_LIBRARY
NAMES ipopt
) )
# If you want to want to use other linear solver # If you want to want to use other linear solver
find_library(HSL_LIBRARY find_library(HSL_LIBRARY
NAMES hsl coinhsl NAMES hsl coinhsl
PATHS ${IPOPT_ROOT}
PATH_SUFFIXES "lib" PATH_SUFFIXES "lib"
NO_DEFAULT_PATH
)
find_library(HSL_LIBRARY
NAMES hsl coinhsl
) )
find_package_handle_standard_args(hsl DEFAULT_MSG HSL_LIBRARY) find_package_handle_standard_args(hsl DEFAULT_MSG HSL_LIBRARY)
find_package_handle_standard_args(dl DEFAULT_MSG DL_LIBRARY) find_package_handle_standard_args(dl DEFAULT_MSG DL_LIBRARY)
find_package_handle_standard_args(Ipopt DEFAULT_MSG IPOPT_INCLUDE_DIR IPOPT_LIBRARY) find_package_handle_standard_args(IPOpt DEFAULT_MSG IPOPT_INCLUDE_DIR IPOPT_LIBRARY)
if(IPOPT_FOUND) if(IPOPT_FOUND)
set(HAVE_IPOPT ENABLE_IPOPT) set(HAVE_IPOPT ENABLE_IPOPT)
......
MODULES = DuneSolversMacros.cmake
modulesdir = $(datadir)/dune/cmake/modules
dist_modules_DATA = ${MODULES}
include $(top_srcdir)/am/global-rules
EXTRA_DIST = CMakeLists.txt AddIPOptflags.cmake DuneSolversMacros.cmake FindIPOpt.cmake
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.62])
DUNE_AC_INIT # gets module version from dune.module file
AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR([dune-solvers.pc.in])
AC_CONFIG_HEADERS([config.h])
# we need no more than the standard DE-stuff
# this module depends on dune-common dune-grid dune-istl dune-localfunctions
# this implies checking for [dune-common], [dune-geometry], [dune-grid], [dune-istl], [dune-localfunctions]
DUNE_CHECK_ALL
# implicitly set the Dune-flags everywhere
AC_SUBST(AM_CPPFLAGS, $DUNE_CPPFLAGS)
AC_SUBST(AM_LDFLAGS, $DUNE_LDFLAGS)
LIBS="$DUNE_LIBS"
AC_CONFIG_FILES([
Makefile
cmake/Makefile
cmake/modules/Makefile
doc/Makefile
doc/doxygen/Makefile
doc/doxygen/Doxyfile
dune/Makefile
dune/solvers/Makefile
dune/solvers/common/Makefile
dune/solvers/iterationsteps/Makefile
dune/solvers/norms/Makefile
dune/solvers/operators/Makefile
dune/solvers/solvers/Makefile
dune/solvers/test/Makefile
dune/solvers/transferoperators/Makefile
m4/Makefile
dune-solvers.pc
])
AC_OUTPUT
# finally print the summary information
DUNE_SUMMARY_ALL
...@@ -21,7 +21,7 @@ CHANGES REQUIRING CODE ADAPTATION ...@@ -21,7 +21,7 @@ CHANGES REQUIRING CODE ADAPTATION
--------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------
CHANGES POSSIBLY AFFECTING PERFOMANCE (INCLUDING BUGFIXES) CHANGES POSSIBLY AFFECTING PERFORMANCE (INCLUDING BUGFIXES)
---------------------------------------------------------- ----------------------------------------------------------
---------------------------------------------------------- ----------------------------------------------------------
......
SUBDIRS = doxygen
CURDIR = doc
BASEDIR = ..
# add list of html files to generate from wml
PAGES=
docdir=$(datadir)/doc/dune-solvers
EXTRA_DIST = CMakeLists.txt LOWRANKBRANCH-BACKPORT-CHANGES
include $(top_srcdir)/am/webstuff
include $(top_srcdir)/am/global-rules
BASEDIR=../..
CURDIR=doc/doxygen
EXTRA_DIST = CMakeLists.txt
include $(top_srcdir)/am/doxygen
include $(top_srcdir)/am/global-rules
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
#Name of the module #Name of the module
Module: dune-solvers Module: dune-solvers
Version: 2.5 Version: 2.11-git
Maintainer: oliver.sander@tu-dresden.de Maintainer: oliver.sander@tu-dresden.de
#depending on #depending on
Depends: dune-common dune-grid dune-istl dune-localfunctions dune-matrix-vector Depends: dune-common dune-grid dune-istl dune-localfunctions dune-matrix-vector
......
SUBDIRS = solvers
EXTRA_DIST = CMakeLists.txt
include $(top_srcdir)/am/global-rules
dune_add_library("dunesolvers"
iterationsteps/blockgssteps.cc
solvers/criterion.cc)
dune_register_package_flags(LIBRARIES dunesolvers)
add_subdirectory("common") add_subdirectory("common")
add_subdirectory("iterationsteps") add_subdirectory("iterationsteps")
add_subdirectory("norms") add_subdirectory("norms")
...@@ -12,6 +6,10 @@ add_subdirectory("solvers") ...@@ -12,6 +6,10 @@ add_subdirectory("solvers")
add_subdirectory("test") add_subdirectory("test")
add_subdirectory("transferoperators") add_subdirectory("transferoperators")
target_sources(dunesolvers PRIVATE
iterationsteps/blockgssteps.cc
solvers/criterion.cc)
install(FILES install(FILES
computeenergy.hh computeenergy.hh
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dune/solvers) DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dune/solvers)
SUBDIRS = common iterationsteps norms operators solvers test transferoperators
dune_solversdir = $(includedir)/dune/solvers
dune_solvers_HEADERS = computeenergy.hh
EXTRA_DIST = CMakeLists.txt
include $(top_srcdir)/am/global-rules
install(FILES install(FILES
algorithm.hh
arithmetic.hh
boxconstraint.hh boxconstraint.hh
canignore.hh canignore.hh
copyorreference.hh copyorreference.hh
...@@ -13,5 +11,5 @@ install(FILES ...@@ -13,5 +11,5 @@ install(FILES
resize.hh resize.hh
staticmatrixtools.hh staticmatrixtools.hh
tuplevector.hh tuplevector.hh
typetraits.hh wrapownshare.hh
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dune/solvers/common) DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dune/solvers/common)
SUBDIRS =
commondir = $(includedir)/dune/solvers/common
common_HEADERS = arithmetic.hh \
boxconstraint.hh \
genericvectortools.hh \
canignore.hh \
interval.hh \
numproc.hh \
permutationmanager.hh \
preconditioner.hh \
staticmatrixtools.hh
EXTRA_DIST = CMakeLists.txt
include $(top_srcdir)/am/global-rules
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_SOLVERS_COMMON_ALGORITHM_HH
#define DUNE_SOLVERS_COMMON_ALGORITHM_HH
#include <dune/common/indices.hh>
#include <dune/common/typeutilities.hh>
#include <dune/common/typetraits.hh>
#include <dune/istl/multitypeblockvector.hh>
namespace Dune {
namespace Solvers {
// Implementation of integralRangeFor
namespace Imp {
template<class ST, ST begin, ST end>
struct StaticForLoop
{
template<class F, class...Args>
static void apply(F&& f, Args&&... args)
{
f(std::integral_constant<ST, begin>(), std::forward<Args>(args)...);
StaticForLoop<ST, begin+1, end>::apply(std::forward<F>(f), std::forward<Args>(args)...);
}
};
template<class ST, ST end>
struct StaticForLoop<ST, end, end>
{
template<class F, class...Args>
static void apply(F&& f, Args&&...)
{}
};
// Overload for static ranges
template<class Index, class Begin, class End, class F, class... Args,
std::enable_if_t<IsIntegralConstant<Begin>::value and IsIntegralConstant<End>::value, int> = 0>
void integralRangeFor(Begin&& begin, End&& end, F&& f, Args&&... args)
{
static const Index begin_t = std::decay_t<Begin>::value;
static const Index end_t = std::decay_t<End>::value;
StaticForLoop<Index, begin_t, end_t>::apply(std::forward<F>(f), std::forward<Args>(args)...);
}
// Overload for dynamic ranges
template<class Index, class Begin, class End, class F, class... Args,
std::enable_if_t<not(IsIntegralConstant<Begin>::value and IsIntegralConstant<End>::value), int> = 0>
void integralRangeFor(Begin&& begin, End&& end, F&& f, Args&&... args)
{
for(Index i=begin; i != end; ++i)
f(i, std::forward<Args>(args)...);
}
}
/**
* \brief Hybrid for loop over integral range
*
* \tparam Index Raw type of used indices
* \tparam Begin Type of begin index
* \tparam End Type of end index
* \tparam F Type of functor containing the loop body
* \tparam Args Types of further arguments to the loop body
*
* \param begin Initial index
* \param end One past last index
* \param f Functor to call in each loop instance
* \param args Additional arguments to be passed to the functor
*
* This is a hybrid for loop that can work on statically and dynamically
* sized containers. The functor is called with index as first argument
* and all additional arguments. If begin and end are both of type
* std::integral_constant<*,*> than the loop is static with indices
* of the form std::integral_constant<Index, *>, otherwise the loop
* is dynamic with indices type Index.
*/
template<class Index, class Begin, class End, class F, class... Args>
void integralRangeFor(Begin&& begin, End&& end, F&& f, Args&&... args)
{
Imp::integralRangeFor<Index>(std::forward<Begin>(begin), std::forward<End>(end), std::forward<F>(f), std::forward<Args>(args)...);
}
// Implementation of hybridEquals
namespace Imp {
// Compute t1==t2 either statically or dynamically
template<class T1, class T2>
constexpr auto hybridEquals(const T1& t1, const T2& t2, PriorityTag<1>) -> decltype(T1::value, T2::value, std::integral_constant<bool,T1::value == T2::value>())
{ return {}; }
template<class T1, class T2>
constexpr auto hybridEquals(const T1& t1, const T2& t2, PriorityTag<0>)
{
return t1==t2;
}
} //end namespace Imp
/**
* \brief Hybrid equality comparison
*
* If both types have a static member value, the result of comparing
* these is returned as std::integral_constant<bool, *>. Otherwise
* the result of a runtime comparison of t1 and t2 is directly returned.
*/
template<class T1, class T2>
constexpr auto hybridEquals(const T1& t1, const T2& t2)
{
return Imp::hybridEquals(t1, t2, PriorityTag<1>());
}
// Implementation of hybridIf
namespace Imp {
template<class IfFunc, class ElseFunc>
constexpr void hybridIf(std::true_type, IfFunc&& ifFunc, ElseFunc&& elseFunc)
{
ifFunc([](auto&& x) { return std::forward<decltype(x)>(x);});
}
template<class IfFunc, class ElseFunc>
constexpr void hybridIf(std::false_type, IfFunc&& ifFunc, ElseFunc&& elseFunc)
{
elseFunc([](auto&& x) { return std::forward<decltype(x)>(x);});
}
template<class IfFunc, class ElseFunc>
constexpr void hybridIf(const bool& condition, IfFunc&& ifFunc, ElseFunc&& elseFunc)
{
if (condition)
ifFunc([](auto&& x) { return std::forward<decltype(x)>(x);});
else
elseFunc([](auto&& x) { return std::forward<decltype(x)>(x);});
}
} //end namespace Imp
/**
* \brief Hybrid if
*
* This will call either ifFunc or elseFunc depending
* on the condition. In any case a single argument
* will be passed to the called function. This will always
* be the indentity function. Passing an expression through
* this function will lead to lazy evaluation. This way both
* 'branches' can contain expressions that are only valid
* within this branch if the condition is a std::integral_constant<bool,*>.
*
* In order to do this, the passed functors must have a single
* argument of type auto.
*/
template<class Condition, class IfFunc, class ElseFunc>
constexpr void hybridIf(const Condition& condition, IfFunc&& ifFunc, ElseFunc&& elseFunc)
{
Imp::hybridIf(condition, std::forward<IfFunc>(ifFunc), std::forward<ElseFunc>(elseFunc));
}
/**
* \brief Hybrid if
*
* This provides a hybridIf with empty else clause.
*/
template<class Condition, class IfFunc>
constexpr void hybridIf(const Condition& condition, IfFunc&& ifFunc)
{
hybridIf(condition, std::forward<IfFunc>(ifFunc), [](auto&& i) {});
}
// Everything in the next namespace block is just used to implement StaticSize, HasStaticSize, hybridSize
namespace Imp {
// As a last resort try if there's a static constexpr size()
template<class T>
constexpr auto staticSize(const T*, const PriorityTag<0>&)
-> decltype(std::integral_constant<std::size_t,T::size()>())
{
return {};
}
// Try if tuple_size is implemented for class
template<class T>
constexpr auto staticSize(const T*, const PriorityTag<2>&)
-> decltype(std::integral_constant<std::size_t,std::tuple_size<T>::value>())
{
return {};
}
// Try if tuple_size is implemented for class
template<class T, int i>
constexpr auto staticSize(const Dune::FieldVector<T, i>*, const PriorityTag<3>&)
-> decltype(std::integral_constant<std::size_t,i>())
{
return {};
}
template<class T>
constexpr std::false_type hasStaticSize(const T* t, const PriorityTag<0>& p)
{
return {};
}
template<class T>
constexpr auto hasStaticSize(const T* t, const PriorityTag<1>& p)
-> decltype(staticSize(t ,PriorityTag<42>()), std::true_type())
{
return {};
}
}
/**
* \brief Check if type is a statically sized container
*
* \ingroup Utility
*
* Derives from std::true_type or std::false_type
*/
template<class T>
struct HasStaticSize :
public decltype(Imp::hasStaticSize((typename std::decay<T>::type*)(nullptr), PriorityTag<42>()))
{};
/**
* \brief Obtain size of statically sized container
*
* \ingroup Utility
*
* Derives from std::integral_constant<std::size_t, size>
*/
template<class T>
struct StaticSize :
public decltype(Imp::staticSize((typename std::decay<T>::type*)(nullptr), PriorityTag<42>()))
{};
/**
* \brief Hybrid size query
*
* \tparam T Type of container whose size is queried
*
* \param t Container whose size is queried
*
* This function is hybrid in the sense that it returns a statically
* encoded size, i.e., an integral_constant if possible and the
* dynamic result of the t.size() method otherwise.
*
* This is the static-size overload which returns the size i
* as std::integral_constant<std::size_t, i>.
*/
template<class T,
std::enable_if_t<HasStaticSize<T>::value, int> = 0>
constexpr auto hybridSize(const T& t)
{
return Imp::staticSize((T*)(nullptr), PriorityTag<42>());
}
/**
* \brief Hybrid size query
*
* \tparam T Type of container whose size is queried
*
* \param t Container whose size is queried
*
* This function is hybrid in the sense that it returns a statically
* encoded size, i.e., an integral_constant if possible and the
* dynamic result of the *.size() method otherwise.
*
* This is the dynamic-size overload which returns the result
* of t.size().
*/
template<class T,
std::enable_if_t<not HasStaticSize<T>::value, int> = 0>
constexpr auto hybridSize(const T& t)
{
return t.size();
}
/**
* \brief Hybrid for loop over sparse range
*/
template<class... T, class F>
void sparseRangeFor(const Dune::MultiTypeBlockVector<T...>& range, F&& f)
{
integralRangeFor<std::size_t>(Indices::_0, hybridSize(range), [&](auto&& i) {
f(range[i], i);
});
}
/**
* \brief Hybrid for loop over sparse range
*/
template<class Range, class F>
void sparseRangeFor(Range&& range, F&& f)
{
auto it = range.begin();
auto end = range.end();
for(; it!=end; ++it)
f(*it, it.index());
}
} // namespace Solvers
} // namespace Dune
#endif// DUNE_SOLVERS_COMMON_FORLOOP_HH