diff --git a/src/amdis/BackupRestore.hpp b/src/amdis/BackupRestore.hpp new file mode 100644 index 0000000000000000000000000000000000000000..7efe8e19f6d7d51ed81603a845a4724ddde06998 --- /dev/null +++ b/src/amdis/BackupRestore.hpp @@ -0,0 +1,177 @@ +#pragma once + +#include <cstdint> +#include <fstream> +#include <memory> +#include <vector> + +#include <dune/grid/common/backuprestore.hh> +#include <dune/grid/common/gridfactory.hh> + +namespace AMDiS +{ + // Fallback Implementation for Grids not supporting direct BackupRestore + template <class Grid> + class BackupRestoreByGridFactory + { + template <class GridView> + class Writer + { + enum { dim = GridView::dimension }; + enum { dow = GridView::dimensionworld }; + + using ct = typename GridView::ctype; + + public: + Writer(GridView const& gv) + : gridView_(gv) + { + std::int64_t num = 0; + indexMap_.resize(gridView_.size(dim)); + auto const& indexSet = gridView_.indexSet(); + for (auto const& vertex : vertices(gridView_)) + indexMap_[indexSet.index(vertex)] = std::int64_t(num++); + } + + void writeVertices(std::ostream& out) const + { + for (auto const& vertex : vertices(gridView_)) { + auto v = vertex.geometry().center(); + out.write((char*)&v, dow*sizeof(ct)); + } + } + + void writeElements(std::ostream& out) const + { + auto const& indexSet = gridView_.indexSet(); + + std::vector<std::int64_t> connectivity; + connectivity.reserve(8); + for (auto const& e : elements(gridView_)) { + unsigned int id = e.type().id(); + out.write((char*)&id, sizeof(unsigned int)); + + connectivity.clear(); + for (unsigned int j = 0; j < e.subEntities(dim); ++j) + connectivity.emplace_back(indexMap_[indexSet.subIndex(e,j,dim)]); + + out.write((char*)connectivity.data(), connectivity.size()*sizeof(std::int64_t)); + } + } + + private: + GridView gridView_; + std::vector<std::int64_t> indexMap_; + }; + + class Reader + { + enum { dim = Grid::dimension }; + enum { dow = Grid::dimensionworld }; + + using ct = typename Grid::ctype; + using Factory = Dune::GridFactory<Grid>; + using GlobalCoordinates = Dune::FieldVector<ct,dow>; + + public: + Reader(Factory& factory, std::istream& in) + : factory_(factory) + { + in.read((char*)&numElements_, sizeof(std::int64_t)); + in.read((char*)&numVertices_, sizeof(std::int64_t)); + } + + void readVertices(std::istream& in) const + { + GlobalCoordinates p; + for (std::int64_t i = 0; i < numVertices_; ++i) { + in.read((char*)&p[0], dow*sizeof(ct)); + factory_.insertVertex(p); + } + } + + void readElements(std::istream& in) const + { + std::vector<std::int64_t> connectivity(8); + std::vector<unsigned int> vertices; + vertices.reserve(8); + + for (std::int64_t i = 0; i < numElements_; ++i) { + unsigned int id = 0; + in.read((char*)&id, sizeof(unsigned int)); + + Dune::GeometryType type(id,dim); + auto refElem = Dune::referenceElement<ct,dim>(type); + + in.read((char*)connectivity.data(), refElem.size(dim)*sizeof(std::int64_t)); + vertices.clear(); + std::copy_n(connectivity.begin(),refElem.size(dim),std::back_inserter(vertices)); + + factory_.insertElement(type, vertices); + } + } + + private: + Factory& factory_; + std::int64_t numElements_ = 0; + std::int64_t numVertices_ = 0; + }; + + public: + /// \brief Write a hierarchic grid to disk + template <class GridView> + static void backup(GridView const& gv, std::string const& filename) + { + std::ofstream out(filename, std::ios::binary); + backup(gv,out); + } + + /// \brief write a hierarchic grid into a stream + template <class GridView> + static void backup(GridView const& gv, std::ostream& out) + { + std::int32_t dim = GridView::dimension; + std::int32_t dow = GridView::dimensionworld; + std::int64_t num_elements = gv.size(0); + std::int64_t num_vertices = gv.size(dim); + + out.write((char*)&dim, sizeof(std::int32_t)); + out.write((char*)&dow, sizeof(std::int32_t)); + out.write((char*)&num_elements, sizeof(std::int64_t)); + out.write((char*)&num_vertices, sizeof(std::int64_t)); + + Writer<GridView> writer(gv); + writer.writeVertices(out); + writer.writeElements(out); + } + + /// \brief read a hierarchic grid from disk + static Grid* restore(std::string const& filename) + { + std::ifstream in(filename, std::ios::binary); + return restore(in); + } + + /// \brief read a hierarchic grid from a stream + static Grid* restore(std::istream& in) + { + Dune::GridFactory<Grid> factory; + + std::int32_t dim = 0, dow = 0; + + in.read((char*)&dim, sizeof(std::int32_t)); + in.read((char*)&dow, sizeof(std::int32_t)); + + assert(Grid::dimension == dim); + assert(Grid::dimensionworld == dow); + + Reader reader(factory, in); + reader.readVertices(in); + reader.readElements(in); + + std::unique_ptr<Grid> ptr(factory.createGrid()); + return ptr.release(); + } + }; + +} // end namespace AMDiS diff --git a/src/amdis/Initfile.hpp b/src/amdis/Initfile.hpp index df76a58b0d7be1ff37f0b662b23c1d815dc464cc..5cbbaea32e0132bd57a77c4f64ba42ab1571f330 100644 --- a/src/amdis/Initfile.hpp +++ b/src/amdis/Initfile.hpp @@ -47,6 +47,12 @@ namespace AMDiS value = pt().get(key, value); } + template <class T> + static void set(std::string const& key, T const& value) + { + pt()[key] = value; + } + /// Returns specified info level static int getMsgInfo() { diff --git a/src/amdis/Mesh.hpp b/src/amdis/Mesh.hpp index be361b7392f7b0e49fce52da89bf93473e1aad39..d4524bf3b98ca98eaea1e30d50f649c1cf134e77 100644 --- a/src/amdis/Mesh.hpp +++ b/src/amdis/Mesh.hpp @@ -119,14 +119,19 @@ namespace AMDiS Dune::GmshReader<Grid> reader; return std::unique_ptr<Grid>{reader.read(filename)}; } -#if HAVE_ALBERTA - else if (ext == ".1d" || ext == ".2d" || ext == ".3d") { - Dune::GridFactory<Grid> factory; - Dune::AlbertaReader<Grid> reader; - reader.readGrid(filename, factory); - return std::unique_ptr<Grid>{factory.createGrid()}; - } -#endif +// #if HAVE_ALBERTA +// else if (ext == ".1d" || ext == ".2d" || ext == ".3d") { +// Dune::Hybrid::ifElse(bool_t<ALBERTA_DIM == Grid::dimensionworld>{}, +// [&](auto id) { +// Dune::GridFactory<Grid> factory; +// Dune::AlbertaReader<Grid> reader; +// id(reader).readGrid(filename, id(factory)); +// return std::unique_ptr<Grid>{factory.createGrid()}; +// }); + +// warning("WORLDDIM must be given in Alberta flags."); +// } +// #endif error_exit("No way to construct UG-Grid found"); return {}; diff --git a/src/amdis/PeriodicBC.inc.hpp b/src/amdis/PeriodicBC.inc.hpp index 0c92fecd8ba3fbbe67237bb39c7f1bd59de33d1c..b8901f9f1bfdb5f65fa00b70907bbe6af80c0b09 100644 --- a/src/amdis/PeriodicBC.inc.hpp +++ b/src/amdis/PeriodicBC.inc.hpp @@ -84,7 +84,7 @@ initAssociations(Basis const& basis) auto x = faceTrafo_.evaluate(insideCoords[i]); for (std::size_t j = 0; j < outsideCoords.size(); ++j) { auto const& y = outsideCoords[j]; - if ((x-y).two_norm() < tol) { + if (distance(x,y) < tol) { periodicNodes_[insideGlobalDOFs[i]] = true; associations_[insideGlobalDOFs[i]] = localView.index(outsideDOFs[j]); } @@ -183,7 +183,7 @@ initAssociations2(Basis const& basis) auto x = faceTrafo_.evaluate(insideCoords[i]); for (std::size_t j = 0; j < outsideCoords.size(); ++j) { auto const& y = outsideCoords[j]; - if ((x-y).two_norm() < tol) { + if (distance(x,y) < tol) { periodicNodes_[insideGlobalDOFs[i]] = true; associations_[insideGlobalDOFs[i]] = localView.index(outsideDOFs[j]); } diff --git a/src/amdis/ProblemStat.hpp b/src/amdis/ProblemStat.hpp index 3a5ad1d009a4e7aea6492f215010040678b6301c..005cf68eeb8afa62ed9e4213293fe8222d377395 100644 --- a/src/amdis/ProblemStat.hpp +++ b/src/amdis/ProblemStat.hpp @@ -295,6 +295,18 @@ namespace AMDiS /// Writes output files. void writeFiles(AdaptInfo& adaptInfo, bool force = false); + /// Backup the grid + void backup(std::string const& filename) const; + + /// Implements \ref ProblemStatBase::backup + void backup(AdaptInfo& adaptInfo) override; + + /// Retore the grid + auto restore(std::string const& filename); + + /// Implements \ref ProblemStatBase::restore + void restore(Flag initFlag) override; + public: // get-methods diff --git a/src/amdis/ProblemStat.inc.hpp b/src/amdis/ProblemStat.inc.hpp index 48686e05ed75fe8291f667931cfd2a6af2042423..0a942639d2b8038814a3c898a271384b12087f2d 100644 --- a/src/amdis/ProblemStat.inc.hpp +++ b/src/amdis/ProblemStat.inc.hpp @@ -6,9 +6,11 @@ #include <dune/common/hybridutilities.hh> #include <dune/common/timer.hh> +#include <dune/grid/common/capabilities.hh> #include <dune/typetree/childextraction.hh> #include <amdis/AdaptInfo.hpp> +#include <amdis/BackupRestore.hpp> #include <amdis/FileWriter.hpp> #include <amdis/Assembler.hpp> #include <amdis/GridFunctionOperator.hpp> @@ -477,4 +479,87 @@ writeFiles(AdaptInfo& adaptInfo, bool force) } +template <class Traits> +void ProblemStat<Traits>:: +backup(std::string const& filename) const +{ + if (Dune::Capabilities::hasBackupRestoreFacilities<Grid>::v) + Dune::BackupRestoreFacility<Grid>::backup(*grid_, filename); + else { + warning("Falling back to backup of gridview."); + BackupRestoreByGridFactory<Grid>::backup(gridView(), filename); + } +} + + +template <class Traits> +void ProblemStat<Traits>:: +backup(AdaptInfo& adaptInfo) +{ + auto param = Parameters::get<std::string>(name_ + "->backup->grid"); + std::string grid_filename = param ? *param : + name_ + "_" + std::to_string(adaptInfo.timestepNumber()) + ".grid"; + + auto param2 = Parameters::get<std::string>(name_ + "->backup->solution"); + std::string solution_filename = param2 ? *param2 : + name_ + "_" + std::to_string(adaptInfo.timestepNumber()) + ".solution"; + + backup(grid_filename); + solution_->backup(solution_filename); + msg("Problem backuped to files '{}' and '{}'.", grid_filename, solution_filename); +} + + +template <class Traits> +auto ProblemStat<Traits>:: +restore(std::string const& filename) +{ + // restore grid from file + std::unique_ptr<Grid> grid; + if (Dune::Capabilities::hasBackupRestoreFacilities<Grid>::v) + grid.reset(Dune::BackupRestoreFacility<Grid>::restore(filename)); + else + grid.reset(BackupRestoreByGridFactory<Grid>::restore(filename)); + return std::move(grid); +} + + +template <class Traits> +void ProblemStat<Traits>:: +restore(Flag initFlag) +{ + std::string grid_filename = Parameters::get<std::string>(name_ + "->restore->grid").value(); + std::string solution_filename = Parameters::get<std::string>(name_ + "->restore->solution").value(); + test_exit(filesystem::exists(grid_filename), "Restore file '{}' not found.", grid_filename); + test_exit(filesystem::exists(solution_filename), "Restore file '{}' not found.", solution_filename); + + // restore grid from file + adoptGrid(restore(grid_filename)); + + // create fespace + if (initFlag.isSet(INIT_FE_SPACE) || initFlag.isSet(INIT_SYSTEM)) + createGlobalBasis(); + + // create system + if (initFlag.isSet(INIT_SYSTEM)) + createMatricesAndVectors(); + + // create solver + if (linearSolver_) + warning("solver already created\n"); + else if (initFlag.isSet(INIT_SOLVER)) + createSolver(); + + // create marker + if (initFlag.isSet(INIT_MARKER)) + createMarker(); + + // create file writer + if (initFlag.isSet(INIT_FILEWRITER)) + createFileWriter(); + + solution_->compress(); + solution_->restore(solution_filename); +} + } // end namespace AMDiS diff --git a/src/amdis/ProblemStatBase.hpp b/src/amdis/ProblemStatBase.hpp index 81f4a7cf827aefb800396906e0c1ec161321d39f..df333cffc7bfdb7d6f09f3ebc341bf3717f9d82e 100644 --- a/src/amdis/ProblemStatBase.hpp +++ b/src/amdis/ProblemStatBase.hpp @@ -111,6 +111,12 @@ namespace AMDiS */ virtual void estimate(AdaptInfo& adaptInfo) = 0; + /// \brief backup the grid and the solution to a file + virtual void backup(AdaptInfo& adaptInfo) = 0; + + /// \brief restore the grid and the solution from a file + virtual void restore(Flag initFlag) = 0; + /// Returns the name of the problem. virtual std::string const& name() const = 0; }; diff --git a/src/amdis/common/FieldMatVec.hpp b/src/amdis/common/FieldMatVec.hpp index 41d7229ae94f229d4ea3a401652bd26c18c42668..eaa65e1a9b2c4e5ffe65f3f2f41dd41b2b2353e0 100644 --- a/src/amdis/common/FieldMatVec.hpp +++ b/src/amdis/common/FieldMatVec.hpp @@ -271,6 +271,10 @@ namespace Dune /// Dot-product with the vector itself + template <class T, + std::enable_if_t<Dune::IsNumber<T>::value, int> = 0> + auto unary_dot(T const& x); + template <class T, int N> auto unary_dot(FieldVector<T, N> const& x); @@ -319,6 +323,10 @@ namespace Dune /** \ingroup vector_norms * \brief The euklidean 2-norm of a vector = sqrt( sum_i |x_i|^2 ) **/ + template <class T, + std::enable_if_t<Dune::IsNumber<T>::value, int> = 0> + auto two_norm(T const& x); + template <class T, int N> auto two_norm(FieldVector<T, N> const& x); @@ -346,6 +354,10 @@ namespace Dune // ---------------------------------------------------------------------------- /// The euklidean distance between two vectors = |lhs-rhs|_2 + template <class T, + std::enable_if_t<Dune::IsNumber<T>::value, int> = 0> + T distance(T const& lhs, T const& rhs); + template <class T, int N> T distance(FieldVector<T, N> const& lhs, FieldVector<T, N> const& rhs); diff --git a/src/amdis/common/FieldMatVec.inc.hpp b/src/amdis/common/FieldMatVec.inc.hpp index 93f0c219159bc36224dce8e2ddd2957f0764a9b8..405239cdcf4a45cff50ff65e764f64fe31398c91 100644 --- a/src/amdis/common/FieldMatVec.inc.hpp +++ b/src/amdis/common/FieldMatVec.inc.hpp @@ -239,6 +239,14 @@ T sum(FieldMatrix<T, 1, N> const& x) /// Dot-product with the vector itself +template <class T, + std::enable_if_t<Dune::IsNumber<T>::value, int> > +auto unary_dot(T const& x) +{ + using std::abs; + return AMDiS::Math::sqr(abs(x)); +} + template <class T, int N> auto unary_dot(FieldVector<T, N> const& x) { @@ -327,6 +335,14 @@ auto one_norm(FieldMatrix<T, 1, N> const& x) /** \ingroup vector_norms * \brief The euklidean 2-norm of a vector = sqrt( sum_i |x_i|^2 ) **/ +template <class T, + std::enable_if_t<Dune::IsNumber<T>::value, int> > +auto two_norm(T const& x) +{ + using std::abs; + return abs(x); +} + template <class T, int N> auto two_norm(FieldVector<T, N> const& x) { @@ -374,6 +390,14 @@ auto infty_norm(FieldMatrix<T, 1, N> const& x) // ---------------------------------------------------------------------------- /// The euklidean distance between two vectors = |lhs-rhs|_2 +template <class T, + std::enable_if_t<Dune::IsNumber<T>::value, int> > +T distance(T const& lhs, T const& rhs) +{ + using std::abs; + return abs(lhs - rhs); +} + template <class T, int N> T distance(FieldVector<T, N> const& lhs, FieldVector<T, N> const& rhs) { diff --git a/src/amdis/linearalgebra/DOFVectorBase.hpp b/src/amdis/linearalgebra/DOFVectorBase.hpp index 9f17f9aa9f3462b6183656ced9dd57aa81e23d44..c505124d17842927b239ee8e351e7dcb64d2b0e1 100644 --- a/src/amdis/linearalgebra/DOFVectorBase.hpp +++ b/src/amdis/linearalgebra/DOFVectorBase.hpp @@ -226,6 +226,12 @@ namespace AMDiS /// Assemble all vector operators added by \ref addOperator(). void assemble(); + /// Write DOFVector to file + void backup(std::string const& filename); + + /// Read backup data from file + void restore(std::string const& filename); + /// Return the associated DataTransfer object std::shared_ptr<DataTransfer const> dataTransfer() const { diff --git a/src/amdis/linearalgebra/DOFVectorBase.inc.hpp b/src/amdis/linearalgebra/DOFVectorBase.inc.hpp index 783eb8998bced4271c82a18f3414245b6481a838..96b82af9576628ef25e37480a643dbde719d5973 100644 --- a/src/amdis/linearalgebra/DOFVectorBase.inc.hpp +++ b/src/amdis/linearalgebra/DOFVectorBase.inc.hpp @@ -1,5 +1,9 @@ #pragma once +#include <cstdint> +#include <fstream> +#include <functional> + #include <amdis/Assembler.hpp> #include <amdis/LocalOperator.hpp> #include <amdis/typetree/Traversal.hpp> @@ -91,9 +95,79 @@ assemble() for (auto const& element : elements(basis_->gridView())) { localView.bind(element); assemble(localView); - localView.unbind(element); + localView.unbind(); } finish(true); } + +template <class GB, class B> +void DOFVectorBase<GB,B>:: +backup(std::string const& filename) +{ + std::ofstream out(filename, std::ios::binary); + + std::int64_t numElements = basis_->gridView().size(0); + out.write((char*)&numElements, sizeof(std::int64_t)); + + auto localView = basis_->localView(); + std::vector<value_type> data; + for (auto const& element : elements(basis_->gridView())) + { + localView.bind(element); + data.clear(); + for_each_leaf_node(localView.tree(), [&](auto const& node, auto) -> void { + auto const& fe = node.finiteElement(); + std::size_t size = fe.size(); + + for (std::size_t i = 0; i < size; ++i) + data.push_back((*this)[localView.index(node.localIndex(i))]); + }); + + std::uint64_t len = data.size(); + out.write((char*)&len, sizeof(std::uint64_t)); + out.write((char*)data.data(), len*sizeof(value_type)); + + localView.unbind(); + } +} + +template <class GB, class B> +void DOFVectorBase<GB,B>:: +restore(std::string const& filename) +{ + std::ifstream in(filename, std::ios::binary); + + std::int64_t numElements = 0; + in.read((char*)&numElements, sizeof(std::int64_t)); + assert(numElements == basis_->gridView().size(0)); + + // assume the order of element traversal is not changed + auto localView = basis_->localView(); + std::vector<value_type> data; + for (auto const& element : elements(basis_->gridView())) + { + std::uint64_t len = 0; + in.read((char*)&len, sizeof(std::uint64_t)); + data.resize(len); + + in.read((char*)data.data(), len*sizeof(value_type)); + + localView.bind(element); + std::size_t shift = 0; + for_each_leaf_node(localView.tree(), [&](auto const& node, auto) -> void { + auto const& fe = node.finiteElement(); + std::size_t size = fe.size(); + + assert(data.size() >= shift+size); + for (std::size_t i = 0; i < size; ++i) + (*this)[localView.index(node.localIndex(i))] = data[shift + i]; + + shift += size; + }); + + localView.unbind(); + } +} + } // end namespace AMDiS diff --git a/src/amdis/operations/FieldMatVec.hpp b/src/amdis/operations/FieldMatVec.hpp index 512cc45d1957bd22cc5b3b3b19fb5241f2fa1835..7e2c07c9c4ce7d419ba7b9119ca981ae95afdefc 100644 --- a/src/amdis/operations/FieldMatVec.hpp +++ b/src/amdis/operations/FieldMatVec.hpp @@ -47,6 +47,7 @@ namespace AMDiS template <class V> constexpr auto operator()(V const& vec) const { + using Dune::unary_dot; return unary_dot(vec); } @@ -74,6 +75,7 @@ namespace AMDiS template <class V> constexpr auto operator()(V const& vec) const { + using Dune::two_norm; return two_norm(vec); } }; @@ -85,6 +87,7 @@ namespace AMDiS template <class M> constexpr auto operator()(M const& mat) const { + using Dune::trans; return trans(mat); } diff --git a/test/BackupRestoreTest.cpp b/test/BackupRestoreTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c86708924808ef627ed145e9754bd28055806ca2 --- /dev/null +++ b/test/BackupRestoreTest.cpp @@ -0,0 +1,136 @@ +#include <amdis/AMDiS.hpp> +#include <amdis/Integrate.hpp> +#include <amdis/ProblemStat.hpp> + +#include <dune/grid/onedgrid.hh> +#include <dune/grid/yaspgrid.hh> + +#if HAVE_DUNE_SPGRID +#include <dune/grid/spgrid.hh> +#endif +#if HAVE_DUNE_ALUGRID +#include <dune/alugrid/grid.hh> +#endif +#if HAVE_DUNE_FOAMGRID +#include <dune/foamgrid/foamgrid.hh> +#endif + +#include "Tests.hpp" + +using namespace AMDiS; + +template <class Grid, class Factory> +void test(Factory factory) +{ + using Param = TaylorHoodBasis<Grid>; + using Problem = ProblemStat<Param>; + + std::size_t num_elements = 0; + std::size_t num_vertices = 0; + + // backup + { + std::unique_ptr<Grid> grid(factory()); + Problem prob("test", *grid); + prob.initialize(INIT_ALL); + prob.globalRefine(2); + + prob.solution(Dune::Indices::_0) << [](auto const& x) { return x; }; + prob.solution(Dune::Indices::_1) << [](auto const& x) { return two_norm(x); }; + + num_elements = prob.grid()->size(0); + num_vertices = prob.grid()->size(Grid::dimension); + + AdaptInfo adaptInfo("adapt"); + prob.backup(adaptInfo); + } + + // restore + { + Problem prob("test"); + prob.restore(INIT_ALL); + + AMDIS_TEST_EQ(num_elements, prob.grid()->size(0)); + AMDIS_TEST_EQ(num_vertices, prob.grid()->size(Grid::dimension)); + + DOFVector<typename Param::GlobalBasis> vec(*prob.globalBasis()); + makeDOFVectorView(vec, Dune::Indices::_0) << [](auto const& x) { return x; }; + makeDOFVectorView(vec, Dune::Indices::_1) << [](auto const& x) { return two_norm(x); }; + + double error0 = std::sqrt(integrate( + unary_dot(prob.solution(Dune::Indices::_0) - makeDiscreteFunction(vec, Dune::Indices::_0)), prob.gridView())); + AMDIS_TEST(error0 < 1.e-10); + + double error1 = std::sqrt(integrate( + pow<2>(prob.solution(Dune::Indices::_1) - makeDiscreteFunction(vec, Dune::Indices::_1)), prob.gridView())); + AMDIS_TEST(error1 < 1.e-10); + } +} + +template <class Grid> +void test_cube() +{ + using Factory = Dune::StructuredGridFactory<Grid>; + Dune::FieldVector<double,Grid::dimensionworld> left(0.0); + Dune::FieldVector<double,Grid::dimensionworld> right(1.0); + auto sizes = Dune::filledArray<Grid::dimension, unsigned int>(2); + test<Grid>([&]() { return Factory::createCubeGrid(left, right, sizes); }); +} + +template <class Grid> +void test_simplex() +{ + using Factory = Dune::StructuredGridFactory<Grid>; + Dune::FieldVector<double,Grid::dimensionworld> left(0.0); + Dune::FieldVector<double,Grid::dimensionworld> right(1.0); + auto sizes = Dune::filledArray<Grid::dimension, unsigned int>(2); + test<Grid>([&]() { return Factory::createSimplexGrid(left, right, sizes); }); +} + +int main(int argc, char** argv) +{ + AMDiS::init(argc, argv); + + std::string filename = "test"; + Parameters::set("test->backup->grid", filename + ".grid"); + Parameters::set("test->restore->grid", filename + ".grid"); + Parameters::set("test->backup->solution", filename + ".solution"); + Parameters::set("test->restore->solution", filename + ".solution"); + +#if GRID_ID == 0 + test_cube<Dune::YaspGrid<2>>(); + test_cube<Dune::YaspGrid<3>>(); +#elif GRID_ID == 1 && HAVE_DUNE_UGGRID + test_cube<Dune::UGGrid<2>>(); + test_cube<Dune::UGGrid<3>>(); +#elif GRID_ID == 2 && HAVE_DUNE_ALUGRID + test_cube<Dune::ALUGrid<2,2,Dune::cube,Dune::nonconforming>>(); + test_cube<Dune::ALUGrid<3,3,Dune::cube,Dune::nonconforming>>(); + //test_cube<Dune::ALUGrid<2,3,Dune::cube,Dune::nonconforming>>(); +#elif GRID_ID == 3 && HAVE_DUNE_SPGRID + test<Dune::SPGrid<double,2>>([]() { + return std::unique_ptr<Dune::SPGrid<double,2>>( + new Dune::SPGrid<double,2>(Dune::SPDomain<double, 2>({0.0,0.0}, {1.0,1.0}), Dune::SPMultiIndex<2>({2,2}))); }); + test<Dune::SPGrid<double,3>>([]() { + return std::unique_ptr<Dune::SPGrid<double,3>>( + new Dune::SPGrid<double,3>(Dune::SPDomain<double, 3>({0.0,0.0,0.0}, {1.0,1.0,1.0}), Dune::SPMultiIndex<3>({2,2,2}))); }); +#elif GRID_ID == 4 && HAVE_DUNE_UGGRID + test_simplex<Dune::UGGrid<2>>(); + test_simplex<Dune::UGGrid<3>>(); +#elif GRID_ID == 5 && HAVE_DUNE_ALUGRID + test_simplex<Dune::ALUGrid<2,2,Dune::simplex,Dune::nonconforming>>(); + test_simplex<Dune::ALUGrid<3,3,Dune::simplex,Dune::nonconforming>>(); + //test_simplex<Dune::ALUGrid<2,3,Dune::simplex,Dune::nonconforming>>(); +#elif GRID_ID == 6 && HAVE_DUNE_ALUGRID + test_simplex<Dune::ALUGrid<2,2,Dune::simplex,Dune::conforming>>(); + test_simplex<Dune::ALUGrid<3,3,Dune::simplex,Dune::conforming>>(); + //test_simplex<Dune::ALUGrid<2,3,Dune::simplex,Dune::conforming>>(); +#elif GRID_ID == 7 + test_cube<Dune::OneDGrid>(); +#endif + // test_simplex<Dune::AlbertaGrid<2,2>>(); // Segmentation fault + // test_simplex<Dune::FoamGrid<2,2>>(); // Segmentation fault + + AMDiS::finalize(); + return report_errors(); +} diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b57c08786e19419d3a6ca7285226198cf9480e6f..fe265d45fb6caef40011838b467b7ee033b33425 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -5,6 +5,16 @@ dune_add_test(SOURCES AccessTest.cpp dune_add_test(SOURCES AdaptInfoTest.cpp LINK_LIBRARIES amdis) +foreach(_GRID RANGE 7) + dune_add_test(NAME "BackupRestoreTest_${_GRID}" + SOURCES BackupRestoreTest.cpp + COMPILE_DEFINITIONS "GRID_ID=${_GRID}" + LABELS "BackupRestore" + LINK_LIBRARIES amdis) + add_dune_alberta_flags(GRIDDIM 2 WORLDDIM 2 "BackupRestoreTest_${_GRID}") +endforeach() +unset(_GRID) + dune_add_test(SOURCES ConceptsTest.cpp LINK_LIBRARIES amdis)