diff --git a/AMDiS/CMakeLists.txt b/AMDiS/CMakeLists.txt index 0ca1d5a498d1f2adceed36f6455ac3a0a9e05814..3c5f98cab53e23f9c7d70caa4ff0591538c8ae8a 100644 --- a/AMDiS/CMakeLists.txt +++ b/AMDiS/CMakeLists.txt @@ -226,6 +226,7 @@ if(ENABLE_PARALLEL_DOMAIN) ${SOURCE_DIR}/parallel/CheckerPartitioner.cc ${SOURCE_DIR}/parallel/ElementObjectDatabase.cc ${SOURCE_DIR}/parallel/MeshDistributor.cc + ${SOURCE_DIR}/parallel/MeshLevelData.cc ${SOURCE_DIR}/parallel/MeshManipulation.cc ${SOURCE_DIR}/parallel/MeshPartitioner.cc ${SOURCE_DIR}/parallel/MpiHelper.cc diff --git a/AMDiS/src/AMDiS.cc b/AMDiS/src/AMDiS.cc index 1448c59b9f7a4ba4510704006110cd25521e1784..1da66eb4249ecb3186297306b6983cc13a632fca 100644 --- a/AMDiS/src/AMDiS.cc +++ b/AMDiS/src/AMDiS.cc @@ -49,6 +49,18 @@ namespace AMDiS { } + void init(std::string initFileName) + { + FUNCNAME("AMDiS::init()"); + +#ifdef HAVE_PARALLEL_DOMAIN_AMDIS + ERROR_EXIT("Does not work in parallel!\n"); +#endif + + Parameters::init(initFileName); + } + + void finalize() { FUNCNAME("AMDiS::finalize()"); diff --git a/AMDiS/src/AMDiS.h b/AMDiS/src/AMDiS.h index 0398b02a942fff92dcc28fbccb26332378abd6c7..402ca5fee42c804e4272da074f7a05319dda5d39 100644 --- a/AMDiS/src/AMDiS.h +++ b/AMDiS/src/AMDiS.h @@ -155,6 +155,8 @@ namespace AMDiS { void init(int argc, char **argv); + void init(std::string initFileName); + void finalize(); } diff --git a/AMDiS/src/parallel/MeshDistributor.cc b/AMDiS/src/parallel/MeshDistributor.cc index 3471f3c3872d6b8d390ee22e3918da9766f0e174..25461b17d4fe5d2996a73a7d27041574a3799f28 100644 --- a/AMDiS/src/parallel/MeshDistributor.cc +++ b/AMDiS/src/parallel/MeshDistributor.cc @@ -326,6 +326,9 @@ namespace AMDiS { ParallelDebug::testPeriodicBoundary(*this); #endif + // If required, create hierarchical mesh level structure. + createMeshLevelStructure(); + // === Global refinements. === int globalRefinement = 0; @@ -773,6 +776,59 @@ namespace AMDiS { } + void MeshDistributor::createMeshLevelStructure() + { + FUNCNAME("MeshDistributor::createMeshLevelStructure()"); + + if (mpiSize != 16) + return; + + std::set<int> neighbours; + for (InteriorBoundary::iterator it(rankIntBoundary); !it.end(); ++it) + neighbours.insert(it.getRank()); + + for (InteriorBoundary::iterator it(otherIntBoundary); !it.end(); ++it) + neighbours.insert(it.getRank()); + + levelData.init(neighbours); + + bool multiLevelTest = false; + Parameters::get("parallel->multi level test", multiLevelTest); + if (multiLevelTest) { + switch (mpiRank) { + case 0: case 1: case 4: case 5: + { + std::set<int> m; + m.insert(0); m.insert(1); m.insert(4); m.insert(5); + levelData.addLevel(m); + } + break; + case 2: case 3: case 6: case 7: + { + std::set<int> m; + m.insert(2); m.insert(3); m.insert(6); m.insert(7); + levelData.addLevel(m); + } + break; + case 8: case 9: case 12: case 13: + { + std::set<int> m; + m.insert(8); m.insert(9); m.insert(12); m.insert(13); + levelData.addLevel(m); + } + break; + case 10: case 11: case 14: case 15: + { + std::set<int> m; + m.insert(10); m.insert(11); m.insert(14); m.insert(15); + levelData.addLevel(m); + } + break; + } + } + } + + void MeshDistributor::checkMeshChange(bool tryRepartition) { FUNCNAME("MeshDistributor::checkMeshChange()"); @@ -2315,6 +2371,8 @@ namespace AMDiS { SerUtil::serialize(out, nMeshChangesAfterLastRepartitioning); SerUtil::serialize(out, repartitioningCounter); + + levelData.serialize(out); } @@ -2396,6 +2454,8 @@ namespace AMDiS { SerUtil::deserialize(in, nMeshChangesAfterLastRepartitioning); SerUtil::deserialize(in, repartitioningCounter); + levelData.deserialize(in); + deserialized = true; } diff --git a/AMDiS/src/parallel/MeshDistributor.h b/AMDiS/src/parallel/MeshDistributor.h index 95cea99cd2afcdaaff734e3dfb1f858f0c84aa6f..f762a8ee45b5558903ca577bd95d0dcd2e969b1f 100644 --- a/AMDiS/src/parallel/MeshDistributor.h +++ b/AMDiS/src/parallel/MeshDistributor.h @@ -28,6 +28,7 @@ #include "parallel/DofComm.h" #include "parallel/ElementObjectDatabase.h" #include "parallel/ParallelTypes.h" +#include "parallel/MeshLevelData.h" #include "parallel/MeshPartitioner.h" #include "parallel/InteriorBoundary.h" #include "parallel/PeriodicMap.h" @@ -537,6 +538,8 @@ namespace AMDiS { // Removes all periodic boundaries from a given boundary map. void removePeriodicBoundaryConditions(BoundaryIndexMap& boundaryMap); + void createMeshLevelStructure(); + /// Writes a vector of dof pointers to an output stream. void serialize(ostream &out, DofContainer &data); @@ -732,6 +735,8 @@ namespace AMDiS { map<const FiniteElemSpace*, BoundaryDofInfo> boundaryDofInfo; + MeshLevelData levelData; + public: bool sebastianMode; diff --git a/AMDiS/src/parallel/MeshLevelData.cc b/AMDiS/src/parallel/MeshLevelData.cc new file mode 100644 index 0000000000000000000000000000000000000000..7df797ef76dac8a195ce659f6bfcbe3f346be02b --- /dev/null +++ b/AMDiS/src/parallel/MeshLevelData.cc @@ -0,0 +1,61 @@ +// +// Software License for AMDiS +// +// Copyright (c) 2010 Dresden University of Technology +// All rights reserved. +// Authors: Simon Vey, Thomas Witkowski et al. +// +// This file is part of AMDiS +// +// See also license.opensource.txt in the distribution. + + +#include "parallel/MeshLevelData.h" +#include "Global.h" + +namespace AMDiS { + + using namespace std; + + + void MeshLevelData::init(std::set<int> &neighbourRanks) + { + levelRanks.resize(1); + levelRanks[0].insert(-1); + nLevel = 1; + + levelNeighbour.resize(1); + levelNeighbour[0] = neighbourRanks; + } + + + void MeshLevelData::addLevel(std::set<int> &ranksInDomain) + { + FUNCNAME("MeshLevelData()::addLevel()"); + + TEST_EXIT(nLevel >= 1)("Mesh level structure is not initialized()"); + TEST_EXIT(nLevel == 1)("Only 2 level are supported yet!\n"); + + levelRanks.insert(levelRanks.begin(), ranksInDomain); + nLevel++; + + levelNeighbour.resize(2); + levelNeighbour[1] = levelNeighbour[0]; + levelNeighbour[0].clear(); + for (std::set<int>::iterator it = levelNeighbour[1].begin(); + it != levelNeighbour[1].end(); ++it) + if (levelRanks[0].count(*it) == 0) + levelNeighbour[0].insert(*it); + } + + + void MeshLevelData::serialize(ostream &out) + { + } + + + void MeshLevelData::deserialize(istream &in) + { + } + +} diff --git a/AMDiS/src/parallel/MeshLevelData.h b/AMDiS/src/parallel/MeshLevelData.h new file mode 100644 index 0000000000000000000000000000000000000000..832ce999baee258148aabdd1ec61dc0aa5de7d2c --- /dev/null +++ b/AMDiS/src/parallel/MeshLevelData.h @@ -0,0 +1,62 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// == http://www.amdis-fem.org == +// == == +// ============================================================================ +// +// Software License for AMDiS +// +// Copyright (c) 2010 Dresden University of Technology +// All rights reserved. +// Authors: Simon Vey, Thomas Witkowski et al. +// +// This file is part of AMDiS +// +// See also license.opensource.txt in the distribution. + + + +/** \file MeshLevelData.h */ + +#ifndef AMDIS_MESH_LEVEL_DATA_H +#define AMDIS_MESH_LEVEL_DATA_H + + +#include <iostream> +#include <set> +#include <vector> + +namespace AMDiS { + + using namespace std; + + class MeshLevelData + { + public: + MeshLevelData() + : nLevel(0) + {} + + void init(std::set<int> &neighbourRanks); + + void addLevel(std::set<int> &ranksInDomain); + + // Writes all data of this object to an output stream. + void serialize(ostream &out); + + // Reads the object data from an input stream. + void deserialize(istream &in); + + protected: + vector<std::set<int> > levelRanks; + + int nLevel; + + vector<std::set<int> > levelNeighbour; + }; + +} + +#endif diff --git a/demo/src/ellipt.cc b/demo/src/ellipt.cc index f2c528a2a75091923fde8af730fff17778de0f9c..f566b2ccfd814ff2c3e26d0bd71f76ef0ec61c4d 100644 --- a/demo/src/ellipt.cc +++ b/demo/src/ellipt.cc @@ -72,7 +72,7 @@ int main(int argc, char* argv[]) ellipt.addVectorOperator(rhsOperator, 0); // ===== add boundary conditions ===== - ellipt.addDirichletBC(1, 0, 0, new G); +// ellipt.addDirichletBC(1, 0, 0, new G); // ===== start adaption loop ===== diff --git a/test/seq/CMakeLists.txt b/test/seq/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..310a161c09dde229229ee79351663cd8eccf6191 --- /dev/null +++ b/test/seq/CMakeLists.txt @@ -0,0 +1,32 @@ +project("AMDiS test suite (seq)") +cmake_minimum_required(VERSION 2.8) + +find_package(AMDIS REQUIRED) + +if(AMDIS_FOUND) + message("amdis was found\n") + include(${AMDIS_USE_FILE}) + SET(BASIS_LIBS ${AMDIS_LIBRARIES}) +endif(AMDIS_FOUND) + +find_package(Boost 1.42 REQUIRED) +if(Boost_FOUND) + list(APPEND AMDIS_INCLUDE_DIRS ${Boost_INCLUDE_DIR}) + message("boost lib-dirs: ${Boost_LIBRARY_DIRS}") + message("use the boost dir: ${Boost_INCLUDE_DIR}") + if(WIN32) + message("the windows find_boost does not set the boost library paths, please set it") + SET(Boost_LIBRARY_DIRS CACHE PATH "The directory containing the boost libraries") + endif(WIN32) + list(APPEND BASIS_LIBS ${Boost_LIBRARY_DIRS}/libboost_unit_test_framework.so) +endif(Boost_FOUND) + +file(GLOB sources src/*.cc) +foreach(s ${sources}) + get_filename_component(swe ${s} NAME_WE) + add_executable(${swe} ${s}) + target_link_libraries(${swe} ${BASIS_LIBS}) +endforeach(s) + +#create the output dir +file(MAKE_DIRECTORY output) diff --git a/test/seq/init/test0001.dat.2d b/test/seq/init/test0001.dat.2d new file mode 100644 index 0000000000000000000000000000000000000000..bc2445f1ddd48219cf4f6b124699a696066269bb --- /dev/null +++ b/test/seq/init/test0001.dat.2d @@ -0,0 +1,29 @@ +dimension of world: 2 + +elliptMesh->macro file name: ./macro/macro.stand.2d +elliptMesh->global refinements: 5 + +ellipt->mesh: elliptMesh +ellipt->dim: 2 +ellipt->components: 1 +ellipt->polynomial degree[0]: 1 + +ellipt->solver: cg +ellipt->solver->max iteration: 10 +ellipt->solver->tolerance: 1.e-8 +ellipt->solver->info: 10 +ellipt->solver->left precon: diag +ellipt->solver->right precon: no + +ellipt->estimator[0]: 0 +ellipt->estimator[0]->error norm: 1 % 1: H1_NORM, 2: L2_NORM +ellipt->estimator[0]->C0: 0.1 % constant of element residual +ellipt->estimator[0]->C1: 0.1 % constant of jump residual + +ellipt->marker[0]->strategy: 0 % 0: no adaption 1: GR 2: MS 3: ES 4:GERS + +ellipt->adapt[0]->tolerance: 1e-4 +ellipt->adapt->max iteration: 15 + +ellipt->output->filename: output/ellipt.2d +ellipt->output->ParaView format: 1 diff --git a/test/seq/macro/macro.stand.2d b/test/seq/macro/macro.stand.2d new file mode 100644 index 0000000000000000000000000000000000000000..8caa1a56795ca498a88cf5742929bd9f0729f1a5 --- /dev/null +++ b/test/seq/macro/macro.stand.2d @@ -0,0 +1,30 @@ +DIM: 2 +DIM_OF_WORLD: 2 + +number of elements: 4 +number of vertices: 5 + +element vertices: +0 1 4 +1 2 4 +2 3 4 +3 0 4 + +element boundaries: +0 0 1 +0 0 3 +0 0 1 +0 0 2 + +vertex coordinates: + 0.0 0.0 + 1.0 0.0 + 1.0 1.0 + 0.0 1.0 + 0.5 0.5 + +element neighbours: +1 3 -1 +2 0 -1 +3 1 -1 +0 2 -1 \ No newline at end of file diff --git a/test/seq/src/test0001.cc b/test/seq/src/test0001.cc new file mode 100644 index 0000000000000000000000000000000000000000..89a2bd7a448b205bd0eee4769faf23dddb05d4f9 --- /dev/null +++ b/test/seq/src/test0001.cc @@ -0,0 +1,45 @@ +#define BOOST_TEST_DYN_LINK +#define BOOST_TEST_MODULE 0001 + +#include <boost/test/unit_test.hpp> +#include <AMDiS.h> + +using namespace AMDiS; + +BOOST_AUTO_TEST_CASE(blub) +{ + FUNCNAME("main"); + + AMDiS::init("./init/test0001.dat.2d"); + + // ===== create and init the scalar problem ===== + ProblemStat ellipt("ellipt"); + ellipt.initialize(INIT_ALL); + + // === create adapt info === + AdaptInfo adaptInfo("ellipt->adapt", ellipt.getNumComponents()); + + BOOST_REQUIRE(ellipt.getNumComponents() == 1); + + // === create adapt === + AdaptStationary adapt("ellipt->adapt", ellipt, adaptInfo); + + // ===== create matrix operator ===== + Operator matrixOperator(ellipt.getFeSpace()); + matrixOperator.addTerm(new Simple_SOT); + ellipt.addMatrixOperator(matrixOperator, 0, 0); + + // ===== create rhs operator ===== + Operator rhsOperator(ellipt.getFeSpace()); + rhsOperator.addTerm(new Simple_ZOT); + ellipt.addVectorOperator(rhsOperator, 0); + + // ===== start adaption loop ===== + adapt.adapt(); + + BOOST_REQUIRE(ellipt.getFeSpace()->getAdmin()->getUsedSize() == 81); + + AMDiS::finalize(); +} + +