Commit e6cd8e18 authored by Thomas Witkowski's avatar Thomas Witkowski

* Global refinement bug fix (for different meshes of different components)

parent 23e3a357
......@@ -279,7 +279,8 @@ namespace AMDiS {
}
}
} else {
DimVec<double> grdPhi(dim, DEFAULT_VALUE, 0.0);
// DimVec<double> grdPhi(dim, DEFAULT_VALUE, 0.0);
DimVec<double>* grdPhi = grdPhis[omp_get_thread_num()];
for (int i = 0; i < numPoints; i++) {
for (int j = 0; j < dim + 1; j++) {
......@@ -287,9 +288,9 @@ namespace AMDiS {
}
for (int j = 0; j < nBasFcts; j++) {
(*(basFcts->getGrdPhi(j)))(quad->getLambda(i), grdPhi);
(*(basFcts->getGrdPhi(j)))(quad->getLambda(i), *grdPhi);
for (int k = 0; k < parts; k++) {
grd1[k] += grdPhi[k] * localVec[j];
grd1[k] += (*grdPhi)[k] * localVec[j];
}
}
......@@ -379,7 +380,9 @@ namespace AMDiS {
}
}
} else {
DimMat<double> D2Phi(dim, NO_INIT);
// DimMat<double> D2Phi(dim, NO_INIT);
DimMat<double>* D2Phi = D2Phis[omp_get_thread_num()];
for (iq = 0; iq < numPoints; iq++) {
for (k = 0; k < parts; k++)
for (l = 0; l < parts; l++)
......@@ -387,11 +390,11 @@ namespace AMDiS {
for (i = 0; i < nBasFcts; i++) {
WARNING("not tested after index correction\n");
(*(basFcts->getD2Phi(i)))(quad->getLambda(iq), D2Phi);
(*(basFcts->getD2Phi(i)))(quad->getLambda(iq), *D2Phi);
for (k = 0; k < parts; k++)
for (l = 0; l < parts; l++)
D2Tmp[k][l] += localVec[i] * D2Phi[k][l];
D2Tmp[k][l] += localVec[i] * (*D2Phi)[k][l];
}
for (i = 0; i < dow; i++)
......
......@@ -228,7 +228,17 @@ namespace AMDiS {
* Are used to store temporary local dofs of an element.
* Thread safe.
*/
std::vector<DegreeOfFreedom* > localIndices;
std::vector<DegreeOfFreedom*> localIndices;
/** \brief
* Temporarly used in \ref getGrdAtQPs. Thread safe.
*/
std::vector<DimVec<double>*> grdPhis;
/** \brief
* Temporarly used in \ref getD2AtQPs. Thread safe.
*/
std::vector<DimMat<double>*> D2Phis;
};
......
......@@ -25,11 +25,16 @@ namespace AMDiS {
boundaryManager(NULL)
{
nBasFcts = feSpace->getBasisFcts()->getNumber();
int dim = feSpace->getMesh()->getDim();
localIndices.resize(omp_get_max_threads());
grdPhis.resize(omp_get_max_threads());
D2Phis.resize(omp_get_max_threads());
for (int i = 0; i < omp_get_max_threads(); i++) {
localIndices[i] = GET_MEMORY(DegreeOfFreedom, this->nBasFcts);
grdPhis[i] = NEW DimVec<double>(dim, DEFAULT_VALUE, 0.0);
D2Phis[i] = NEW DimMat<double>(dim, NO_INIT);
}
}
......@@ -38,6 +43,8 @@ namespace AMDiS {
{
for (int i = 0; i < static_cast<int>(localIndices.size()); i++) {
FREE_MEMORY(localIndices[i], DegreeOfFreedom, this->nBasFcts);
DELETE grdPhis[i];
DELETE D2Phis[i];
}
}
......
......@@ -29,9 +29,7 @@ namespace AMDiS {
neighbour_(mesh_->getDim(), NO_INIT),
neighbourCoord_(mesh_->getDim(), NO_INIT),
oppVertex_(mesh_->getDim(), NO_INIT),
grdLambda_(mesh_->getDim(), NO_INIT)
//parametric_(false)
grdLambda_(mesh_->getDim(), NO_INIT)
{
projection_.set(NULL);
......@@ -58,7 +56,7 @@ namespace AMDiS {
{
int dim = l.getSize() - 1;
static WorldVector<double> world[2];
static WorldVector<double> world[4];
WorldVector<double> *ret = w ? w : &world[omp_get_thread_num()];
double c = l[0];
......@@ -106,9 +104,9 @@ namespace AMDiS {
for (int i = 0; i < dow; i++) {
e1[i] = coords[1][i] - v0[i];
if(dim > 1)
if (dim > 1)
e2[i] = coords[2][i] - v0[i];
if(dim > 2)
if (dim > 2)
e3[i] = coords[3][i] - v0[i];
}
......@@ -117,22 +115,22 @@ namespace AMDiS {
det = coords[1][0] - coords[0][0];
break;
case 2:
if(dim == 1) {
if (dim == 1) {
det = norm(&e1);
} else {
det = e1[0]*e2[1] - e1[1]*e2[0];
det = e1[0] * e2[1] - e1[1] * e2[0];
}
break;
case 3:
{
WorldVector<double> n;
if (dim > 1) {
n[0] = e1[1] * e2[2] - e1[2] * e2[1];
n[1] = e1[2] * e2[0] - e1[0] * e2[2];
n[2] = e1[0] * e2[1] - e1[1] * e2[0];
}
if (dim == 1) {
det = norm(&e1);
} else if (dim == 2) {
......@@ -141,12 +139,12 @@ namespace AMDiS {
det = n[0] * e3[0] + n[1] * e3[1] + n[2] * e3[2];
} else
ERROR_EXIT("not yet for problem dimension = %d", dim);
break;
}
break;
}
default:
ERROR_EXIT("not yet for Global::getGeo(WORLD) = %d", dow);
}
return abs(det);
}
......
......@@ -159,7 +159,7 @@ namespace AMDiS {
nonLinSolver_ = nonLinSolverCreator->create();
nonLinSolver_->setVectorCreator(NEW SystemVector::Creator("temp",
componentSpaces_,
numComponents_));
nComponents));
}
......@@ -171,13 +171,13 @@ namespace AMDiS {
void ProblemNonLinVec::buildAfterCoarsen(AdaptInfo *adaptInfo, Flag)
{
FUNCNAME("ProblemNonLinVec::buildAfterCoarsen()");
int i, numMeshes = static_cast<int>(meshes_.size());
int nMeshes = static_cast<int>(meshes_.size());
for(i = 0; i < numMeshes; i++) {
for (int i = 0; i < nMeshes; i++) {
meshes_[i]->dofCompress();
}
for(i = 0; i < numComponents_; i++) {
for (int i = 0; i < nComponents; i++) {
MSG("%d DOFs for %s\n",
componentSpaces_[i]->getAdmin()->getUsedSize(),
componentSpaces_[i]->getName().c_str());
......@@ -187,15 +187,15 @@ namespace AMDiS {
ElInfo *elInfo;
// for all elements ...
for(i = 0; i < numComponents_; i++) {
for (int i = 0; i < nComponents; i++) {
elInfo = stack.traverseFirst(componentMeshes_[i], -1,
Mesh::CALL_LEAF_EL |
Mesh::FILL_BOUND |
Mesh::FILL_COORDS |
Mesh::FILL_DET |
Mesh::FILL_GRD_LAMBDA);
while(elInfo) {
if(solution_->getDOFVector(i)->getBoundaryManager()) {
while (elInfo) {
if (solution_->getDOFVector(i)->getBoundaryManager()) {
solution_->getDOFVector(i)->
getBoundaryManager()->fillBoundaryConditions(elInfo, solution_->getDOFVector(i));
}
......
......@@ -167,7 +167,7 @@ namespace AMDiS {
nonLinSolver_(NULL),
updater_(NULL)
{
u0_.resize(numComponents_);
u0_.resize(nComponents);
u0_.set(NULL);
};
......@@ -178,7 +178,7 @@ namespace AMDiS {
int index)
{
FUNCNAME("ProblemNonLinVec::setU0()");
TEST_EXIT(index < numComponents_)("invalid index\n");
TEST_EXIT(index < nComponents)("invalid index\n");
u0_[index] = u0Fct;
solution_->getDOFVector(index)->interpol(u0Fct);
};
......
......@@ -130,7 +130,7 @@ namespace AMDiS {
// before timeout of the runqueue.
int readSerialization = 0;
::std::string serializationFilename = "";
std::string serializationFilename = "";
GET_PARAMETER(0, "argv->rs", &serializationFilename);
// If the parameter -rs is set, we do nothing here, because the problem will be
......@@ -153,24 +153,21 @@ namespace AMDiS {
TEST_EXIT(serializationFilename != "")("no serialization file\n");
MSG("Deserialization from file: %s\n", serializationFilename.c_str());
::std::ifstream in(serializationFilename.c_str());
std::ifstream in(serializationFilename.c_str());
deserialize(in);
in.close();
} else {
int globalRefinements = 0;
GET_PARAMETER(0, meshes_[0]->getName() + "->global refinements", "%d",
&globalRefinements);
// Initialize the meshes if there is no serialization file.
for (int i = 0; i < static_cast<int>(meshes_.size()); i++) {
if (initFlag.isSet(INIT_MESH) &&
meshes_[i] &&
!(meshes_[i]->isInitialized())) {
meshes_[i]->initialize();
// do global refinements
int globalRefinements = 0;
GET_PARAMETER(0, meshes_[0]->getName() + "->global refinements", "%d",
&globalRefinements);
for (int gr = 0; gr < static_cast<int>(meshes_.size()); gr++) {
refinementManager_->globalRefine(meshes_[gr], globalRefinements);
}
meshes_[i]->initialize();
refinementManager_->globalRefine(meshes_[i], globalRefinements);
}
}
}
......@@ -183,23 +180,22 @@ namespace AMDiS {
{
FUNCNAME("ProblemVec::createMesh()");
componentMeshes_.resize(numComponents_);
::std::map<int, Mesh*> meshForRefinementSet;
componentMeshes_.resize(nComponents);
std::map<int, Mesh*> meshForRefinementSet;
char number[3];
::std::string meshName("");
std::string meshName("");
GET_PARAMETER(0, name_ + "->mesh", &meshName);
TEST_EXIT(meshName != "")("no mesh name spezified\n");
int dim = 0;
GET_PARAMETER(0, name_ + "->dim", "%d", &dim);
TEST_EXIT(dim)("no problem dimension spezified!\n");
for (int i = 0; i < numComponents_; i++) {
for (int i = 0; i < nComponents; i++) {
sprintf(number, "%d", i);
int refSet = -1;
GET_PARAMETER(0, name_ + "->refinement set[" + number + "]", "%d", &refSet);
if (refSet < 0) {
WARNING("refinement set for component %d not set\n", i);
refSet = 0;
}
if (meshForRefinementSet[refSet] == NULL) {
......@@ -234,30 +230,30 @@ namespace AMDiS {
int degree = 1;
char number[3];
::std::map< ::std::pair<Mesh*, int>, FiniteElemSpace*> feSpaceMap;
std::map< std::pair<Mesh*, int>, FiniteElemSpace*> feSpaceMap;
int dim = -1;
GET_PARAMETER(0, name_ + "->dim", "%d", &dim);
TEST_EXIT(dim != -1)("no problem dimension spezified!\n");
componentSpaces_.resize(numComponents_, NULL);
componentSpaces_.resize(nComponents, NULL);
for (int i = 0; i < numComponents_; i++) {
for (int i = 0; i < nComponents; i++) {
sprintf(number, "%d", i);
GET_PARAMETER(0, name_ + "->polynomial degree[" + number + "]","%d", &degree);
TEST_EXIT(componentSpaces_[i] == NULL)("feSpace already created\n");
if (feSpaceMap[::std::pair<Mesh*, int>(componentMeshes_[i], degree)] == NULL) {
if (feSpaceMap[std::pair<Mesh*, int>(componentMeshes_[i], degree)] == NULL) {
FiniteElemSpace *newFESpace =
FiniteElemSpace::provideFESpace(NULL,
Lagrange::getLagrange(dim, degree),
componentMeshes_[i],
name_ + "->feSpace");
feSpaceMap[::std::pair<Mesh*, int>(componentMeshes_[i], degree)] = newFESpace;
feSpaceMap[std::pair<Mesh*, int>(componentMeshes_[i], degree)] = newFESpace;
feSpaces_.push_back(newFESpace);
}
componentSpaces_[i] =
feSpaceMap[::std::pair<Mesh*, int>(componentMeshes_[i], degree)];
feSpaceMap[std::pair<Mesh*, int>(componentMeshes_[i], degree)];
}
// create dof admin for vertex dofs if neccessary
......@@ -278,21 +274,21 @@ namespace AMDiS {
// === create vectors and system matrix ===
systemMatrix_ = NEW Matrix<DOFMatrix*>(numComponents_, numComponents_);
systemMatrix_ = NEW Matrix<DOFMatrix*>(nComponents, nComponents);
systemMatrix_->set(NULL);
rhs_ = NEW SystemVector("rhs", componentSpaces_, numComponents_);
solution_ = NEW SystemVector("solution", componentSpaces_, numComponents_);
rhs_ = NEW SystemVector("rhs", componentSpaces_, nComponents);
solution_ = NEW SystemVector("solution", componentSpaces_, nComponents);
char number[10];
::std::string numberedName;
for (i = 0; i < numComponents_; i++) {
std::string numberedName;
for (i = 0; i < nComponents; i++) {
(*systemMatrix_)[i][i] = NEW DOFMatrix(componentSpaces_[i],
componentSpaces_[i], "A_ii");
(*systemMatrix_)[i][i]->setCoupleMatrix(false);
sprintf(number, "[%d]", i);
numberedName = "rhs" + ::std::string(number);
numberedName = "rhs" + std::string(number);
rhs_->setDOFVector(i, NEW DOFVector<double>(componentSpaces_[i], numberedName));
numberedName = name_ + ::std::string(number);
numberedName = name_ + std::string(number);
solution_->setDOFVector(i, NEW DOFVector<double>(componentSpaces_[i],
numberedName));
solution_->getDOFVector(i)->refineInterpol(true);
......@@ -309,7 +305,7 @@ namespace AMDiS {
FUNCNAME("ProblemVec::createSolver()");
// === create solver ===
::std::string solverType("no");
std::string solverType("no");
GET_PARAMETER(0, name_ + "->solver", &solverType);
OEMSolverCreator<SystemVector> *solverCreator =
dynamic_cast<OEMSolverCreator<SystemVector>*>(
......@@ -322,10 +318,10 @@ namespace AMDiS {
solver_->initParameters();
// === create preconditioners ===
::std::string preconType("no");
std::string preconType("no");
PreconditionerScal *scalPrecon;
PreconditionerVec *vecPrecon = NEW PreconditionerVec(numComponents_);
PreconditionerVec *vecPrecon = NEW PreconditionerVec(nComponents);
GET_PARAMETER(0, name_ + "->solver->left precon", &preconType);
CreatorInterface<PreconditionerScal> *preconCreator =
......@@ -337,12 +333,12 @@ namespace AMDiS {
dynamic_cast<PreconditionerScalCreator*>(preconCreator)->
setName(name_ + "->solver->left precon");
for(i = 0; i < numComponents_; i++) {
for(i = 0; i < nComponents; i++) {
dynamic_cast<PreconditionerScalCreator*>(preconCreator)->
setSizeAndRow(numComponents_, i);
setSizeAndRow(nComponents, i);
scalPrecon = preconCreator->create();
for(j = 0; j < numComponents_; j++) {
for(j = 0; j < nComponents; j++) {
scalPrecon->setMatrix(&(*systemMatrix_)[i][j], j);
}
vecPrecon->setScalarPrecon(i, scalPrecon);
......@@ -351,7 +347,7 @@ namespace AMDiS {
}
vecPrecon = NEW PreconditionerVec(numComponents_);
vecPrecon = NEW PreconditionerVec(nComponents);
GET_PARAMETER(0, name_ + "->solver->right precon", &preconType);
preconCreator =
......@@ -362,12 +358,12 @@ namespace AMDiS {
setName(name_ + "->solver->left precon");
for(i = 0; i < numComponents_; i++) {
for(i = 0; i < nComponents; i++) {
dynamic_cast<PreconditionerScalCreator*>(preconCreator)->
setSizeAndRow(numComponents_, i);
setSizeAndRow(nComponents, i);
scalPrecon = preconCreator->create();
for(j = 0; j < numComponents_; j++) {
for(j = 0; j < nComponents; j++) {
scalPrecon->setMatrix(&(*systemMatrix_)[i][j], j);
}
vecPrecon->setScalarPrecon(i, scalPrecon);
......@@ -379,7 +375,7 @@ namespace AMDiS {
// === create vector creator ===
solver_->setVectorCreator(NEW SystemVector::Creator("temp",
componentSpaces_,
numComponents_));
nComponents));
}
void ProblemVec::createEstimator()
......@@ -395,15 +391,15 @@ namespace AMDiS {
}
char number[3];
::std::string estName;
std::string estName;
for(i = 0; i < numComponents_; i++) {
for(i = 0; i < nComponents; i++) {
TEST_EXIT(estimator_[i] == NULL)("estimator already created\n");
sprintf(number, "%d", i);
estName = name_ + "->estimator[" + ::std::string(number) + "]";
estName = name_ + "->estimator[" + std::string(number) + "]";
// === create estimator ===
::std::string estimatorType("no");
std::string estimatorType("no");
GET_PARAMETER(0, estName, &estimatorType);
EstimatorCreator *estimatorCreator =
dynamic_cast<EstimatorCreator*>(
......@@ -420,7 +416,7 @@ namespace AMDiS {
if(estimator_[i]) {
for(j=0; j < numComponents_; j++) {
for(j=0; j < nComponents; j++) {
estimator_[i]->addSystem((*systemMatrix_)[i][j],
solution_->getDOFVector(j),
rhs_->getDOFVector(j));
......@@ -433,13 +429,13 @@ namespace AMDiS {
{
FUNCNAME("ProblemVec::createMarker()");
::std::string numberedName;
std::string numberedName;
char number[10];
int numMarkersCreated = 0;
for (int i = 0; i < numComponents_; i++) {
for (int i = 0; i < nComponents; i++) {
sprintf(number, "[%d]", i);
numberedName = name_ + "->marker" + ::std::string(number);
numberedName = name_ + "->marker" + std::string(number);
marker_[i] = Marker::createMarker(numberedName, i);
if (marker_[i]) {
numMarkersCreated++;
......@@ -455,14 +451,14 @@ namespace AMDiS {
// Create one filewriter for all components of the problem
::std::string numberedName = name_ + "->output";
::std::string filename = "";
std::string numberedName = name_ + "->output";
std::string filename = "";
GET_PARAMETER(0, numberedName + "->filename", &filename);
if (filename != "") {
::std::vector< DOFVector<double>* > solutionList(numComponents_);
std::vector< DOFVector<double>* > solutionList(nComponents);
for (int i = 0; i < numComponents_; i++) {
for (int i = 0; i < nComponents; i++) {
TEST_EXIT(componentMeshes_[0] == componentMeshes_[i])
("All Meshes have to be equal to write a vector file.\n");
......@@ -477,9 +473,9 @@ namespace AMDiS {
// Create own filewriters for each components of the problem
char number[10];
for (int i = 0; i < numComponents_; i++) {
for (int i = 0; i < nComponents; i++) {
sprintf(number, "[%d]", i);
numberedName = name_ + "->output" + ::std::string(number);
numberedName = name_ + "->output" + std::string(number);
filename = "";
GET_PARAMETER(0, numberedName + "->filename", &filename);
......@@ -552,7 +548,7 @@ namespace AMDiS {
double wtime = omp_get_wtime();
#endif
for (int i = 0; i < numComponents_; i++) {
for (int i = 0; i < nComponents; i++) {
Estimator *scalEstimator = estimator_[i];
if (scalEstimator) {
......@@ -587,7 +583,7 @@ namespace AMDiS {
allowFirstRefinement();
Flag markFlag = 0;
for (int i = 0; i < numComponents_; i++) {
for (int i = 0; i < nComponents; i++) {
if (marker_[i]) {
markFlag |= marker_[i]->markMesh(adaptInfo, componentMeshes_[i]);
} else {
......@@ -631,12 +627,12 @@ namespace AMDiS {
FUNCNAME("ProblemVec::oneIteration()");
if (allowFirstRef_) {
for (int i = 0; i < numComponents_; i++) {
for (int i = 0; i < nComponents; i++) {
adaptInfo->allowRefinement(true, i);
}
allowFirstRef_ = false;
} else {
for (int i = 0; i < numComponents_; i++) {
for (int i = 0; i < nComponents; i++) {
if (adaptInfo->spaceToleranceReached(i)) {
adaptInfo->allowRefinement(false, i);
} else {
......@@ -677,13 +673,13 @@ namespace AMDiS {
}
for (int i = 0; i < numComponents_; i++) {
for (int i = 0; i < nComponents; i++) {
MSG("%d DOFs for %s\n",
componentSpaces_[i]->getAdmin()->getUsedSize(),
componentSpaces_[i]->getName().c_str());
rhs_->getDOFVector(i)->set(0.0);
for (int j = 0; j < numComponents_; j++) {
for (int j = 0; j < nComponents; j++) {
if ((*systemMatrix_)[i][j]) {
// The matrix should not be deleted, if it was assembled before
// and it is marked to be assembled only once.
......@@ -698,10 +694,10 @@ namespace AMDiS {
#ifdef _OPENMP
#pragma omp parallel for
#endif
for (i = 0; i < numComponents_; i++) {
for (i = 0; i < nComponents; i++) {
const BasisFunction *basisFcts = componentSpaces_[i]->getBasisFcts();
for (int j = 0; j < numComponents_; j++) {
for (int j = 0; j < nComponents; j++) {
// Only if this variable is true, the current matrix will be assembled.
bool assembleMatrix = true;
// The DOFMatrix which should be assembled (or not, if assembleMatrix
......@@ -739,30 +735,29 @@ namespace AMDiS {
TraverseStack stack;
ElInfo *elInfo = stack.traverseFirst(componentMeshes_[i], -1, assembleFlag);
while (elInfo) {
if (useGetBound_) {
basisFcts->getBound(elInfo, bound);
}
if (assembleMatrix) {
matrix->assemble(1.0, elInfo, bound);
if (matrix->getBoundaryManager()) {
matrix->
getBoundaryManager()->
fillBoundaryConditions(elInfo, matrix);
fillBoundaryConditions(elInfo, matrix);
}
}
if (i == j) {
rhs_->getDOFVector(i)->assemble(1.0, elInfo, bound);
}
elInfo = stack.traverseNext(elInfo);
}
if (assembleMatrix && matrix->getBoundaryManager())
matrix->getBoundaryManager()->exitMatrix(matrix);
......@@ -856,7 +851,7 @@ namespace AMDiS {
return false;
}
void ProblemVec::interpolInitialSolution(::std::vector<AbstractFunction<double, WorldVector<double> >*> *fct)
void ProblemVec::interpolInitialSolution(std::vector<AbstractFunction<double, WorldVector<double> >*> *fct)
{
FUNCNAME("ProblemVec::interpolInitialSolution()");