diff --git a/AMDiS/src/CouplingIterationInterface.cc b/AMDiS/src/CouplingIterationInterface.cc index d4c1a54b3dd6b3627bcfa3f7278567fc3e3f412c..717b74eff67cb0d8e85069b7727220d1efade2c7 100644 --- a/AMDiS/src/CouplingIterationInterface.cc +++ b/AMDiS/src/CouplingIterationInterface.cc @@ -32,8 +32,10 @@ namespace AMDiS { if (number < 0) idx = problems.size(); std::vector<ProblemIterationInterface*>::iterator pos = problems.begin() + idx; + std::vector<bool>::iterator pos2 = solveProblem.begin() + idx; problems.insert(pos, probIter); + solveProblem.insert(pos2, true); }; @@ -57,10 +59,12 @@ namespace AMDiS { { FUNCNAME("CouplingIterationInterface::oneIteration()"); Flag flag = 0; - for (unsigned i = 0; i < problems.size(); ++i) { - problems[i]->beginIteration(adaptInfo); - flag |= problems[i]->oneIteration(adaptInfo, toDo); - problems[i]->endIteration(adaptInfo); + for (size_t i = 0; i < problems.size(); ++i) { + if (solveProblem[i]) { + problems[i]->beginIteration(adaptInfo); + flag |= problems[i]->oneIteration(adaptInfo, toDo); + problems[i]->endIteration(adaptInfo); + } } return flag; @@ -80,8 +84,8 @@ namespace AMDiS { /// Returns number of managed problems int CouplingIterationInterface::getNumProblems() { - int num= 0; - for (unsigned i = 0; i < problems.size(); ++i) + size_t num= 0; + for (size_t i = 0; i < problems.size(); ++i) num += problems[i]->getNumProblems(); return num; }; @@ -93,14 +97,14 @@ namespace AMDiS { */ ProblemStatBase *CouplingIterationInterface::getProblem(int number) { - int maxNum = getNumProblems(); - if (maxNum <= number || number < 0) + size_t maxNum = getNumProblems(); + if (maxNum <= static_cast<size_t>(number)) throw(std::runtime_error("Problem number out of range.")); - int sum = 0; + size_t sum = 0; ProblemStatBase *probIter = NULL; - for (unsigned i = 0; i < problems.size(); ++i) { - if (sum + problems[i]->getNumProblems() <= number) + for (size_t i = 0; i < problems.size(); ++i) { + if (sum + problems[i]->getNumProblems() <= static_cast<size_t>(number)) sum += problems[i]->getNumProblems(); else probIter = problems[i]->getProblem(number - sum); @@ -112,12 +116,23 @@ namespace AMDiS { /// Returns the name of the problem. - std::string CouplingIterationInterface::getName(int number) + std::string CouplingIterationInterface::getName(size_t number) { - if (static_cast<int>(problems.size()) <= number || number < 0) + if (static_cast<size_t>(problems.size()) <= number) throw(std::runtime_error("Problem number out of range.")); return problems[number]->getName(); }; + + void CouplingIterationInterface::setSolveProblem(std::string name, bool flag) + { + for (size_t i = 0; i < problems.size(); ++i) { + if (problems[i]->getName() == name) { + setSolveProblem(i, flag); + break; + } + } + }; + } // namespace AMDiS diff --git a/AMDiS/src/CouplingIterationInterface.h b/AMDiS/src/CouplingIterationInterface.h index 39c4e9dff63ca35e2b50db11e52c51ff5f854fef..aa2e29bdacfac5783abe4942443d40091c1dc979 100644 --- a/AMDiS/src/CouplingIterationInterface.h +++ b/AMDiS/src/CouplingIterationInterface.h @@ -59,19 +59,26 @@ namespace AMDiS { /// Called after each adaption loop iteration. virtual void endIteration(AdaptInfo *adaptInfo); - /// Returns number of managed problems virtual int getNumProblems(); + /// Returns number of managed problems + virtual size_t getNumIterationInterfaces() { return problems.size(); } + /** \brief * Returns the problem with the given number. If only one problem * is managed by this master problem, the number hasn't to be given. */ virtual ProblemStatBase *getProblem(int number = 0); + virtual ProblemIterationInterface *getIterationInterface(size_t number = 0) { return problems[number]; } + /// Returns the name of the problem with the given number. - virtual std::string getName(int number); + virtual std::string getName(size_t number); virtual std::string getName() { return getName(0); } + virtual void setSolveProblem(size_t number, bool flag = true) { solveProblem[number] = flag; } + virtual void setSolveProblem(std::string name, bool flag = true); + /// Function that serializes the problem plus information about the iteration. virtual void serialize(std::ostream &out) {}; @@ -82,6 +89,7 @@ namespace AMDiS { /// vector/map of coupled stationary problems std::vector<ProblemIterationInterface*> problems; + std::vector<bool> solveProblem; }; } diff --git a/AMDiS/src/CouplingProblemStat.h b/AMDiS/src/CouplingProblemStat.h new file mode 100644 index 0000000000000000000000000000000000000000..9e65593951d3ec311dafe720039eaaf4afe0cafe --- /dev/null +++ b/AMDiS/src/CouplingProblemStat.h @@ -0,0 +1,271 @@ +// ============================================================================ +// == == +// == 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 CouplingProblemStat.h */ + +#ifndef AMDIS_COUPLING_PROBLEM_STAT_H +#define AMDIS_COUPLING_PROBLEM_STAT_H + +#include <vector> +#include <set> +#include <list> +#include "AMDiS_fwd.h" +#include "ProblemStat.h" +#include "Initfile.h" +#include <boost/lexical_cast.hpp> + +namespace AMDiS { + + using namespace std; + + + /** \brief + * This class defines a coupled stationary problem definition in sequential + * computations. + */ + class CouplingProblemStat + { + public: + /// Constructor + CouplingProblemStat(std::string name_) + : name(name_), + nComponents(0), + nMeshes(0), + refinementManager(NULL), + coarseningManager(NULL) + {} + + /// Destructor + virtual ~CouplingProblemStat() {} + + /// add problem by number + virtual void addProblem(ProblemStat* prob) + { + problems.push_back(prob); + }; + + /// Initialisation of the problem. + virtual void initialize(Flag initFlag, + CouplingProblemStat *adoptProblem = NULL, + Flag adoptFlag = INIT_NOTHING) + { + + // create one refinement-/coarseningmanager for all problems + if (refinementManager != NULL && coarseningManager != NULL) { + WARNING("refinement-/coarseningmanager already created\n"); + } else { + if (!adoptProblem) + createRefCoarseManager(); + else { + refinementManager = adoptProblem->refinementManager; + coarseningManager = adoptProblem->coarseningManager; + } + } + + if (refinementManager == NULL || coarseningManager == NULL) + WARNING("no refinement-/coarseningmanager created\n"); + + // create Meshes and FeSpaces + + // one global macro-mesh for all problems + string meshName(""); + Parameters::get(name + "->mesh", meshName); + TEST_EXIT(meshName != "")("No mesh name specified for \"%s->mesh\"!\n", + name.c_str()); + + // all problems must have the same dimension (?) + int dim = 0; + Parameters::get(name + "->dim", dim); + TEST_EXIT(dim)("No problem dimension specified for \"%s->dim\"!\n", + name.c_str()); + + map<int, Mesh*> meshForRefinementSet; + vector< std::set<Mesh*> > meshesForProblems(problems.size()); + map<pair<Mesh*, int>, FiniteElemSpace*> feSpaceMap; + for (size_t i = 0; i < problems.size(); ++i) { + TEST_EXIT(problems[i])("problem[%d] does not exist!\n",i); + nComponents += problems[i]->getNumComponents(); + for (size_t j = 0; j < problems[i]->getNumComponents(); j++) { + // mesh + int refSet = -1; + Parameters::get(problems[i]->getName() + "->" + + "refinement set[" + boost::lexical_cast<string>(j) + "]", + refSet); + if (refSet < 0) + refSet = 0; + + if (meshForRefinementSet.find(refSet) == meshForRefinementSet.end()) { + Mesh *newMesh = new Mesh(meshName, dim); + meshForRefinementSet[refSet] = newMesh; + meshes.push_back(newMesh); + meshesForProblems[i].insert(newMesh); + nMeshes++; + } else + meshesForProblems[i].insert(meshForRefinementSet[refSet]); + + problems[i]->setComponentMesh(j, meshForRefinementSet[refSet]); + + // feSpace + int degree = 1; + Parameters::get(problems[i]->getName() + "->polynomial degree[" + + boost::lexical_cast<string>(j) + "]", degree); + + if (feSpaceMap[pair<Mesh*, int>(meshForRefinementSet[refSet], degree)] == NULL) { + stringstream s; + s << problems[i]->getName() << "->feSpace[" << j << "]"; + + FiniteElemSpace *newFeSpace = + FiniteElemSpace::provideFeSpace(NULL, Lagrange::getLagrange(dim, degree), + meshForRefinementSet[refSet], s.str()); + feSpaceMap[pair<Mesh*, int>(meshForRefinementSet[refSet], degree)] = newFeSpace; + feSpaces.push_back(newFeSpace); + } + +// problems[i].setComponentSpace(i, feSpaceMap[pair<Mesh*, int>(meshForRefinementSet[refSet], degree)]); + } + } + + for (size_t i = 0; i < problems.size(); ++i) { + vector<Mesh*> problemMeshes(meshesForProblems[i].begin(), meshesForProblems[i].end()); + problems[i]->setMeshes(problemMeshes); + problems[i]->setRefinementManager(refinementManager); + problems[i]->setCoarseningManager(coarseningManager); + problems[i]->initialize(INIT_ALL); + } + } + + void createRefCoarseManager() + { + FUNCNAME("ProblemStat::createRefCoarseManager()"); + + int dim = 0; + Parameters::get(name + "->dim", dim); + TEST_EXIT(dim)("No problem dimension specified for \"%s->dim\"!\n", + name.c_str()); + + switch (dim) { + case 1: + coarseningManager = new CoarseningManager1d(); + refinementManager = new RefinementManager1d(); + break; + case 2: + coarseningManager = new CoarseningManager2d(); + refinementManager = new RefinementManager2d(); + break; + case 3: + coarseningManager = new CoarseningManager3d(); + refinementManager = new RefinementManager3d(); + break; + default: + ERROR_EXIT("invalid dim!\n"); + } + } + + /// Returns number of managed problems + virtual int getNumProblems() + { + return problems.size(); + } + + /// Implementation of ProblemStatBase::getNumComponents() + virtual int getNumComponents() + { + return nComponents; + } + + /** \brief + * Returns the problem with the given number. If only one problem + * is managed by this master problem, the number hasn't to be given. + */ + virtual ProblemStat *getProblem(int number = 0) + { + return problems[number]; + } + + /// Returns \ref meshes[i] + inline Mesh* getMesh(int number = 0) + { + return meshes[number]; + } + + /// Returns \ref meshes + inline vector<Mesh*> getMeshes() + { + return meshes; + } + + /// Returns \ref refinementManager. + inline RefinementManager* getRefinementManager(int comp = 0) + { + return refinementManager; + } + + /// Returns \ref refinementManager. + inline CoarseningManager* getCoarseningManager(int comp = 0) + { + return coarseningManager; + } + + /// Returns the name of the problem + inline virtual string getName() + { + return name; + } + + protected: + + /// Name of this problem. + string name; + + /// Number of problem components + int nComponents; + + /** \brief + * Number of problem meshes. If all components are defined on the same mesh, + * this number is 1. Otherwise, this variable is the number of different meshes + * within the problem. + */ + int nMeshes; + + /// FE spaces of this problem. + vector<FiniteElemSpace*> feSpaces; + + /// Meshes of this problem. + vector<Mesh*> meshes; + + /** \brief + * All actions of mesh refinement are performed by refinementManager. + * If new refinement algorithms should be realized, one has to override + * RefinementManager and give one instance of it to AdaptStationary. + */ + RefinementManager *refinementManager; + + /** \brief + * All actions of mesh coarsening are performed by coarseningManager. + * If new coarsening algorithms should be realized, one has to override + * CoarseningManager and give one instance of it to AdaptStationary. + */ + CoarseningManager *coarseningManager; + + vector<ProblemStat*> problems; + }; +} + +#endif diff --git a/AMDiS/src/ProblemStat.cc b/AMDiS/src/ProblemStat.cc index f437f85c088c6f261e7ca549bbe15c3094fe8b2b..348423d923406c7acb5552b01c66b6d3ad978bfd 100644 --- a/AMDiS/src/ProblemStat.cc +++ b/AMDiS/src/ProblemStat.cc @@ -66,8 +66,6 @@ namespace AMDiS { adoptFlag.isSet(INIT_FE_SPACE))) { meshes = adoptProblem->getMeshes(); componentMeshes = adoptProblem->componentMeshes; - refinementManager = adoptProblem->refinementManager; - coarseningManager = adoptProblem->coarseningManager; // If the adopt problem has fewer components than this problem, but only one // mesh for all component, than scal up the componentMeshes array. @@ -89,6 +87,27 @@ namespace AMDiS { if (meshes.size() == 0) WARNING("no mesh created\n"); + // === create refinement/corasening-manager === + if (refinementManager != NULL && coarseningManager != NULL) { + WARNING("refinement-/coarseningmanager already created\n"); + } else { + if (initFlag.isSet(CREATE_MESH) || + (!adoptFlag.isSet(INIT_MESH) && + (initFlag.isSet(INIT_SYSTEM) || initFlag.isSet(INIT_FE_SPACE)))) + createRefCoarseManager(); + + if (adoptProblem && + (adoptFlag.isSet(INIT_MESH) || + adoptFlag.isSet(INIT_SYSTEM) || + adoptFlag.isSet(INIT_FE_SPACE))) { + refinementManager = adoptProblem->refinementManager; + coarseningManager = adoptProblem->coarseningManager; + } + } + + if (refinementManager == NULL || coarseningManager == NULL) + WARNING("no refinement-/coarseningmanager created\n"); + // === create fespace === if (feSpaces.size() != 0) { WARNING("feSpaces already created\n"); @@ -275,19 +294,30 @@ namespace AMDiS { } componentMeshes[i] = meshForRefinementSet[refSet]; } + } + + + void ProblemStatSeq::createRefCoarseManager() + { + FUNCNAME("ProblemStat::createRefCoarseManager()"); + + int dim = 0; + Parameters::get(name + "->dim", dim); + TEST_EXIT(dim)("No problem dimension specified for \"%s->dim\"!\n", + name.c_str()); switch (dim) { case 1: - coarseningManager = new CoarseningManager1d(); refinementManager = new RefinementManager1d(); + coarseningManager = new CoarseningManager1d(); break; case 2: - coarseningManager = new CoarseningManager2d(); refinementManager = new RefinementManager2d(); + coarseningManager = new CoarseningManager2d(); break; case 3: - coarseningManager = new CoarseningManager3d(); refinementManager = new RefinementManager3d(); + coarseningManager = new CoarseningManager3d(); break; default: ERROR_EXIT("invalid dim!\n"); diff --git a/AMDiS/src/ProblemStat.h b/AMDiS/src/ProblemStat.h index 7a541914015f8a4595d50a503317a15bc141f7a4..35a7230f87a03085d55b3268da2847581aad96e3 100644 --- a/AMDiS/src/ProblemStat.h +++ b/AMDiS/src/ProblemStat.h @@ -78,6 +78,8 @@ namespace AMDiS { rhs(NULL), systemMatrix(NULL), useGetBound(true), + refinementManager(NULL), + coarseningManager(NULL), info(10), deserialized(false), computeExactError(false), @@ -114,6 +116,9 @@ namespace AMDiS { /// Used in \ref initialize(). virtual void createMesh(); + /// Used in \ref initialize(). + virtual void createRefCoarseManager(); + /// Used in \ref initialize(). virtual void createFeSpace(DOFAdmin *admin); @@ -535,6 +540,31 @@ namespace AMDiS { writeAsmInfo = b; } + void setMeshes(vector<Mesh*> meshes_) + { + meshes = meshes_; + nMeshes = static_cast<int>(meshes.size()); + } + + void setComponentMesh(int comp, Mesh* mesh) + { + if (static_cast<int>(componentMeshes.size()) < nComponents) + componentMeshes.resize(nComponents); + TEST_EXIT(comp >= 0 && comp < nComponents) + ("Component number not in feasable range!"); + + componentMeshes[comp] = mesh; + } + + void setRefinementManager(RefinementManager *ref) + { + refinementManager = ref; + } + + void setCoarseningManager(CoarseningManager *coarse) + { + coarseningManager = coarse; + } /** \} */ /** \brief