Commit 5d6a1f99 authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

Rewriting adaptive grid

parent c03faa46
...@@ -26,20 +26,35 @@ dune-2.6 ubuntu-18.04 clang-6-17: ...@@ -26,20 +26,35 @@ dune-2.6 ubuntu-18.04 clang-6-17:
- dunecontrol --current make -j4 examples - dunecontrol --current make -j4 examples
dune-git debian-10 gcc-8-17: .dune-git:
image: registry.dune-project.org/docker/ci/dune:git-debian-10-gcc-8-17 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/staging/dune-typetree.git
- duneci-install-module https://gitlab.dune-project.org/staging/dune-functions.git
script: script:
- duneci-standard-test - duneci-standard-test
- dunecontrol --current make -j4 examples - dunecontrol --current make -j4 examples
dune-git debian-10 gcc-8-17:
extends: .dune-git
image: registry.dune-project.org/docker/ci/debian:10
variables:
DUNECI_TOOLCHAIN: gcc-8-17
dune-git debian-9 gcc-6-14: dune-git debian-9 gcc-6-14:
image: registry.dune-project.org/docker/ci/dune:git-debian-9-gcc-6-14 extends: .dune-git
script: image: registry.dune-project.org/docker/ci/debian:9
- duneci-standard-test variables:
- dunecontrol --current make -j4 examples DUNECI_TOOLCHAIN: gcc-6-14
dune-git ubuntu-18.04 clang-6-17: dune-git ubuntu-18.04 clang-6-17:
image: registry.dune-project.org/docker/ci/dune:git-ubuntu-18.04-clang-6-17 extends: .dune-git
script: image: registry.dune-project.org/docker/ci/ubuntu:18.04
- duneci-standard-test variables:
- dunecontrol --current make -j4 examples DUNECI_TOOLCHAIN: clang-6-17
This diff is collapsed.
...@@ -65,7 +65,7 @@ namespace AMDiS ...@@ -65,7 +65,7 @@ namespace AMDiS
public: public:
/// Constructor. Stores the shared_ptr of the basis and creates a new DataTransfer. /// Constructor. Stores the shared_ptr of the basis and creates a new DataTransfer.
DOFVector(std::shared_ptr<GB> basis, DOFVector(std::shared_ptr<GB> const& basis,
DataTransferOperation op = DataTransferOperation::INTERPOLATE) DataTransferOperation op = DataTransferOperation::INTERPOLATE)
: Super(basis) : Super(basis)
, Obs(basis) , Obs(basis)
......
...@@ -43,10 +43,11 @@ namespace AMDiS ...@@ -43,10 +43,11 @@ namespace AMDiS
enum { dimworld = Grid::dimensionworld }; enum { dimworld = Grid::dimensionworld };
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
/** /**
* \param name The name of the mesh used in the initifile * \param name The name of the mesh used in the initfile
**/ **/
MeshCreator(std::string const& name) MeshCreator(std::string const& name)
: name_(name) : name_(name)
...@@ -64,11 +65,11 @@ namespace AMDiS ...@@ -64,11 +65,11 @@ namespace AMDiS
* *
* Otherwise tries to create a grid depending on the grid type. * Otherwise tries to create a grid depending on the grid type.
**/ **/
std::shared_ptr<AdaptiveGrid<Grid>> create() const std::shared_ptr<Grid> create() const
{ {
auto filename = Parameters::get<std::string>(name_ + "->macro file name"); auto filename = Parameters::get<std::string>(name_ + "->macro file name");
auto structured = Parameters::get<std::string>(name_ + "->structured"); auto structured = Parameters::get<std::string>(name_ + "->structured");
std::shared_ptr<Grid> gridPtr; std::unique_ptr<HostGrid> gridPtr;
if (filename) { if (filename) {
// read a macro file // read a macro file
gridPtr = create_unstructured_grid(filename.value()); gridPtr = create_unstructured_grid(filename.value());
...@@ -83,26 +84,26 @@ namespace AMDiS ...@@ -83,26 +84,26 @@ namespace AMDiS
} }
} else { } else {
// decide by inspecting the grid type how to create the grid // decide by inspecting the grid type how to create the grid
gridPtr = create_by_gridtype<Grid>(Dune::PriorityTag<42>{}); gridPtr = create_by_gridtype<HostGrid>(Dune::PriorityTag<42>{});
} }
return AdaptiveGrid<Grid>::instance(gridPtr); return construct(std::move(gridPtr));
} }
/// Create a structured cube grid /// Create a structured cube grid
std::unique_ptr<Grid> create_cube_grid() const std::unique_ptr<HostGrid> create_cube_grid() const
{ {
return create_structured_grid([](auto&& lower, auto&& upper, auto&& numCells) return create_structured_grid([](auto&& lower, auto&& upper, auto&& numCells)
{ {
return Dune::StructuredGridFactory<Grid>::createCubeGrid(lower, upper, numCells); return Dune::StructuredGridFactory<HostGrid>::createCubeGrid(lower, upper, numCells);
}); });
} }
/// Create a structured simplex grid /// Create a structured simplex grid
std::unique_ptr<Grid> create_simplex_grid() const std::unique_ptr<HostGrid> create_simplex_grid() const
{ {
return create_structured_grid([](auto&& lower, auto&& upper, auto&& numCells) return create_structured_grid([](auto&& lower, auto&& upper, auto&& numCells)
{ {
return Dune::StructuredGridFactory<Grid>::createSimplexGrid(lower, upper, numCells); return Dune::StructuredGridFactory<HostGrid>::createSimplexGrid(lower, upper, numCells);
}); });
} }
...@@ -119,9 +120,20 @@ namespace AMDiS ...@@ -119,9 +120,20 @@ namespace AMDiS
} }
private: private:
static std::shared_ptr<Grid> construct(std::unique_ptr<Grid> hostGrid)
{
return std::move(hostGrid);
}
template <class HG>
static std::shared_ptr<Grid> construct(std::unique_ptr<HG> hostGrid)
{
return std::make_shared<Grid>(std::move(hostGrid));
}
// use the structured grid factory to create the grid // use the structured grid factory to create the grid
template <class Size = unsigned int, class Factory> template <class Size = unsigned int, class Factory>
std::unique_ptr<Grid> create_structured_grid(Factory factory) const std::unique_ptr<HostGrid> create_structured_grid(Factory factory) const
{ {
// Lower left corner of the domain // Lower left corner of the domain
Dune::FieldVector<ctype,int(dimworld)> lower(0); Dune::FieldVector<ctype,int(dimworld)> lower(0);
...@@ -137,16 +149,16 @@ namespace AMDiS ...@@ -137,16 +149,16 @@ namespace AMDiS
} }
// read a filename from `[meshName]->macro file name` and determine from the extension the fileformat // read a filename from `[meshName]->macro file name` and determine from the extension the fileformat
std::unique_ptr<Grid> create_unstructured_grid(std::string const& filename) const std::unique_ptr<HostGrid> create_unstructured_grid(std::string const& filename) const
{ {
filesystem::path fn(filename); filesystem::path fn(filename);
auto ext = fn.extension(); auto ext = fn.extension();
if (ext == ".msh") { if (ext == ".msh") {
return read_gmsh_file<Grid>(filename, Dune::PriorityTag<42>{}); return read_gmsh_file<HostGrid>(filename, Dune::PriorityTag<42>{});
} }
else if (ext == ".1d" || ext == ".2d" || ext == ".3d" || ext == ".amc") { else if (ext == ".1d" || ext == ".2d" || ext == ".3d" || ext == ".amc") {
return read_alberta_file<Grid>(filename, Dune::PriorityTag<42>{}); return read_alberta_file<HostGrid>(filename, Dune::PriorityTag<42>{});
} }
else { else {
error_exit("Cannot read grid file. Unknown file extension."); error_exit("Cannot read grid file. Unknown file extension.");
...@@ -160,7 +172,7 @@ namespace AMDiS ...@@ -160,7 +172,7 @@ namespace AMDiS
std::declval<std::shared_ptr<Dune::BoundarySegment<GridType::dimension, GridType::dimensionworld> >>()) ); std::declval<std::shared_ptr<Dune::BoundarySegment<GridType::dimension, GridType::dimensionworld> >>()) );
// use GmshReader if GridFactory supports insertBoundarySegments // use GmshReader if GridFactory supports insertBoundarySegments
template <class GridType = Grid, template <class GridType = HostGrid,
REQUIRES(Dune::Std::is_detected<SupportsGmshReader, GridType>::value)> REQUIRES(Dune::Std::is_detected<SupportsGmshReader, GridType>::value)>
std::unique_ptr<GridType> read_gmsh_file(std::string const& filename, Dune::PriorityTag<1>) const std::unique_ptr<GridType> read_gmsh_file(std::string const& filename, Dune::PriorityTag<1>) const
{ {
...@@ -169,7 +181,7 @@ namespace AMDiS ...@@ -169,7 +181,7 @@ namespace AMDiS
} }
// fallback if GmshReader cannot be used // fallback if GmshReader cannot be used
template <class GridType = Grid> template <class GridType = HostGrid>
std::unique_ptr<GridType> read_gmsh_file(std::string const& filename, Dune::PriorityTag<0>) const std::unique_ptr<GridType> read_gmsh_file(std::string const& filename, Dune::PriorityTag<0>) const
{ {
error_exit("Gmsh reader not supported for this grid type!"); error_exit("Gmsh reader not supported for this grid type!");
...@@ -183,7 +195,7 @@ namespace AMDiS ...@@ -183,7 +195,7 @@ namespace AMDiS
using IsAlbertaGrid = decltype(std::declval<GridType>().alberta2dune(0,0)); using IsAlbertaGrid = decltype(std::declval<GridType>().alberta2dune(0,0));
// construct the albertagrid directly from a filename // construct the albertagrid directly from a filename
template <class GridType = Grid, template <class GridType = HostGrid,
REQUIRES(GridType::dimensionworld == DIM_OF_WORLD), REQUIRES(GridType::dimensionworld == DIM_OF_WORLD),
REQUIRES(Dune::Std::is_detected<IsAlbertaGrid, GridType>::value)> REQUIRES(Dune::Std::is_detected<IsAlbertaGrid, GridType>::value)>
std::unique_ptr<GridType> read_alberta_file(std::string const& filename, Dune::PriorityTag<3>) const std::unique_ptr<GridType> read_alberta_file(std::string const& filename, Dune::PriorityTag<3>) const
...@@ -192,7 +204,7 @@ namespace AMDiS ...@@ -192,7 +204,7 @@ namespace AMDiS
} }
// use a gridfactory and the generic AlbertaReader // use a gridfactory and the generic AlbertaReader
template <class GridType = Grid, template <class GridType = HostGrid,
REQUIRES(GridType::dimensionworld == DIM_OF_WORLD)> REQUIRES(GridType::dimensionworld == DIM_OF_WORLD)>
std::unique_ptr<GridType> read_alberta_file(std::string const& filename, Dune::PriorityTag<2>) const std::unique_ptr<GridType> read_alberta_file(std::string const& filename, Dune::PriorityTag<2>) const
{ {
...@@ -205,7 +217,7 @@ namespace AMDiS ...@@ -205,7 +217,7 @@ namespace AMDiS
} }
// error if WORLDDIM not the same as Grid::dimensionworld // error if WORLDDIM not the same as Grid::dimensionworld
template <class GridType = Grid, template <class GridType = HostGrid,
REQUIRES(GridType::dimensionworld != DIM_OF_WORLD)> REQUIRES(GridType::dimensionworld != DIM_OF_WORLD)>
std::unique_ptr<GridType> read_alberta_file(std::string const& filename, Dune::PriorityTag<1>) const std::unique_ptr<GridType> read_alberta_file(std::string const& filename, Dune::PriorityTag<1>) const
{ {
...@@ -225,19 +237,19 @@ namespace AMDiS ...@@ -225,19 +237,19 @@ namespace AMDiS
#if HAVE_ALBERTA #if HAVE_ALBERTA
// albertagrid -> simplex // albertagrid -> simplex
template <class GridType = Grid, template <class GridType = HostGrid,
REQUIRES(Dune::Std::is_detected<IsAlbertaGrid, GridType>::value)> REQUIRES(Dune::Std::is_detected<IsAlbertaGrid, GridType>::value)>
std::unique_ptr<GridType> create_by_gridtype(Dune::PriorityTag<3>) const std::unique_ptr<GridType> create_by_gridtype(Dune::PriorityTag<3>) const
{ {
return create_structured_grid([](auto&& lower, auto&& upper, auto&& numCells) return create_structured_grid([](auto&& lower, auto&& upper, auto&& numCells)
{ {
return MacroGridFactory<Grid>::createSimplexGrid(lower, upper, numCells); return MacroGridFactory<GridType>::createSimplexGrid(lower, upper, numCells);
}); });
} }
#endif #endif
// yasp grid -> cube // yasp grid -> cube
template <class GridType = Grid, template <class GridType = HostGrid,
class = typename GridType::YGrid> class = typename GridType::YGrid>
std::unique_ptr<GridType> create_by_gridtype(Dune::PriorityTag<2>) const std::unique_ptr<GridType> create_by_gridtype(Dune::PriorityTag<2>) const
{ {
...@@ -250,27 +262,27 @@ namespace AMDiS ...@@ -250,27 +262,27 @@ namespace AMDiS
} }
template <int dim, class ct> template <int dim, class ct>
std::unique_ptr<Grid> create_yaspgrid(Types<Dune::YaspGrid<dim,Dune::EquidistantCoordinates<ct,dim>>>, std::unique_ptr<HostGrid> create_yaspgrid(Types<Dune::YaspGrid<dim,Dune::EquidistantCoordinates<ct,dim>>>,
int overlap, std::bitset<dimension> const& per) const int overlap, std::bitset<dimension> const& per) const
{ {
return create_structured_grid<int>([&](auto&& /*lower*/, auto&& upper, std::array<int,dimension> const& numCells) return create_structured_grid<int>([&](auto&& /*lower*/, auto&& upper, std::array<int,dimension> const& numCells)
{ {
return std::make_unique<Grid>(upper, numCells, per, overlap); return std::make_unique<HostGrid>(upper, numCells, per, overlap);
}); });
} }
template <int dim, class ct> template <int dim, class ct>
std::unique_ptr<Grid> create_yaspgrid(Types<Dune::YaspGrid<dim,Dune::EquidistantOffsetCoordinates<ct,dim>>>, std::unique_ptr<HostGrid> create_yaspgrid(Types<Dune::YaspGrid<dim,Dune::EquidistantOffsetCoordinates<ct,dim>>>,
int overlap, std::bitset<dimension> const& per) const int overlap, std::bitset<dimension> const& per) const
{ {
return create_structured_grid<int>([&](auto&& lower, auto&& upper, std::array<int,dimension> const& numCells) return create_structured_grid<int>([&](auto&& lower, auto&& upper, std::array<int,dimension> const& numCells)
{ {
return std::make_unique<Grid>(lower, upper, numCells, per, overlap); return std::make_unique<HostGrid>(lower, upper, numCells, per, overlap);
}); });
} }
template <int dim, class ct> template <int dim, class ct>
std::unique_ptr<Grid> create_yaspgrid(Types<Dune::YaspGrid<dim,Dune::TensorProductCoordinates<ct,dim>>>, std::unique_ptr<HostGrid> create_yaspgrid(Types<Dune::YaspGrid<dim,Dune::TensorProductCoordinates<ct,dim>>>,
int overlap, std::bitset<dimension> const& per) const int overlap, std::bitset<dimension> const& per) const
{ {
error_exit("MeshCreator cannot create YaspGrid with TensorProductCoordinates."); error_exit("MeshCreator cannot create YaspGrid with TensorProductCoordinates.");
...@@ -280,7 +292,7 @@ namespace AMDiS ...@@ -280,7 +292,7 @@ namespace AMDiS
#if HAVE_DUNE_SPGRID #if HAVE_DUNE_SPGRID
// spgrid -> cube // spgrid -> cube
template <class GridType = Grid, template <class GridType = HostGrid,
class = typename GridType::ReferenceCube, class = typename GridType::ReferenceCube,
class = typename GridType::MultiIndex> class = typename GridType::MultiIndex>
std::unique_ptr<GridType> create_by_gridtype(Dune::PriorityTag<1>) const std::unique_ptr<GridType> create_by_gridtype(Dune::PriorityTag<1>) const
...@@ -294,7 +306,7 @@ namespace AMDiS ...@@ -294,7 +306,7 @@ namespace AMDiS
#endif #endif
// final fallback // final fallback
template <class GridType = Grid> template <class GridType = HostGrid>
std::unique_ptr<GridType> create_by_gridtype(Dune::PriorityTag<0>) const std::unique_ptr<GridType> create_by_gridtype(Dune::PriorityTag<0>) const
{ {
error_exit("Don't know how to create the grid."); error_exit("Don't know how to create the grid.");
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#include <memory> #include <memory>
#include <type_traits> #include <type_traits>
#include <dune/common/typeutilities.hh>
#include <amdis/common/ConceptsBase.hpp> #include <amdis/common/ConceptsBase.hpp>
#include <amdis/Output.hpp> #include <amdis/Output.hpp>
...@@ -12,135 +14,128 @@ namespace AMDiS ...@@ -12,135 +14,128 @@ namespace AMDiS
{ {
namespace Impl namespace Impl
{ {
// Forward declaration // forward declaration
template <class Event> template <class Event>
class SignalInterface; class ObserverInterface;
template <class Event> template <class Event>
class ObserverInterface class SignalBase
{ {
public: public:
virtual ~ObserverInterface() = default; /// Attaches an observer to this class. This method will be called by all observers with
/// with themselves as argument.
/// Attach the observer to a subject. It will then receive notifications from the subject when void attachObserver(ObserverInterface<Event>* o) const
/// an event of type Event it triggered.
void attach(std::shared_ptr<SignalInterface<Event>> const& subject)
{ {
subject->attachObserver(this); observers_.push_back(o);
} }
/// Detach the observer from the subject. It will then no longer receive notifications. This /// Detaches an observer to this class. This method will be called by all observers with
/// must be called before the observer is deleted. /// with themselves as argument.
void detach(std::shared_ptr<SignalInterface<Event>> const& subject) void detachObserver(ObserverInterface<Event>* o) const
{ {
subject->detachObserver(this); auto it = std::find(observers_.begin(), observers_.end(), o);
if (it != observers_.end())
observers_.erase(it);
} }
/// This method will be called by the subject when triggering the event. /// Notify all observers that have called attachObserver but have not called detachObserver
virtual void update(Event const&) void notify(Event const& e) const
{ {
error_exit("Method must be overridden by derived class"); for (ObserverInterface<Event>* o : observers_)
o->update(e);
} }
};
template <class Event>
class SignalInterface
{
public:
virtual ~SignalInterface() = default;
/// Attaches an observer to this class. This method will be called by all observers with private:
/// with themselves as argument. /// List of observers that need to be notified in case of an event
virtual void attachObserver(ObserverInterface<Event>*) = 0; // NOTE: this list is mutable, since the notification list itself is not part
// of the internal state of the object signaling the event.
/// Detaches an observer to this class. This method will be called by all observers with mutable std::list<ObserverInterface<Event>*> observers_;
/// with themselves as argument.
virtual void detachObserver(ObserverInterface<Event>*) = 0;
/// Notify all observers that have called attachObserver but have not called detachObserver
virtual void notify(Event const&) const = 0;
}; };
template <class Event> template <class Event>
class SignalsImpl class ObserverInterface
: virtual public SignalInterface<Event>
{ {
public: public:
virtual ~SignalsImpl() = default; virtual ~ObserverInterface() = default;
void attachObserver(ObserverInterface<Event>* o) override /// Attach the observer to a subject. It will then receive notifications from the subject when
/// an event of type Event it triggered.
void attach(std::shared_ptr<SignalBase<Event> const> const& subject)
{ {
observers_.push_back(o); if (bool(subject))
subject->attachObserver(this);
} }
void detachObserver(ObserverInterface<Event>* o) override /// Detach the observer from the subject. It will then no longer receive notifications. This
/// must be called before the observer is deleted.
void detach(std::shared_ptr<SignalBase<Event> const> const& subject)
{ {
auto it = std::find(observers_.begin(), observers_.end(), o); if (bool(subject))
if (it != observers_.end()) subject->detachObserver(this);
observers_.erase(it);
} }
void notify(Event const& e) const override /// This method will be called by the subject when triggering the event.
virtual void update(Event const&)
{ {
for (ObserverInterface<Event>* o : observers_) error_exit("Method must be overridden by derived class");
o->update(e);
} }
private:
std::list<ObserverInterface<Event>*> observers_;
}; };
template <class Event>
class SignalsDummy
: virtual public SignalInterface<Event>
{
public:
virtual ~SignalsDummy() = default;
void attachObserver(ObserverInterface<Event>* o) override {}
void detachObserver(ObserverInterface<Event>* o) override {}
void notify(Event const& e) const override {}
};
template <class Event> template <class Event>
class ObserverImpl class ObserverBase
: virtual public ObserverInterface<Event> : virtual public ObserverInterface<Event>
{ {
using Self = ObserverImpl; using Self = ObserverBase;
ObserverImpl() private:
: subject_(std::make_shared<SignalsDummy<Event>>()) ObserverBase() = default;
{}
public: // use subject if Event is handled directly
ObserverImpl(std::shared_ptr<SignalInterface<Event>> subject) template <class S,
REQUIRES(std::is_base_of<SignalBase<Event>, S>::value)>
ObserverBase(std::shared_ptr<S const> subject, Dune::PriorityTag<2>)
: subject_(std::move(subject)) : subject_(std::move(subject))
{ {
this->attach(subject_); this->attach(subject_);
} }
// Get next subject in hierarchy if Event is not handled // get next subject in hierarchy if Event is not handled
template <class Subject, template <class Observer,
REQUIRES(!std::is_convertible<std::shared_ptr<Subject>, std::shared_ptr<SignalInterface<Event>>>::value)> class = void_t<decltype(std::declval<Observer>().subject_)> >
ObserverImpl(std::shared_ptr<Subject> subject) ObserverBase(std::shared_ptr<Observer const> const& o, Dune::PriorityTag<1>)
: Self(subject->getSubject()) : ObserverBase(o->subject_)
{}
// non-observable type
template <class T>
ObserverBase(std::shared_ptr<T const> const& other, Dune::PriorityTag<0>)
{
/* fallback implementation */
}
public:
template <class T>