Liebe Gitlab-Nutzer, lieber Gitlab-Nutzer, es ist nun möglich sich mittels des ZIH-Logins/LDAP an unserem Dienst anzumelden. Ein Anmelden über dieses erzeugt ein neues Konto. Das alte Konto ist über den Reiter "Standard" erreichbar. Die Administratoren

Dear Gitlab user, it is now possible to log in to our service using the ZIH login/LDAP. Logging in via this will create a new account. The old account can be accessed via the "Standard" tab. The administrators

Commit 746bb31d authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

Merge branch 'feature/data_transfer_dof_admin' into 'develop'

Add a Manager class for GridTransfer with automatic registration of DOFVectors

See merge request !52
parents 5abe55d5 084ba1ca
Pipeline #1476 passed with stage
in 20 minutes and 16 seconds
......@@ -31,6 +31,7 @@ install(FILES
GridFunctionOperator.hpp
GridFunctions.hpp
GridTransfer.hpp
GridTransferManager.hpp
Initfile.hpp
InitfileParser.hpp
LinearAlgebra.hpp
......
#pragma once
#include <vector>
#include <list>
#include <amdis/linear_algebra/DOFVectorInterface.hpp>
#include <amdis/Output.hpp>
namespace AMDiS
{
class GridTransferInterface
{
public:
virtual ~GridTransferInterface() = default;
virtual void attach(DOFVectorInterface*) = 0;
virtual void detach(DOFVectorInterface*) = 0;
virtual bool preAdapt() = 0;
virtual bool adapt() = 0;
virtual void postAdapt() = 0;
};
template <class Grid>
class GridTransfer
: public GridTransferInterface
{
using Self = GridTransfer;
public:
GridTransfer(Grid& grid)
: grid_(&grid)
{}
void bind(Grid& grid)
{
grid_ = &grid;
}
void unbind()
{
grid_ = nullptr;
}
/// Attach a data container to the grid transfer, that gets interpolated during grid change
void attach(DOFVectorInterface* vec)
virtual void attach(DOFVectorInterface* vec) override
{
data_.push_back(vec);
}
virtual void detach(DOFVectorInterface* vec) override
{
auto it = std::find(data_.begin(), data_.end(), vec);
if (it != data_.end())
data_.erase(it);
else
warning("DOFVector to detach not found");
}
/// Prepare the grid and the data for the adaption
bool preAdapt()
virtual bool preAdapt() override
{
assert(grid_ != nullptr);
mightCoarsen_ = grid_->preAdapt(); // any element might be coarsened in adapt()
for (auto* vec : data_)
for (auto* vec : this->data_)
vec->preAdapt(mightCoarsen_);
return mightCoarsen_;
}
/// do the grid adaption
bool adapt()
virtual bool adapt() override
{
assert(grid_ != nullptr);
refined_ = grid_->adapt(); // returns true if a least one entity was refined
return refined_;
}
// Perform data adaption to the new grid
void postAdapt()
virtual void postAdapt() override
{
assert(grid_ != nullptr);
if (mightCoarsen_ || refined_) {
for (auto* vec : data_)
for (auto* vec : this->data_)
vec->postAdapt(refined_);
}
grid_->postAdapt();
}
protected:
Grid* grid_;
std::vector<DOFVectorInterface*> data_;
private:
Grid* grid_ = nullptr;
std::list<DOFVectorInterface*> data_;
bool mightCoarsen_ = false;
bool refined_ = false;
};
......
#pragma once
#include <cstdint>
#include <map>
#include <memory>
#include <amdis/GridTransfer.hpp>
#include <amdis/utility/ConcurrentCache.hpp>
namespace AMDiS
{
/// Static administration class for automatic handling of DOFVectors during grid adaption
class GridTransferManager
{
template <class T1, class T2>
friend class DOFVectorBase;
using Self = GridTransferManager;
using Key = std::uintptr_t;
using Data = std::unique_ptr<GridTransferInterface>;
private:
// Constructors. Since this is a static class you cannot call any constructor.
GridTransferManager() = delete;
public:
/**
* \brief Adapts the grid according to previously set marks and performs data transfer on
* all DOFVectors associated to the given grid.
*
* This function retrieves the grid's stored GridTransfer and calls its adaptation methods.
* During this process the grid will change according to previously set grid element markings.
* All DOFVectors associated to the given grid will be interpolated to the new grid according to
* their DataTransfer member object.
*
* Takes a grid as argument. Marking of the grid needs to be performed prior to calling this.
* Returns true if the grid changed during adaptation.
**/
template <class Grid>
static bool adapt(Grid& grid)
{
auto gridTransfer = GridTransferManager::gridTransfer(grid);
bool adapted = gridTransfer.preAdapt();
adapted |= gridTransfer.adapt();
gridTransfer.postAdapt();
return adapted;
}
/// Returns the GridTransfer corresponding to a Grid, to be used during the adaptation cycle
template <class Grid>
static GridTransfer<Grid>& gridTransfer(Grid& grid)
{
GridTransfer<Grid>* gridTransfer
= dynamic_cast<GridTransfer<Grid>*>(Self::gridTransferInterface(grid));
gridTransfer->bind(grid);
return *gridTransfer;
}
private:
// DOFVector registration methods. They are called automaticly by the DOFVectors.
template <class Vec>
static void attach(Vec& vec)
{
auto const& grid = vec.basis().gridView().grid();
Self::gridTransferInterface(grid)->attach(&vec);
}
template <class Vec>
static void detach(Vec& vec)
{
auto const& grid = vec.basis().gridView().grid();
Self::gridTransferInterface(grid)->detach(&vec);
}
// Returns the GridTransferInterface class,
// used for attaching and detaching DOFVectors to a GridTransfer
template <class Grid>
static GridTransferInterface* gridTransferInterface(Grid const &grid)
{
Key key = Key(&grid);
auto& gridTransferInterfaceUniquePtr = GridTransferCache::get(key, [&](Key const&)
{
return std::make_unique<GridTransfer<Grid>>();
});
return gridTransferInterfaceUniquePtr.get();
}
private:
// Associate to each Grid (represented as address) a GridTransfer
using GridTransferCache = ConcurrentCache< Key, Data, StaticLockedPolicy, std::map<Key, Data> >;
};
} // end namespace AMDiS
......@@ -18,7 +18,6 @@
#include <amdis/DirichletBC.hpp>
//#include <amdis/Estimator.hpp>
#include <amdis/Flag.hpp>
#include <amdis/GridTransfer.hpp>
#include <amdis/Initfile.hpp>
#include <amdis/LinearAlgebra.hpp>
#include <amdis/LinearSolvers.hpp>
......@@ -347,12 +346,6 @@ namespace AMDiS
setGrid(Dune::stackobject_to_shared_ptr(grid));
}
void addAdaptionData(DOFVectorInterface* vec)
{
assert(bool(gridTransfer_));
gridTransfer_->attach(vec);
}
void addMarker(std::shared_ptr<Marker<Grid>> const& marker)
{
marker_.push_back(marker);
......@@ -384,7 +377,6 @@ namespace AMDiS
void adoptGrid(std::shared_ptr<Grid> const& grid)
{
grid_ = grid;
gridTransfer_ = std::make_shared<GridTransfer<Grid>>(*grid_);
Parameters::get(name_ + "->mesh", gridName_);
}
......@@ -421,9 +413,6 @@ namespace AMDiS
/// Grid of this problem.
std::shared_ptr<Grid> grid_;
/// Handling the adaption of the grid
std::shared_ptr<GridTransfer<Grid>> gridTransfer_;
/// Name of the grid
std::string gridName_ = "mesh";
......
......@@ -10,6 +10,7 @@
#include <amdis/AdaptInfo.hpp>
#include <amdis/FileWriter.hpp>
#include <amdis/GridFunctionOperator.hpp>
#include <amdis/GridTransferManager.hpp>
#include <amdis/LocalAssembler.hpp>
#include <amdis/common/Loops.hpp>
......@@ -37,7 +38,6 @@ void ProblemStat<Traits>::initialize(
adoptFlag.isSet(INIT_SYSTEM) ||
adoptFlag.isSet(INIT_FE_SPACE))) {
grid_ = adoptProblem->grid_;
gridTransfer_ = adoptProblem->gridTransfer_;
}
}
......@@ -123,7 +123,6 @@ void ProblemStat<Traits>::createGrid()
{
Parameters::get(name_ + "->mesh", gridName_);
grid_ = MeshCreator<Grid>::create(gridName_);
gridTransfer_ = std::make_shared<GridTransfer<Grid>>(*grid_);
msg("Create grid:");
msg("#elements = {}" , grid_->size(0));
......@@ -175,10 +174,6 @@ void ProblemStat<Traits>::createMatricesAndVectors()
solution_ = std::make_shared<SystemVector>(*globalBasis_, INTERPOLATE);
rhs_ = std::make_shared<SystemVector>(*globalBasis_, NO_OPERATION);
assert(bool(gridTransfer_));
gridTransfer_->attach(solution_.get());
gridTransfer_->attach(rhs_.get());
auto localView = globalBasis_->localView();
AMDiS::forEachNode_(localView.tree(), [&,this](auto const& node, auto treePath)
{
......@@ -333,11 +328,8 @@ adaptGrid(AdaptInfo& adaptInfo)
{
Dune::Timer t;
bool adapted = gridTransfer_->preAdapt();
adapted |= gridTransfer_->adapt(); // NOTE: |= does not short-circuit and works with bools as ||=
if (adapted)
globalBasis_->update(gridView());
gridTransfer_->postAdapt();
bool adapted = GridTransferManager::adapt(*grid_);
globalBasis_->update(gridView());
msg("adaptGrid needed {} seconds", t.elapsed());
return adapted ? MESH_ADAPTED : Flag(0);
......
#pragma once
#include <cmath>
#include <utility>
#include <dune/functions/functionspacebases/sizeinfo.hh>
#include <amdis/DataTransfer.hpp>
#include <amdis/GridTransferManager.hpp>
#include <amdis/LocalAssemblerList.hpp>
#include <amdis/common/Math.hpp>
#include <amdis/common/ScalarTypes.hpp>
......@@ -52,18 +54,47 @@ namespace AMDiS
, dataTransfer_(DataTransferFactory::create(op, basis))
{
compress();
GridTransferManager::attach(*this);
operators_.init(basis);
}
DOFVectorBase(Self const&) = default;
DOFVectorBase(Self&&) = default;
/// Copy constructor
DOFVectorBase(Self const& that)
: basis_(that.basis_)
, backend_(that.backend_)
, elementVector_(that.elementVector_)
, operators_(that.operators_)
, dataTransfer_(that.dataTransfer_)
{
GridTransferManager::attach(*this);
}
/// Move constructor
DOFVectorBase(Self&& that)
: basis_(std::move(that.basis_))
, backend_(std::move(that.backend_))
, elementVector_(std::move(that.elementVector_))
, operators_(std::move(that.operators_))
, dataTransfer_(std::move(that.dataTransfer_))
{
GridTransferManager::attach(*this);
}
/// Destructor
virtual ~DOFVectorBase() override
{
GridTransferManager::detach(*this);
}
/// Copy assignment operator
Self& operator=(Self const& that)
{
GridTransferManager::detach(*this);
basis_ = that.basis_;
backend_.resize(that.size());
backend_ = that.backend_;
dataTransfer_ = that.dataTransfer_;
GridTransferManager::attach(*this);
return *this;
}
......
......@@ -7,6 +7,7 @@
#include <dune/functions/functionspacebases/powerbasis.hh>
#include <dune/functions/functionspacebases/lagrangebasis.hh>
#include <amdis/GridTransferManager.hpp>
#include <amdis/LinearAlgebra.hpp>
#include "Tests.hpp"
......@@ -41,26 +42,41 @@ int main(int argc, char** argv)
Dune::FieldVector<double, 2> L; L = 1.0;
auto s = Dune::filledArray<2>(1);
Dune::YaspGrid<2> grid(L, s);
auto const& gridView = grid.leafGridView();
// create basis
auto basis = makeBasis(grid.leafGridView(),
auto basis = makeBasis(gridView,
composite(power<2>(lagrange<2>(), flatInterleaved()), lagrange<1>(), flatLexicographic()));
using Basis = decltype(basis);
DOFVector<Basis> vec1(basis);
test_dofvector(basis, vec1);
DOFVector<Basis, float> vec2(basis);
test_dofvector(basis, vec2);
{
DOFVector<Basis> vec1(basis);
test_dofvector(basis, vec1);
DOFVector<Basis, float> vec2(basis);
test_dofvector(basis, vec2);
auto vec3 = makeDOFVector(basis);
test_dofvector(basis, vec3);
auto vec3 = makeDOFVector(basis);
test_dofvector(basis, vec3);
auto vec4 = makeDOFVector<float>(basis);
test_dofvector(basis, vec4);
auto vec4 = makeDOFVector<float>(basis);
test_dofvector(basis, vec4);
#if DUNE_HAVE_CXX_CLASS_TEMPLATE_ARGUMENT_DEDUCTION
DOFVector vec5(basis);
test_dofvector(basis, vec5);
DOFVector vec5(basis);
test_dofvector(basis, vec5);
#endif
}
\ No newline at end of file
}
// test GridTransferManager registration
{
DOFVector<Basis> vec1(basis);
test_dofvector(basis, vec1);
for (auto const& e : elements(gridView))
grid.mark(1, e);
GridTransferManager::adapt(grid);
AMDIS_TEST_EQ(vec1.size(), basis.dimension());
}
report_errors();
}
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