Commit 249f590b authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

add CouplingProblemStat and modifications in ProblemStat

parent 1891d309
...@@ -32,8 +32,10 @@ namespace AMDiS { ...@@ -32,8 +32,10 @@ namespace AMDiS {
if (number < 0) if (number < 0)
idx = problems.size(); idx = problems.size();
std::vector<ProblemIterationInterface*>::iterator pos = problems.begin() + idx; std::vector<ProblemIterationInterface*>::iterator pos = problems.begin() + idx;
std::vector<bool>::iterator pos2 = solveProblem.begin() + idx;
problems.insert(pos, probIter); problems.insert(pos, probIter);
solveProblem.insert(pos2, true);
}; };
...@@ -57,10 +59,12 @@ namespace AMDiS { ...@@ -57,10 +59,12 @@ namespace AMDiS {
{ FUNCNAME("CouplingIterationInterface::oneIteration()"); { FUNCNAME("CouplingIterationInterface::oneIteration()");
Flag flag = 0; Flag flag = 0;
for (unsigned i = 0; i < problems.size(); ++i) { for (size_t i = 0; i < problems.size(); ++i) {
problems[i]->beginIteration(adaptInfo); if (solveProblem[i]) {
flag |= problems[i]->oneIteration(adaptInfo, toDo); problems[i]->beginIteration(adaptInfo);
problems[i]->endIteration(adaptInfo); flag |= problems[i]->oneIteration(adaptInfo, toDo);
problems[i]->endIteration(adaptInfo);
}
} }
return flag; return flag;
...@@ -80,8 +84,8 @@ namespace AMDiS { ...@@ -80,8 +84,8 @@ namespace AMDiS {
/// Returns number of managed problems /// Returns number of managed problems
int CouplingIterationInterface::getNumProblems() int CouplingIterationInterface::getNumProblems()
{ {
int num= 0; size_t num= 0;
for (unsigned i = 0; i < problems.size(); ++i) for (size_t i = 0; i < problems.size(); ++i)
num += problems[i]->getNumProblems(); num += problems[i]->getNumProblems();
return num; return num;
}; };
...@@ -93,14 +97,14 @@ namespace AMDiS { ...@@ -93,14 +97,14 @@ namespace AMDiS {
*/ */
ProblemStatBase *CouplingIterationInterface::getProblem(int number) ProblemStatBase *CouplingIterationInterface::getProblem(int number)
{ {
int maxNum = getNumProblems(); size_t maxNum = getNumProblems();
if (maxNum <= number || number < 0) if (maxNum <= static_cast<size_t>(number))
throw(std::runtime_error("Problem number out of range.")); throw(std::runtime_error("Problem number out of range."));
int sum = 0; size_t sum = 0;
ProblemStatBase *probIter = NULL; ProblemStatBase *probIter = NULL;
for (unsigned i = 0; i < problems.size(); ++i) { for (size_t i = 0; i < problems.size(); ++i) {
if (sum + problems[i]->getNumProblems() <= number) if (sum + problems[i]->getNumProblems() <= static_cast<size_t>(number))
sum += problems[i]->getNumProblems(); sum += problems[i]->getNumProblems();
else else
probIter = problems[i]->getProblem(number - sum); probIter = problems[i]->getProblem(number - sum);
...@@ -112,12 +116,23 @@ namespace AMDiS { ...@@ -112,12 +116,23 @@ namespace AMDiS {
/// Returns the name of the problem. /// 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.")); throw(std::runtime_error("Problem number out of range."));
return problems[number]->getName(); 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 } // namespace AMDiS
...@@ -59,19 +59,26 @@ namespace AMDiS { ...@@ -59,19 +59,26 @@ namespace AMDiS {
/// Called after each adaption loop iteration. /// Called after each adaption loop iteration.
virtual void endIteration(AdaptInfo *adaptInfo); virtual void endIteration(AdaptInfo *adaptInfo);
/// Returns number of managed problems
virtual int getNumProblems(); virtual int getNumProblems();
/// Returns number of managed problems
virtual size_t getNumIterationInterfaces() { return problems.size(); }
/** \brief /** \brief
* Returns the problem with the given number. If only one problem * Returns the problem with the given number. If only one problem
* is managed by this master problem, the number hasn't to be given. * is managed by this master problem, the number hasn't to be given.
*/ */
virtual ProblemStatBase *getProblem(int number = 0); 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. /// 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 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. /// Function that serializes the problem plus information about the iteration.
virtual void serialize(std::ostream &out) {}; virtual void serialize(std::ostream &out) {};
...@@ -82,6 +89,7 @@ namespace AMDiS { ...@@ -82,6 +89,7 @@ namespace AMDiS {
/// vector/map of coupled stationary problems /// vector/map of coupled stationary problems
std::vector<ProblemIterationInterface*> problems; std::vector<ProblemIterationInterface*> problems;
std::vector<bool> solveProblem;
}; };
} }
......
// ============================================================================
// == ==
// == 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
...@@ -66,8 +66,6 @@ namespace AMDiS { ...@@ -66,8 +66,6 @@ namespace AMDiS {
adoptFlag.isSet(INIT_FE_SPACE))) { adoptFlag.isSet(INIT_FE_SPACE))) {
meshes = adoptProblem->getMeshes(); meshes = adoptProblem->getMeshes();
componentMeshes = adoptProblem->componentMeshes; componentMeshes = adoptProblem->componentMeshes;
refinementManager = adoptProblem->refinementManager;
coarseningManager = adoptProblem->coarseningManager;
// If the adopt problem has fewer components than this problem, but only one // If the adopt problem has fewer components than this problem, but only one
// mesh for all component, than scal up the componentMeshes array. // mesh for all component, than scal up the componentMeshes array.
...@@ -89,6 +87,27 @@ namespace AMDiS { ...@@ -89,6 +87,27 @@ namespace AMDiS {
if (meshes.size() == 0) if (meshes.size() == 0)
WARNING("no mesh created\n"); 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 === // === create fespace ===
if (feSpaces.size() != 0) { if (feSpaces.size() != 0) {
WARNING("feSpaces already created\n"); WARNING("feSpaces already created\n");
...@@ -275,19 +294,30 @@ namespace AMDiS { ...@@ -275,19 +294,30 @@ namespace AMDiS {
} }
componentMeshes[i] = meshForRefinementSet[refSet]; 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) { switch (dim) {
case 1: case 1:
coarseningManager = new CoarseningManager1d();
refinementManager = new RefinementManager1d(); refinementManager = new RefinementManager1d();
coarseningManager = new CoarseningManager1d();
break; break;
case 2: case 2:
coarseningManager = new CoarseningManager2d();
refinementManager = new RefinementManager2d(); refinementManager = new RefinementManager2d();
coarseningManager = new CoarseningManager2d();
break; break;
case 3: case 3:
coarseningManager = new CoarseningManager3d();
refinementManager = new RefinementManager3d(); refinementManager = new RefinementManager3d();
coarseningManager = new CoarseningManager3d();
break; break;
default: default:
ERROR_EXIT("invalid dim!\n"); ERROR_EXIT("invalid dim!\n");
......
...@@ -78,6 +78,8 @@ namespace AMDiS { ...@@ -78,6 +78,8 @@ namespace AMDiS {
rhs(NULL), rhs(NULL),
systemMatrix(NULL), systemMatrix(NULL),
useGetBound(true), useGetBound(true),
refinementManager(NULL),
coarseningManager(NULL),
info(10), info(10),
deserialized(false), deserialized(false),
computeExactError(false), computeExactError(false),
...@@ -114,6 +116,9 @@ namespace AMDiS { ...@@ -114,6 +116,9 @@ namespace AMDiS {
/// Used in \ref initialize(). /// Used in \ref initialize().
virtual void createMesh(); virtual void createMesh();
/// Used in \ref initialize().
virtual void createRefCoarseManager();
/// Used in \ref initialize(). /// Used in \ref initialize().
virtual void createFeSpace(DOFAdmin *admin); virtual void createFeSpace(DOFAdmin *admin);
...@@ -535,6 +540,31 @@ namespace AMDiS { ...@@ -535,6 +540,31 @@ namespace AMDiS {
writeAsmInfo = b; 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 /** \brief
......
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