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

Merge branch 'feature/problemstat_construction' into 'master'

Allow ProblemStat to be constructed from pre-basis factory

See merge request !205
parents 43cefbd6 af1d36c3
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <amdis/Observer.hpp> #include <amdis/Observer.hpp>
#include <amdis/common/Concepts.hpp> #include <amdis/common/Concepts.hpp>
#include <amdis/common/TypeTraits.hpp> #include <amdis/common/TypeTraits.hpp>
#include <amdis/functions/ParallelGlobalBasis.hpp>
#include <amdis/gridfunctions/DiscreteFunction.hpp> #include <amdis/gridfunctions/DiscreteFunction.hpp>
#include <amdis/typetree/TreePath.hpp> #include <amdis/typetree/TreePath.hpp>
...@@ -74,12 +75,11 @@ namespace AMDiS ...@@ -74,12 +75,11 @@ namespace AMDiS
: DOFVector(Dune::wrap_or_move(FWD(basis)), op) : DOFVector(Dune::wrap_or_move(FWD(basis)), op)
{} {}
/// (3) Constructor. Forwards to (1) by creating a new basis from a dune-functions basis. /// (3) Constructor. Forwards to (1) by creating a new basis from a dune-functions pre-basis factory.
template <class GB_, template <class GV, class PBF,
REQUIRES(not Concepts::Similar<GB_,GB>), REQUIRES(Concepts::PreBasisFactory<PBF, GV, MultiIndex_t<PBF>>)>
REQUIRES(Concepts::GlobalBasis<GB_>)> DOFVector(GV const& gridView, PBF const& preBasisFactory, DataTransferOperation op = DataTransferOperation::INTERPOLATE)
DOFVector(GB_&& basis, DataTransferOperation op = DataTransferOperation::INTERPOLATE) : DOFVector(std::make_shared<GB>(gridView, preBasisFactory), op)
: DOFVector(std::make_shared<GB>(std::move(basis)), op)
{} {}
std::shared_ptr<GlobalBasis const> const& basis() const { return basis_; } std::shared_ptr<GlobalBasis const> const& basis() const { return basis_; }
...@@ -224,6 +224,10 @@ namespace AMDiS ...@@ -224,6 +224,10 @@ namespace AMDiS
DOFVector(GB&& basis, DataTransferOperation op = DataTransferOperation::INTERPOLATE) DOFVector(GB&& basis, DataTransferOperation op = DataTransferOperation::INTERPOLATE)
-> DOFVector<ParallelGlobalBasis<typename Underlying_t<GB>::PreBasis>>; -> DOFVector<ParallelGlobalBasis<typename Underlying_t<GB>::PreBasis>>;
template <class GV, class PBF>
DOFVector(GV const& gridView, PBF const& pbf, DataTransferOperation op = DataTransferOperation::INTERPOLATE)
-> DOFVector<decltype(ParallelGlobalBasis{gridView,pbf})>;
/// \brief Create a DOFVector from a basis. /// \brief Create a DOFVector from a basis.
/** /**
......
...@@ -36,14 +36,16 @@ namespace Dune ...@@ -36,14 +36,16 @@ namespace Dune
namespace AMDiS namespace AMDiS
{ {
/// A creator class for dune grids. /// A creator class for dune grids.
template <class Grid> template <class G>
struct MeshCreator struct MeshCreator
{ {
enum { dimension = Grid::dimension }; enum { dimension = G::dimension };
enum { dimworld = Grid::dimensionworld }; enum { dimworld = G::dimensionworld };
using Grid = AdaptiveGrid_t<G>;
using HostGrid = typename Grid::HostGrid;
using ctype = typename Grid::ctype; using ctype = typename Grid::ctype;
using HostGrid = typename AdaptiveGrid_t<Grid>::HostGrid;
/// Construct a new MeshCreator /// Construct a new MeshCreator
/** /**
......
...@@ -101,15 +101,27 @@ namespace AMDiS ...@@ -101,15 +101,27 @@ namespace AMDiS
adoptGrid(wrap_or_share(FWD(grid))); adoptGrid(wrap_or_share(FWD(grid)));
} }
/// \brief Constructor taking a grid and basis /// \brief Constructor taking a grid and basis.
/// Wraps both in shared pointers. /// Wraps both in shared pointers.
template <class Grid_, class Basis_> template <class Grid_, class Basis_,
class B_ = Underlying_t<Basis_>,
REQUIRES(Concepts::GlobalBasis<B_>)>
ProblemStat(std::string const& name, Grid_&& grid, Basis_&& globalBasis) ProblemStat(std::string const& name, Grid_&& grid, Basis_&& globalBasis)
: ProblemStat(name, FWD(grid)) : ProblemStat(name, FWD(grid))
{ {
adoptGlobalBasis(wrap_or_share(FWD(globalBasis))); adoptGlobalBasis(wrap_or_share(FWD(globalBasis)));
} }
/// \brief Constructor taking a grid and pre-basis factory to create a global basis
/// on the fly.
template <class Grid_, class PBF_,
class GV_ = typename Underlying_t<Grid_>::LeafGridView,
REQUIRES(Concepts::PreBasisFactory<PBF_, GV_, MultiIndex_t<PBF_>>)>
ProblemStat(std::string const& name, Grid_&& grid, PBF_ const& preBasisFactory)
: ProblemStat(name, FWD(grid))
{
adoptGlobalBasis(makeSharedPtr(ParallelGlobalBasis{grid_->leafGridView(), preBasisFactory}));
}
/// \brief Initialisation of the problem. /// \brief Initialisation of the problem.
/** /**
...@@ -511,10 +523,37 @@ namespace AMDiS ...@@ -511,10 +523,37 @@ namespace AMDiS
}; };
namespace Impl
{
template <class Grid, class B, class = void>
struct DeducedProblemTraits;
template <class Grid, class PB>
struct DeducedProblemTraits<Grid,ParallelGlobalBasis<PB>,void>
{
using type = DefaultProblemTraits<ParallelGlobalBasis<PB>>;
};
template <class G, class PBF>
struct DeducedProblemTraits<G,PBF,
std::enable_if_t<Concepts::PreBasisFactory<PBF, typename G::LeafGridView, MultiIndex_t<PBF>>>>
{
using Grid = AdaptiveGrid_t<G>;
using GridView = typename Grid::LeafGridView;
using Basis = decltype(ParallelGlobalBasis{std::declval<GridView>(),std::declval<PBF>()});
using type = DefaultProblemTraits<Basis>;
};
template <class Grid, class Basis>
using DeducedProblemTraits_t = typename DeducedProblemTraits<Grid,Basis>::type;
}
// Deduction guide // Deduction guide
template <class Grid, class GlobalBasis> template <class Grid, class Basis>
ProblemStat(std::string const& name, Grid& grid, GlobalBasis& globalBasis) ProblemStat(std::string name, Grid&& grid, Basis&& globalBasis)
-> ProblemStat<DefaultProblemTraits<GlobalBasis>>; -> ProblemStat<Impl::DeducedProblemTraits_t<Underlying_t<Grid>,Underlying_t<Basis>>>;
// mark templates as explicitly instantiated in cpp file // mark templates as explicitly instantiated in cpp file
......
...@@ -82,6 +82,15 @@ namespace AMDiS ...@@ -82,6 +82,15 @@ namespace AMDiS
); );
}; };
template <class MultiIndex>
struct PreBasisFactory
{
template <class PBF, class GV>
auto require(PBF const& pbf, GV const& gridView) -> decltype(
pbf.template makePreBasis<MultiIndex>(gridView)
);
};
} // end namespace Definition } // end namespace Definition
#endif // DOXYGEN #endif // DOXYGEN
...@@ -183,6 +192,12 @@ namespace AMDiS ...@@ -183,6 +192,12 @@ namespace AMDiS
template <class GB, class GV = typename GB::GridView> template <class GB, class GV = typename GB::GridView>
using GlobalBasis_t = models_t<Dune::Functions::Concept::GlobalBasis<GV>(GB)>; using GlobalBasis_t = models_t<Dune::Functions::Concept::GlobalBasis<GV>(GB)>;
template <class PBF, class GV, class MI = std::array<std::size_t,1>>
constexpr bool PreBasisFactory = models<Definition::PreBasisFactory<MI>(PBF,GV)>;
template <class PBF, class GV, class MI = std::array<std::size_t,1>>
using PreBasisFactory_t = models_t<Definition::PreBasisFactory<MI>(PBF,GV)>;
/** @} **/ /** @} **/
} // end namespace Concepts } // end namespace Concepts
......
...@@ -28,31 +28,43 @@ namespace AMDiS ...@@ -28,31 +28,43 @@ namespace AMDiS
template <class T> template <class T>
struct UnderlyingType struct UnderlyingType
{ {
using type = remove_cvref_t<T>; using type = T;
};
template <class T>
struct UnderlyingType<const T>
{
using type = typename UnderlyingType<T>::type;
};
template <class T>
struct UnderlyingType<T&>
{
using type = typename UnderlyingType<T>::type;
}; };
template <class T> template <class T>
struct UnderlyingType<T*> struct UnderlyingType<T*>
{ {
using type = remove_cvref_t<T>; using type = typename UnderlyingType<T>::type;
}; };
template <class T> template <class T>
struct UnderlyingType<std::reference_wrapper<T>> struct UnderlyingType<std::reference_wrapper<T>>
{ {
using type = remove_cvref_t<T>; using type = typename UnderlyingType<T>::type;
}; };
template <class T> template <class T>
struct UnderlyingType<std::shared_ptr<T>> struct UnderlyingType<std::shared_ptr<T>>
{ {
using type = remove_cvref_t<T>; using type = typename UnderlyingType<T>::type;
}; };
template <class T> template <class T>
struct UnderlyingType<std::unique_ptr<T>> struct UnderlyingType<std::unique_ptr<T>>
{ {
using type = remove_cvref_t<T>; using type = typename UnderlyingType<T>::type;
}; };
} }
...@@ -97,6 +109,12 @@ namespace AMDiS ...@@ -97,6 +109,12 @@ namespace AMDiS
return std::make_unique<TYPEOF(obj)>(FWD(obj)); return std::make_unique<TYPEOF(obj)>(FWD(obj));
} }
template <class Obj>
auto makeSharedPtr(Obj&& obj)
{
return std::make_shared<TYPEOF(obj)>(FWD(obj));
}
template <bool... b> template <bool... b>
using enable_if_all_t using enable_if_all_t
= std::enable_if_t<std::is_same_v<std::integer_sequence<bool,true,b...>, = std::enable_if_t<std::is_same_v<std::integer_sequence<bool,true,b...>,
......
...@@ -211,7 +211,7 @@ namespace AMDiS ...@@ -211,7 +211,7 @@ namespace AMDiS
using GridView = typename PreBasis::GridView; using GridView = typename PreBasis::GridView;
using size_type = std::size_t; using size_type = std::size_t;
static_assert(Node::isLeaf, "Generic NodeIdSet implemented for LeafNodes only. Provide a spcialization for your node!"); static_assert(Node::isLeaf, "Generic NodeIdSet implemented for LeafNodes only. Provide a specialization for your node!");
private: private:
static constexpr int dim = GridView::template Codim<0>::Entity::mydimension; static constexpr int dim = GridView::template Codim<0>::Entity::mydimension;
......
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
namespace AMDiS namespace AMDiS
{ {
template <class PreBasisFactory> template <class PreBasisFactory>
using MultiIndex = std::conditional_t< using MultiIndex_t = std::conditional_t<
(remove_cvref_t<PreBasisFactory>::requiredMultiIndexSize == 1), (remove_cvref_t<PreBasisFactory>::requiredMultiIndexSize == 1),
Dune::Functions::FlatMultiIndex<std::size_t>, Dune::Functions::FlatMultiIndex<std::size_t>,
Dune::ReservedVector<std::size_t, remove_cvref_t<PreBasisFactory>::requiredMultiIndexSize>>; Dune::ReservedVector<std::size_t, remove_cvref_t<PreBasisFactory>::requiredMultiIndexSize>>;
...@@ -101,20 +101,9 @@ namespace AMDiS ...@@ -101,20 +101,9 @@ namespace AMDiS
/// Construct this global basis with a preBasisFactory /// Construct this global basis with a preBasisFactory
template <class PBF> template <class PBF>
ParallelGlobalBasis(std::string const& name, GridView const& gridView, PBF&& preBasisFactory) ParallelGlobalBasis(std::string const& name, GridView const& gridView, PBF const& preBasisFactory)
: ParallelGlobalBasis(name, gridView.grid(), : ParallelGlobalBasis(name, gridView.grid(),
preBasisFactory.template makePreBasis<MultiIndex<PBF>>(gridView)) preBasisFactory.template makePreBasis<MultiIndex_t<PBF>>(gridView))
{}
/// Converting constructor from dune-functions style basis.
/**
* This will create a new ParallelGlobalBasis. The pre-basis is copied from the constructor
* argument and a new communication object is built.
*/
template <class GB_,
REQUIRES(Concepts::GlobalBasis<GB_,GridView>)>
ParallelGlobalBasis(std::string const& name, GB_&& from)
: ParallelGlobalBasis(name, from.gridView().grid(), from.preBasis())
{} {}
/// Construct this global basis with empty name /// Construct this global basis with empty name
...@@ -192,11 +181,11 @@ namespace AMDiS ...@@ -192,11 +181,11 @@ namespace AMDiS
template <class GV, class PBF> template <class GV, class PBF>
ParallelGlobalBasis(std::string const& name, GV const& gridView, PBF&& preBasisFactory) ParallelGlobalBasis(std::string const& name, GV const& gridView, PBF&& preBasisFactory)
-> ParallelGlobalBasis<decltype( -> ParallelGlobalBasis<decltype(
preBasisFactory.template makePreBasis<MultiIndex<PBF>>(gridView))>; preBasisFactory.template makePreBasis<MultiIndex_t<PBF>>(gridView))>;
template <class GV, class PBF> template <class GV, class PBF>
ParallelGlobalBasis(GV const& gridView, PBF&& preBasisFactory) ParallelGlobalBasis(GV const& gridView, PBF&& preBasisFactory)
-> ParallelGlobalBasis<decltype( -> ParallelGlobalBasis<decltype(
preBasisFactory.template makePreBasis<MultiIndex<PBF>>(gridView))>; preBasisFactory.template makePreBasis<MultiIndex_t<PBF>>(gridView))>;
} // end namespace AMDiS } // end namespace AMDiS
#ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif
#include <iostream> #include <iostream>
#include <amdis/AMDiS.hpp> #include <amdis/AMDiS.hpp>
...@@ -9,16 +7,15 @@ ...@@ -9,16 +7,15 @@
using namespace AMDiS; using namespace AMDiS;
// 1 component with polynomial degree 1
//using Grid = Dune::AlbertaGrid<GRIDDIM, WORLDDIM>;
using ElliptParam = YaspGridBasis<GRIDDIM, 1>;
using ElliptProblem = ProblemStat<ElliptParam>;
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
Environment env(argc, argv); Environment env(argc, argv);
ElliptProblem prob("ellipt"); // create a grid by inspecting the initfile parameters
Dune::YaspGrid<2> grid({1.0, 1.0}, {4u, 4u});
using namespace Dune::Functions::BasisFactory;
ProblemStat prob("ellipt", grid, lagrange<1>());
prob.initialize(INIT_ALL); prob.initialize(INIT_ALL);
// -div(A*grad(u)) + div(b*u) + c*u = f // -div(A*grad(u)) + div(b*u) + c*u = f
......
...@@ -98,7 +98,7 @@ int main(int argc, char** argv) ...@@ -98,7 +98,7 @@ int main(int argc, char** argv)
DOFVector<Basis> vec1(basis); DOFVector<Basis> vec1(basis);
// Conversion from Dune::Functions::DefaultGlobalBasis // Conversion from Dune::Functions::DefaultGlobalBasis
auto vec2 = makeDOFVector(makeBasis(gridView, preBasis)); DOFVector vec2(gridView, preBasis);
for (auto const& e : elements(gridView)) for (auto const& e : elements(gridView))
grid.mark(1, e); grid.mark(1, e);
......
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