From be06847b30df4dce8dc92ec58fa635fe86936372 Mon Sep 17 00:00:00 2001 From: Thomas Witkowski <thomas.witkowski@gmx.de> Date: Tue, 9 Jun 2009 16:20:40 +0000 Subject: [PATCH] Work in progress on parallel domain decomposition. --- AMDiS/src/DataCollector.cc | 106 ++++++++++------------------- AMDiS/src/DataCollector.h | 14 ++-- AMDiS/src/ParallelDomainProblem.cc | 78 +++++++++++++++++---- AMDiS/src/ParallelDomainProblem.h | 4 +- AMDiS/src/VtkWriter.cc | 3 +- AMDiS/src/VtkWriter.h | 26 +++---- AMDiS/src/VtkWriter.hh | 11 ++- 7 files changed, 128 insertions(+), 114 deletions(-) diff --git a/AMDiS/src/DataCollector.cc b/AMDiS/src/DataCollector.cc index b533bc57..30feb017 100644 --- a/AMDiS/src/DataCollector.cc +++ b/AMDiS/src/DataCollector.cc @@ -6,6 +6,7 @@ #include "Projection.h" namespace AMDiS { + DataCollector::DataCollector(const FiniteElemSpace *feSpace, DOFVector<double> *values, int level, @@ -61,20 +62,17 @@ namespace AMDiS { void DataCollector::fillAllData() { - if (!elementDataCollected_) { + if (!elementDataCollected_) startCollectingElementData(); - } - if (!periodicDataCollected_) { + if (!periodicDataCollected_) startCollectingPeriodicData(); - } - if (!valueDataCollected_) { + if (!valueDataCollected_) startCollectingValueData(); - } } - int DataCollector::startCollectingElementData() + void DataCollector::startCollectingElementData() { FUNCNAME("DataCollector::startCollectingElementData()"); @@ -99,26 +97,24 @@ namespace AMDiS { // Traverse elements to create element information elInfo = stack.traverseFirst(mesh_, level_, flag); + while (elInfo) { - if (!writeElem_ || writeElem_(elInfo)) { + if (!writeElem_ || writeElem_(elInfo)) addElementData(elInfo); - } + elInfo = stack.traverseNext(elInfo); } elementDataCollected_ = true; - - return(0); } - int DataCollector::startCollectingValueData() + void DataCollector::startCollectingValueData() { FUNCNAME("DataCollector::startCollectingValueData()"); DOFVector<int>::Iterator intPointIt(interpPointInd_, USED_DOFS); - for (intPointIt.reset(); !intPointIt.end(); ++intPointIt) { + for (intPointIt.reset(); !intPointIt.end(); ++intPointIt) (*intPointIt) = -1; - } interpPoints_.clear(); @@ -130,13 +126,11 @@ namespace AMDiS { // Traverse elements to add value information and to mark // interpolation points. - ElInfo *elInfo = stack.traverseFirst(mesh_, - level_, + ElInfo *elInfo = stack.traverseFirst(mesh_, level_, traverseFlag_ | Mesh::FILL_COORDS); while (elInfo) { - if (!writeElem_ || writeElem_(elInfo)) { + if (!writeElem_ || writeElem_(elInfo)) addValueData(elInfo); - } elInfo = stack.traverseNext(elInfo); } @@ -146,11 +140,9 @@ namespace AMDiS { // Remove all interpolation marks and, instead, set to each // interpolation point its continous index starting from 0. int i = 0; - for (intPointIt.reset(); !intPointIt.end(); ++intPointIt) { - if (*intPointIt == -3) { + for (intPointIt.reset(); !intPointIt.end(); ++intPointIt) + if (*intPointIt == -3) *intPointIt = i++; - } - } // Traverse elements to create interpolation values. elInfo = stack.traverseFirst(mesh_, level_, traverseFlag_ | Mesh::FILL_COORDS); @@ -163,11 +155,9 @@ namespace AMDiS { delete [] localDOFs_; valueDataCollected_ = true; - - return 0; } - int DataCollector::startCollectingPeriodicData() + void DataCollector::startCollectingPeriodicData() { FUNCNAME("DataCollector::startCollectingPeriodicData()"); @@ -210,11 +200,9 @@ namespace AMDiS { } periodicDataCollected_ = true; - - return(0); } - int DataCollector::addElementData(ElInfo* elInfo) + void DataCollector::addElementData(ElInfo* elInfo) { FUNCNAME("DataCollector::addElementData()"); @@ -280,19 +268,15 @@ namespace AMDiS { outputIndices_[elInfo->getNeighbour(i)->getIndex()] : -1; } - - if (dim_ == 3) { + if (dim_ == 3) elementInfo.type = (dynamic_cast<ElInfo3d*>(elInfo)->getType()); - } // remember element info elements_.push_back(elementInfo); - - return(0); } - int DataCollector::addValueData(ElInfo *elInfo) + void DataCollector::addValueData(ElInfo *elInfo) { FUNCNAME("DataCollector::addValueData()"); @@ -345,28 +329,24 @@ namespace AMDiS { nInterpPoints_++; } } - } - - return(0); + } } - int DataCollector::addInterpData(ElInfo *elInfo) + void DataCollector::addInterpData(ElInfo *elInfo) { FUNCNAME("DataCollector::addInterpData()"); basisFcts_->getLocalIndices(elInfo->getElement(), localAdmin_, localDOFs_); std::vector<int> elemInterpPoints(0); - for (int i = mesh_->getGeo(VERTEX); i < nBasisFcts_; i++) { + for (int i = mesh_->getGeo(VERTEX); i < nBasisFcts_; i++) elemInterpPoints.push_back((*interpPointInd_)[localDOFs_[i]]); - } - interpPoints_.push_back(elemInterpPoints); - - return(0); + interpPoints_.push_back(elemInterpPoints); } - int DataCollector::addPeriodicData(ElInfo *elInfo) { + void DataCollector::addPeriodicData(ElInfo *elInfo) + { FUNCNAME("DataCollector::addPeriodicData"); LeafDataPeriodic *ldp = dynamic_cast<LeafDataPeriodic*> @@ -423,69 +403,60 @@ namespace AMDiS { } } } - - return(0); } std::list<ElementInfo>* DataCollector::getElementInfos() { - if (!elementDataCollected_) { + if (!elementDataCollected_) startCollectingElementData(); - } return &elements_; } DOFVector< std::list<VertexInfo> >* DataCollector::getVertexInfos() { - if (!elementDataCollected_) { + if (!elementDataCollected_) startCollectingElementData(); - } return vertexInfos_; } std::list<PeriodicInfo>* DataCollector::getPeriodicInfos() { - if (!periodicDataCollected_) { + if (!periodicDataCollected_) startCollectingPeriodicData(); - } return &periodicInfos_; } int DataCollector::getNumberVertices() { - if (!elementDataCollected_) { + if (!elementDataCollected_) startCollectingElementData(); - } return nVertices_; } int DataCollector::getNumberElements() { - if (!elementDataCollected_) { + if (!elementDataCollected_) startCollectingElementData(); - } return nElements_; } int DataCollector::getNumberInterpPoints() { - if (!valueDataCollected_) { + if (!valueDataCollected_) startCollectingValueData(); - } return nInterpPoints_; } int DataCollector::getNumberConnections() { - if (!periodicDataCollected_) { + if (!periodicDataCollected_) startCollectingPeriodicData(); - } return nConnections_; } @@ -502,45 +473,40 @@ namespace AMDiS { DOFVector<double>* DataCollector::getValues() { - if (!valueDataCollected_) { + if (!valueDataCollected_) startCollectingValueData(); - } return values_; } DOFVector< std::list<WorldVector<double> > >* DataCollector::getDofCoords() { - if (!valueDataCollected_) { + if (!valueDataCollected_) startCollectingValueData(); - } return dofCoords_; } DOFVector<int>* DataCollector::getInterpPointInd() { - if (!valueDataCollected_) { + if (!valueDataCollected_) startCollectingValueData(); - } return interpPointInd_; } DOFVector< std::list<WorldVector<double> > >* DataCollector::getInterpPointCoords() { - if (!valueDataCollected_) { + if (!valueDataCollected_) startCollectingValueData(); - } return interpPointCoords_; } std::vector< std::vector<int> >* DataCollector::getInterpPoints() { - if (!valueDataCollected_) { + if (!valueDataCollected_) startCollectingValueData(); - } return &interpPoints_; } diff --git a/AMDiS/src/DataCollector.h b/AMDiS/src/DataCollector.h index d46af551..57234325 100644 --- a/AMDiS/src/DataCollector.h +++ b/AMDiS/src/DataCollector.h @@ -101,25 +101,25 @@ namespace AMDiS { protected: /// Start collecting element and vertex data of the problem. - int startCollectingElementData(); + void startCollectingElementData(); /// Start collecting value data of the problem. - int startCollectingValueData(); + void startCollectingValueData(); /// Start collecting periodic data of the problem. - int startCollectingPeriodicData(); + void startCollectingPeriodicData(); /// Adds information about one element and its vertices. - int addElementData(ElInfo* elInfo); + void addElementData(ElInfo* elInfo); /// Adds value information of one element. - int addValueData(ElInfo *elInfo); + void addValueData(ElInfo *elInfo); /// Adds information about interpolation points of vertices. - int addInterpData(ElInfo *elInfo); + void addInterpData(ElInfo *elInfo); /// Adds value information of one element. - int addPeriodicData(ElInfo *elInfo); + void addPeriodicData(ElInfo *elInfo); /// Vector with vertex values DOFVector<double> *values_; diff --git a/AMDiS/src/ParallelDomainProblem.cc b/AMDiS/src/ParallelDomainProblem.cc index 7cf96050..126ba828 100644 --- a/AMDiS/src/ParallelDomainProblem.cc +++ b/AMDiS/src/ParallelDomainProblem.cc @@ -10,6 +10,9 @@ #include "PartitionElementData.h" #include "DOFMatrix.h" #include "DOFVector.h" +#include "VtkWriter.h" + +#include "petscksp.h" namespace AMDiS { @@ -138,9 +141,8 @@ namespace AMDiS { PartitionElementData *partitionData = dynamic_cast<PartitionElementData*> ((*it)->getElement()->getElementData(PARTITION_ED)); - if (partitionData->getPartitionStatus() != IN) { + if (partitionData->getPartitionStatus() != IN) macrosToRemove.push_back(*it); - } } mesh->removeMacroElements(macrosToRemove); @@ -151,17 +153,15 @@ namespace AMDiS { int *lOrder = (int*)(malloc(sizeof(int) * rankDofs.size())); for (std::vector<const DegreeOfFreedom*>::iterator it = rankDofs.begin(); - it != rankDofs.end(); ++it) { + it != rankDofs.end(); ++it) gOrder[nRankDOFs++] = (*it)[0]; - } int rstart = 0; MPI_Scan(&nRankDOFs, &rstart, 1, MPI_INT, MPI_SUM, PETSC_COMM_WORLD); rstart -= nRankDOFs; - for (int i = 0; i < nRankDOFs; i++) { + for (int i = 0; i < nRankDOFs; i++) lOrder[i] = rstart + i; - } AOCreateBasic(PETSC_COMM_WORLD, nRankDOFs, gOrder, lOrder, &applicationOrdering); @@ -275,6 +275,10 @@ namespace AMDiS { ierr = VecCreate(PETSC_COMM_WORLD, &petscRhsVec); ierr = VecSetSizes(petscRhsVec, rankDofs.size(), partitionDofs.size()); ierr = VecSetType(petscRhsVec, VECMPI); + + ierr = VecCreate(PETSC_COMM_WORLD, &petscSolVec); + ierr = VecSetSizes(petscSolVec, rankDofs.size(), partitionDofs.size()); + ierr = VecSetType(petscSolVec, VECMPI); } void ParallelDomainProblemBase::exitParallelization(AdaptInfo *adaptInfo) @@ -285,14 +289,27 @@ namespace AMDiS { void ParallelDomainProblemBase::fillPetscMatrix(DOFMatrix *mat, DOFVector<double> *vec) { - /* DOFMatrix::Iterator rowIt(mat, USED_DOFS); - for (rowIt.reset(); !rowIt.end(); ++rowIt) { - for (int i = 0; i < static_cast<int>((*rowIt).size()); i++) { - if ((*rowIt)[i].col >= 0) { - MatSetValues(petscMatrix, 1, &i, 1, &((*rowIt)[i].col), &((*rowIt)[i].entry), ADD_VALUES); + using mtl::tag::major; using mtl::tag::nz; using mtl::begin; using mtl::end; + namespace traits= mtl::traits; + typedef DOFMatrix::base_matrix_type Matrix; + + traits::row<Matrix>::type row(mat->getBaseMatrix()); + traits::col<Matrix>::type col(mat->getBaseMatrix()); + traits::const_value<Matrix>::type value(mat->getBaseMatrix()); + + typedef traits::range_generator<major, Matrix>::type cursor_type; + typedef traits::range_generator<nz, cursor_type>::type icursor_type; + + std::cout.precision(10); + for (cursor_type cursor = begin<major>(mat->getBaseMatrix()), cend = end<major>(mat->getBaseMatrix()); cursor != cend; ++cursor) + for (icursor_type icursor = begin<nz>(cursor), icend = end<nz>(cursor); icursor != icend; ++icursor) + if (value(*icursor) != 0.0) { + int r = row(*icursor); + int c = col(*icursor); + double v = value(*icursor); + MatSetValues(petscMatrix, 1, &r, 1, &c, &v, ADD_VALUES); } - } - } + MatAssemblyBegin(petscMatrix, MAT_FINAL_ASSEMBLY); MatAssemblyEnd(petscMatrix, MAT_FINAL_ASSEMBLY); @@ -303,7 +320,38 @@ namespace AMDiS { double value = *dofIt; VecSetValues(petscRhsVec, 1, &index, &value, ADD_VALUES); - }*/ + } + } + + void ParallelDomainProblemBase::solvePetscMatrix(DOFVector<double> *vec) + { + KSP ksp; + PC pc; + + KSPCreate(PETSC_COMM_WORLD, &ksp); + KSPSetOperators(ksp, petscMatrix, petscMatrix, DIFFERENT_NONZERO_PATTERN); + KSPGetPC(ksp, &pc); + PCSetType(pc, PCJACOBI); + KSPSetTolerances(ksp, 1.e-7, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT); + KSPSetType(ksp, KSPBCGS); + KSPMonitorSet(ksp, KSPMonitorDefault, PETSC_NULL, 0); + KSPSolve(ksp, petscRhsVec, petscSolVec); + + PetscScalar *vecPointer; + VecGetArray(petscSolVec, &vecPointer); + + DOFVector<double>::Iterator dofIt(vec, USED_DOFS); + int counter = 0; + for (dofIt.reset(); !dofIt.end(); ++dofIt) + *vec = vecPointer[counter++]; + + VecRestoreArray(petscSolVec, &vecPointer); + + std::stringstream oss; + oss << "test" << MPI::COMM_WORLD.Get_rank() << ".vtu"; + VtkWriter::writeFile(vec, oss.str()); + + std::cout << "USED SIZE = " << vec->getUsedSize() << std::endl; } double ParallelDomainProblemBase::setElemWeights(AdaptInfo *adaptInfo) @@ -370,6 +418,8 @@ namespace AMDiS { fillPetscMatrix(probScal->getSystemMatrix(), probScal->getRHS()); + solvePetscMatrix(probScal->getSolution()); + // if (toDo.isSet(SOLVE)) // iterationIF->getProblem()->solve(adaptInfo, false); diff --git a/AMDiS/src/ParallelDomainProblem.h b/AMDiS/src/ParallelDomainProblem.h index 3da0ec43..c5ad751d 100644 --- a/AMDiS/src/ParallelDomainProblem.h +++ b/AMDiS/src/ParallelDomainProblem.h @@ -105,6 +105,8 @@ namespace AMDiS { void fillPetscMatrix(DOFMatrix *mat, DOFVector<double> *vec); + void solvePetscMatrix(DOFVector<double> *vec); + virtual ProblemStatBase *getProblem(int number = 0) {} virtual void serialize(std::ostream&) {} @@ -168,7 +170,7 @@ namespace AMDiS { Vec petscRhsVec; - Vec petscSolutionVec; + Vec petscSolVec; /// Number of DOFs in the rank mesh. int nRankDOFs; diff --git a/AMDiS/src/VtkWriter.cc b/AMDiS/src/VtkWriter.cc index c995213e..151ef4d4 100644 --- a/AMDiS/src/VtkWriter.cc +++ b/AMDiS/src/VtkWriter.cc @@ -75,8 +75,7 @@ namespace AMDiS { return 0; } - void VtkWriter::writeFile(DOFVector<double> *values, - const char *filename) + void VtkWriter::writeFile(DOFVector<double> *values, const std::string filename) { DataCollector *dc = new DataCollector(values->getFESpace(), values); diff --git a/AMDiS/src/VtkWriter.h b/AMDiS/src/VtkWriter.h index 65d71fca..645ce6d9 100644 --- a/AMDiS/src/VtkWriter.h +++ b/AMDiS/src/VtkWriter.h @@ -51,11 +51,11 @@ namespace AMDiS { int writeFile(const std::string name); /// May be used to simply write ParaView files. - static void writeFile(DOFVector<double> *values, - const char *filename); + static void writeFile(DOFVector<double> *values, const std::string filename); /// Set a compressing method for file output. - void setCompression(FileCompression c) { + void setCompression(FileCompression c) + { compress = c; } @@ -95,25 +95,25 @@ namespace AMDiS { #ifdef HAVE_BOOST /// Writes a world coordinate to a given file. inline void writeCoord(boost::iostreams::filtering_ostream &file, - WorldVector<double> coord) { - for (int i = 0; i < Global::getGeo(WORLD); i++) { + WorldVector<double> coord) + { + for (int i = 0; i < Global::getGeo(WORLD); i++) file << " " << std::scientific << coord[i]; - } - for (int i = Global::getGeo(WORLD); i < 3; i++) { + for (int i = Global::getGeo(WORLD); i < 3; i++) file << " 0.0"; - } + file << "\n"; } #endif /// Writes a world coordinate to a given file. - inline void writeCoord(std::ofstream &file, WorldVector<double> coord) { - for (int i = 0; i < Global::getGeo(WORLD); i++) { + inline void writeCoord(std::ofstream &file, WorldVector<double> coord) + { + for (int i = 0; i < Global::getGeo(WORLD); i++) file << " " << std::scientific << coord[i]; - } - for (int i = Global::getGeo(WORLD); i < 3; i++) { + for (int i = Global::getGeo(WORLD); i < 3; i++) file << " 0.0"; - } + file << "\n"; } diff --git a/AMDiS/src/VtkWriter.hh b/AMDiS/src/VtkWriter.hh index 42f39a44..856285ac 100644 --- a/AMDiS/src/VtkWriter.hh +++ b/AMDiS/src/VtkWriter.hh @@ -97,7 +97,7 @@ namespace AMDiS { for (it2 = it->begin(); it2 != it->end(); ++it2) { it2->outputIndex = counter++; writeCoord(file, it2->coords); - } + } } // For the second dim case, write also the interpolation points. @@ -107,9 +107,8 @@ namespace AMDiS { for (pointIt.reset(); !pointIt.end(); ++pointIt) { std::list< WorldVector<double> >::iterator it2; - for (it2 = pointIt->begin(); it2 != pointIt->end(); ++it2) { + for (it2 = pointIt->begin(); it2 != pointIt->end(); ++it2) writeCoord(file, *it2); - } } } } @@ -147,9 +146,8 @@ namespace AMDiS { ++intPointIt, ++valueIt, ++coordIt) { if (*intPointIt == -2) { - for (int i = 0; i < static_cast<int>(coordIt->size()); i++) { + for (int i = 0; i < static_cast<int>(coordIt->size()); i++) file << " " << (fabs(*valueIt) < 1e-40 ? 0.0 : *valueIt) << "\n"; - } } } @@ -163,9 +161,8 @@ namespace AMDiS { ++intPointIt, ++valueIt, ++interpCoordIt) { if (*intPointIt >= 0) { - for (int i = 0; i < static_cast<int>(interpCoordIt->size()); i++) { + for (int i = 0; i < static_cast<int>(interpCoordIt->size()); i++) file << " " << (fabs(*valueIt) < 1e-40 ? 0.0 : *valueIt) << "\n"; - } } } } -- GitLab