From bc5b945f8e70fe454ba8f1efe815755adec2ec39 Mon Sep 17 00:00:00 2001 From: Thomas Witkowski <thomas.witkowski@gmx.de> Date: Wed, 2 Sep 2009 13:49:58 +0000 Subject: [PATCH] Serveral bug fixes for parallelization. --- AMDiS/libtool | 18 +-- AMDiS/src/DOFVector.hh | 17 +-- AMDiS/src/Element.cc | 14 +- AMDiS/src/ElementDofIterator.h | 2 +- AMDiS/src/Mesh.cc | 30 ++++ AMDiS/src/Mesh.h | 7 + AMDiS/src/ParallelDomainBase.cc | 70 +++++---- AMDiS/src/ProblemVec.cc | 263 +++++++++++++++++++++++++++----- AMDiS/src/ProblemVec.h | 30 ++-- AMDiS/src/SubAssembler.cc | 9 +- AMDiS/src/ZeroOrderAssembler.cc | 30 ++-- 11 files changed, 349 insertions(+), 141 deletions(-) diff --git a/AMDiS/libtool b/AMDiS/libtool index 41ace2e6..9fbd8125 100755 --- a/AMDiS/libtool +++ b/AMDiS/libtool @@ -82,13 +82,13 @@ AR="ar" AR_FLAGS="cru" # A C compiler. -LTCC="gcc" +LTCC="/usr/lib/openmpi/1.2.7-gcc//bin/mpicc" # LTCC compiler flags. LTCFLAGS="-g -O2" # A language-specific compiler. -CC="gcc" +CC="/usr/lib/openmpi/1.2.7-gcc//bin/mpicc" # Is the compiler the GNU C compiler? with_gcc=yes @@ -171,7 +171,7 @@ dlopen_self=unknown dlopen_self_static=unknown # Compiler flag to prevent dynamic linking. -link_static_flag="-static" +link_static_flag="" # Compiler flag to turn off builtin functions. no_builtin_flag=" -fno-builtin" @@ -6798,13 +6798,13 @@ AR="ar" AR_FLAGS="cru" # A C compiler. -LTCC="gcc" +LTCC="/usr/lib/openmpi/1.2.7-gcc//bin/mpicc" # LTCC compiler flags. LTCFLAGS="-g -O2" # A language-specific compiler. -CC="g++" +CC="/usr/lib/openmpi/1.2.7-gcc//bin/mpiCC" # Is the compiler the GNU C compiler? with_gcc=yes @@ -6887,7 +6887,7 @@ dlopen_self=unknown dlopen_self_static=unknown # Compiler flag to prevent dynamic linking. -link_static_flag="-static" +link_static_flag="" # Compiler flag to turn off builtin functions. no_builtin_flag=" -fno-builtin" @@ -6954,11 +6954,11 @@ predeps="" # Dependencies to place after the objects being linked to create a # shared library. -postdeps="-lstdc++ -lm -lgcc_s -lc -lgcc_s" +postdeps="-lmpi_cxx -lmpi -lopen-rte -lopen-pal -ldl -lnsl -lutil -ldl -lstdc++ -lm -lgcc_s -lpthread -lc -lgcc_s" # The library search path used internally by the compiler when linking # a shared library. -compiler_lib_search_path="-L/usr/lib/gcc/i386-redhat-linux/4.1.2 -L/usr/lib/gcc/i386-redhat-linux/4.1.2 -L/usr/lib/gcc/i386-redhat-linux/4.1.2/../../.." +compiler_lib_search_path="-L/usr/lib/openmpi/1.2.7-gcc/lib -L/usr/lib/gcc/i386-redhat-linux/4.1.2 -L/usr/lib/gcc/i386-redhat-linux/4.1.2 -L/usr/lib/gcc/i386-redhat-linux/4.1.2/../../.." # Method to check whether dependent libraries are shared objects. deplibs_check_method="pass_all" @@ -7103,7 +7103,7 @@ AR="ar" AR_FLAGS="cru" # A C compiler. -LTCC="gcc" +LTCC="/usr/lib/openmpi/1.2.7-gcc//bin/mpicc" # LTCC compiler flags. LTCFLAGS="-g -O2" diff --git a/AMDiS/src/DOFVector.hh b/AMDiS/src/DOFVector.hh index c761c559..198715e6 100644 --- a/AMDiS/src/DOFVector.hh +++ b/AMDiS/src/DOFVector.hh @@ -432,15 +432,13 @@ namespace AMDiS { { const BasisFunction *basFct = traverseVector->getFESpace()->getBasisFcts(); const DOFAdmin* admin = traverseVector->getFESpace()->getAdmin(); - const DegreeOfFreedom *dof = basFct->getLocalIndices(const_cast<Element *>(elinfo->getElement()), - admin, NULL); - const T *inter_val = const_cast<BasisFunction*>(basFct)->interpol(elinfo, - 0, - NULL, - traverseVector->interFct, - NULL); - int number = basFct->getNumber(); - for (int i = 0; i < number; i++) + const DegreeOfFreedom *dof = + basFct->getLocalIndices(const_cast<Element*>(elinfo->getElement()), admin, NULL); + const T *inter_val = + const_cast<BasisFunction*>(basFct)->interpol(elinfo, 0, NULL, + traverseVector->interFct, NULL); + int nBasFcts = basFct->getNumber(); + for (int i = 0; i < nBasFcts; i++) (*traverseVector)[dof[i]] = inter_val[i]; return 0; @@ -959,7 +957,6 @@ namespace AMDiS { static T* localVec = NULL; static int localVecSize = 0; const DOFAdmin* admin = feSpace->getAdmin(); - T *result; if (d) { diff --git a/AMDiS/src/Element.cc b/AMDiS/src/Element.cc index 6934a84c..97c66eb7 100644 --- a/AMDiS/src/Element.cc +++ b/AMDiS/src/Element.cc @@ -258,13 +258,14 @@ namespace AMDiS { void Element::newDOFFct2(const DOFAdmin* admin) { - int i, j, k, n0, nd, nd0; + int i, j, k, n0, nd0; DegreeOfFreedom *ldof; int vertices = mesh->getGeo(VERTEX); int edges = mesh->getGeo(EDGE); int faces = mesh->getGeo(FACE); - if (nd = admin->getNumberOfDOFs(VERTEX)) { + int nd = admin->getNumberOfDOFs(VERTEX); + if (nd) { nd0 = admin->getNumberOfPreDOFs(VERTEX); n0 = admin->getMesh()->getNode(VERTEX); for (i = 0; i < vertices; i++) { @@ -273,7 +274,8 @@ namespace AMDiS { } if (mesh->getDim() > 1) { - if (nd = admin->getNumberOfDOFs(EDGE)) { + nd = admin->getNumberOfDOFs(EDGE); + if (nd) { nd0 = admin->getNumberOfPreDOFs(EDGE); n0 = admin->getMesh()->getNode(EDGE); for (i = 0; i < edges; i++) { @@ -283,7 +285,8 @@ namespace AMDiS { } if (mesh->getDim() == 3) { - if (nd = admin->getNumberOfDOFs(FACE)) { + nd = admin->getNumberOfDOFs(FACE); + if (nd) { nd0 = admin->getNumberOfPreDOFs(FACE); n0 = admin->getMesh()->getNode(FACE); for (i = 0; i < faces; i++) { @@ -292,7 +295,8 @@ namespace AMDiS { } } - if (nd = admin->getNumberOfDOFs(CENTER)) { + nd = admin->getNumberOfDOFs(CENTER); + if (nd) { nd0 = admin->getNumberOfPreDOFs(CENTER); n0 = admin->getMesh()->getNode(CENTER); // only one center diff --git a/AMDiS/src/ElementDofIterator.h b/AMDiS/src/ElementDofIterator.h index a64cee19..718632a2 100644 --- a/AMDiS/src/ElementDofIterator.h +++ b/AMDiS/src/ElementDofIterator.h @@ -62,7 +62,7 @@ namespace AMDiS { bool nextStrict(); /// Returns the dof index of the current dof. - inline const DegreeOfFreedom getDof() + inline DegreeOfFreedom getDof() { if (inOrder) return dofs[node0 + elementPos][n0 + orderPosition[dofPos]]; diff --git a/AMDiS/src/Mesh.cc b/AMDiS/src/Mesh.cc index 3e75bcad..07b11ec9 100644 --- a/AMDiS/src/Mesh.cc +++ b/AMDiS/src/Mesh.cc @@ -24,6 +24,8 @@ #include "Projection.h" #include "ElInfoStack.h" +#include "mpi.h" + namespace AMDiS { #define TIME_USED(f,s) ((double)((s)-(f))/(double)CLOCKS_PER_SEC) @@ -1194,6 +1196,34 @@ namespace AMDiS { macroFileInfo = NULL; } + void Mesh::computeMatrixFillin(const FiniteElemSpace *feSpace, + std::vector<int> &nnzInRow, int &overall, int &average) + { + std::map<DegreeOfFreedom, int> dofCounter; + + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(this, -1, Mesh::CALL_LEAF_EL); + ElementDofIterator elDofIter(feSpace); + while (elInfo) { + elDofIter.reset(elInfo->getElement()); + do { + DegreeOfFreedom dof = elDofIter.getDof(); + if (dofCounter.count(dof) == 0) { + dofCounter[dof] = 1; + } else { + dofCounter[dof]++; + } + } while (elDofIter.next()); + elInfo = stack.traverseNext(elInfo); + } + + overall = 0; + for (std::map<DegreeOfFreedom, int>::iterator it = dofCounter.begin(); + it != dofCounter.end(); ++it) { + overall += it->second * 15; + } + } + int Mesh::calcMemoryUsage() { int result = sizeof(Mesh); diff --git a/AMDiS/src/Mesh.h b/AMDiS/src/Mesh.h index 68dc9399..015e5aed 100644 --- a/AMDiS/src/Mesh.h +++ b/AMDiS/src/Mesh.h @@ -564,6 +564,13 @@ namespace AMDiS { /// void clearMacroFileInfo(); + /** \brief + * Traverse this mesh to compute the number of non zero elements the assembled + * matrix will have in each row. + */ + void computeMatrixFillin(const FiniteElemSpace *feSpace, + std::vector<int> &nnzInRow, int &overall, int &average); + /// int calcMemoryUsage(); diff --git a/AMDiS/src/ParallelDomainBase.cc b/AMDiS/src/ParallelDomainBase.cc index c77f2bb7..08839103 100644 --- a/AMDiS/src/ParallelDomainBase.cc +++ b/AMDiS/src/ParallelDomainBase.cc @@ -144,23 +144,8 @@ namespace AMDiS { DbgTestCommonDofs(true); #endif - - // === Create petsc matrix. === - nRankRows = nRankDOFs * nComponents; nOverallRows = nOverallDOFs * nComponents; - - VecCreate(PETSC_COMM_WORLD, &petscRhsVec); - VecSetSizes(petscRhsVec, nRankRows, nOverallRows); - VecSetType(petscRhsVec, VECMPI); - - VecCreate(PETSC_COMM_WORLD, &petscSolVec); - VecSetSizes(petscSolVec, nRankRows, nOverallRows); - VecSetType(petscSolVec, VECMPI); - - VecCreate(PETSC_COMM_WORLD, &petscTmpVec); - VecSetSizes(petscTmpVec, nRankRows, nOverallRows); - VecSetType(petscTmpVec, VECMPI); } @@ -244,21 +229,12 @@ namespace AMDiS { for (icursor_type icursor = begin<nz>(cursor), icend = end<nz>(cursor); icursor != icend; ++icursor) if (value(*icursor) != 0.0) { - if (mpiRank == 0 && r == 0) - std::cout << "C = " << col(*icursor) - << " = " << mapLocalGlobalDOFs[col(*icursor)] - << " = " << mapLocalGlobalDOFs[col(*icursor)] * dispMult + dispAddCol - << " -> " << value(*icursor) - << std::endl; - cols.push_back(mapLocalGlobalDOFs[col(*icursor)] * dispMult + dispAddCol); values.push_back(value(*icursor)); } MatSetValues(petscMatrix, 1, &r, cols.size(), &(cols[0]), &(values[0]), ADD_VALUES); } - - std::cout << "==========" << std::endl; } @@ -281,6 +257,18 @@ namespace AMDiS { MatSetSizes(petscMatrix, nRankRows, nRankRows, nOverallRows, nOverallRows); MatSetType(petscMatrix, MATAIJ); + VecCreate(PETSC_COMM_WORLD, &petscRhsVec); + VecSetSizes(petscRhsVec, nRankRows, nOverallRows); + VecSetType(petscRhsVec, VECMPI); + + VecCreate(PETSC_COMM_WORLD, &petscSolVec); + VecSetSizes(petscSolVec, nRankRows, nOverallRows); + VecSetType(petscSolVec, VECMPI); + + VecCreate(PETSC_COMM_WORLD, &petscTmpVec); + VecSetSizes(petscTmpVec, nRankRows, nOverallRows); + VecSetType(petscTmpVec, VECMPI); + setDofMatrix(mat); MatAssemblyBegin(petscMatrix, MAT_FINAL_ASSEMBLY); @@ -299,6 +287,18 @@ namespace AMDiS { clock_t first = clock(); + VecCreate(PETSC_COMM_WORLD, &petscRhsVec); + VecSetSizes(petscRhsVec, nRankRows, nOverallRows); + VecSetType(petscRhsVec, VECMPI); + + VecCreate(PETSC_COMM_WORLD, &petscSolVec); + VecSetSizes(petscSolVec, nRankRows, nOverallRows); + VecSetType(petscSolVec, VECMPI); + + VecCreate(PETSC_COMM_WORLD, &petscTmpVec); + VecSetSizes(petscTmpVec, nRankRows, nOverallRows); + VecSetType(petscTmpVec, VECMPI); + using mtl::tag::row; using mtl::tag::nz; using mtl::begin; using mtl::end; namespace traits= mtl::traits; typedef DOFMatrix::base_matrix_type Matrix; @@ -481,7 +481,7 @@ namespace AMDiS { } i++; - } + } MatCreateMPIAIJ(PETSC_COMM_WORLD, nRankRows, nRankRows, nOverallRows, nOverallRows, 0, d_nnz, 0, o_nnz, &petscMatrix); @@ -499,7 +499,7 @@ namespace AMDiS { for (int i = 0; i < nComponents; i++) for (int j = 0; j < nComponents; j++) - if ((*mat)[i][j]) + if ((*mat)[i][j]) setDofMatrix((*mat)[i][j], nComponents, i, j); MatAssemblyBegin(petscMatrix, MAT_FINAL_ASSEMBLY); @@ -586,6 +586,9 @@ namespace AMDiS { delete [] sendBuffers[i]; MatDestroy(petscMatrix); + VecDestroy(petscRhsVec); + VecDestroy(petscSolVec); + VecDestroy(petscTmpVec); } @@ -611,17 +614,10 @@ namespace AMDiS { for (int i = 0; i < nComponents; i++) { DOFVector<double> *dofvec = vec.getDOFVector(i); - for (int j = 0; j < nRankDOFs; j++) { - if (i == 0 && mapLocalToDofIndex[j] == 0) - std::cout << "ZUGRIFF AUF: " << j * nComponents + i << std::endl; - - (*dofvec)[mapLocalToDofIndex[j]] = vecPointer[j * nComponents + i]; - } + for (int j = 0; j < nRankDOFs; j++) + (*dofvec)[mapLocalToDofIndex[j]] = vecPointer[j * nComponents + i]; } - if (mpiRank == 0) - std::cout << "RESULT = " << (*(vec.getDOFVector(0)))[0] << std::endl; - VecRestoreArray(petscSolVec, &vecPointer); synchVectors(vec); @@ -637,6 +633,9 @@ namespace AMDiS { MSG(" Residual norm: %e\n", norm); MatDestroy(petscMatrix); + VecDestroy(petscRhsVec); + VecDestroy(petscSolVec); + VecDestroy(petscTmpVec); KSPDestroy(solver); } @@ -933,7 +932,6 @@ namespace AMDiS { int i = 0; for (DofContainer::iterator dofIt = rankAllDofs.begin(); dofIt != rankAllDofs.end(); ++dofIt) { - rankDofsNewLocalIndex[*dofIt] = i; // First, we set all dofs in ranks partition to be owend by the rank. Later, // the dofs in ranks partition that are owned by other rank are set to false. diff --git a/AMDiS/src/ProblemVec.cc b/AMDiS/src/ProblemVec.cc index 7fe5b59a..a4fbd4c6 100644 --- a/AMDiS/src/ProblemVec.cc +++ b/AMDiS/src/ProblemVec.cc @@ -32,7 +32,7 @@ namespace AMDiS { Flag adoptFlag) { FUNCNAME("ProblemVec::initialize()"); - + // === create meshes === if (meshes.size() != 0) { WARNING("meshes already created\n"); @@ -646,6 +646,14 @@ namespace AMDiS { int nnz = 0; for (int i = 0; i < nComponents; i++) { + +#if 0 + std::vector<int> nnzInRow; + int overallNnz, averageNnz; + componentSpaces[i]->getMesh()->computeMatrixFillin(componentSpaces[i], + nnzInRow, overallNnz, averageNnz); +#endif + MSG("%d DOFs for %s\n", componentSpaces[i]->getAdmin()->getUsedSize(), componentSpaces[i]->getName().c_str()); @@ -1384,7 +1392,7 @@ namespace AMDiS { { const BasisFunction *basisFcts = componentSpaces[0]->getBasisFcts(); WorldVector<double> coords; - ElementDofIterator elDofIter(componentSpaces[0]); + ElementDofIterator elDofIter(componentSpaces[0], true); TraverseStack stack; ElInfo *elInfo = stack.traverseFirst(componentMeshes[0], -1, @@ -1456,7 +1464,7 @@ namespace AMDiS { for (DofToCoord::iterator it = dofToCoords.begin(); it != dofToCoords.end(); ++it) { out << it->first << std::endl; for (int j = 0; j < dimOfWorld; j++) - out << (it->second)[j] << std::endl; + out << (it->second)[j] << std::endl; } // Write the matrices. @@ -1491,12 +1499,40 @@ namespace AMDiS { TEST_EXIT(testNnz == nnz)("NNZ does not fit together!\n"); } } + + + for (int i = 0; i < nComponents; i++) { + out << rhs->getDOFVector(i)->getUsedSize() << std::endl; + DOFIterator<double> it(rhs->getDOFVector(i), USED_DOFS); + int c = 0; + for (it.reset(); !it.end(); ++it) { + out << c << " " << *it << std::endl; + c++; + } + + TEST_EXIT(c == rhs->getDOFVector(i)->getUsedSize()) + ("RHS NNZ does not fit together!\n"); + } + + + for (int i = 0; i < nComponents; i++) { + out << solution->getDOFVector(i)->getUsedSize() << std::endl; + DOFIterator<double> it(solution->getDOFVector(i), USED_DOFS); + int c = 0; + for (it.reset(); !it.end(); ++it) { + out << c << " " << *it << std::endl; + c++; + } + + TEST_EXIT(c == rhs->getDOFVector(i)->getUsedSize()) + ("RHS NNZ does not fit together!\n"); + } out.close(); } - - void ProblemVec::readAndCompareDbgMatrix(std::string filename) + + void ProblemVec::readAndCompareDbgMatrix(std::vector<std::string> filenames) { using mtl::tag::major; using mtl::tag::nz; using mtl::begin; using mtl::end; namespace traits = mtl::traits; @@ -1513,42 +1549,92 @@ namespace AMDiS { DegreeOfFreedom dof; int dimOfWorld = Global::getGeo(WORLD); - // Open file and read the number of DOFs the file contains. - std::ifstream in(filename.c_str()); - int nReadDofs; - in >> nReadDofs; + std::vector<std::vector<std::map<std::pair<int, int>, double> > > nnzValues; + std::vector<std::map<int, double> > rhsValues; + std::vector<std::map<int, double> > solValues; - // Read all DOF indices and their world coordinates. - for (int i = 0; i < nReadDofs; i++) { - in >> dof; - for (int j = 0; j < dimOfWorld; j++) - in >> coords[j]; - dofToCoord[dof] = coords; - } + nnzValues.resize(nComponents); + rhsValues.resize(nComponents); + solValues.resize(nComponents); + for (int i = 0; i < nComponents; i++) + nnzValues[i].resize(nComponents); - // Now we traverse all matrices and check them. - for (int i = 0; i < nComponents; i++) { - for (int j = 0; j < nComponents; j++) { - DOFMatrix *dofmatrix = (*systemMatrix)[i][j]; - - if (!dofmatrix) - continue; + for (std::vector<std::string>::iterator fileIt = filenames.begin(); + fileIt != filenames.end(); ++fileIt) { + // Open file and read the number of DOFs the file contains. + std::ifstream in(fileIt->c_str()); + int nReadDofs; + in >> nReadDofs; + + // Read all DOF indices and their world coordinates. + dofToCoord.clear(); + for (int i = 0; i < nReadDofs; i++) { + in >> dof; + for (int j = 0; j < dimOfWorld; j++) + in >> coords[j]; + dofToCoord[dof] = coords; + } + + // Now we traverse all matrices and check them. + for (int i = 0; i < nComponents; i++) { + for (int j = 0; j < nComponents; j++) { + DOFMatrix *dofmatrix = (*systemMatrix)[i][j]; + + if (!dofmatrix) + continue; + + int readNnz; + in >> readNnz; + + // Read each entry in file and check it with the corresponding matrix value + // in this problem. + for (int k = 0; k < readNnz; k++) { + DegreeOfFreedom row, col; + double value; + + in >> row; + in >> col; + in >> value; + + WorldVector<double> rowCoords = dofToCoord[row]; + WorldVector<double> colCoords = dofToCoord[col]; + + if (coordToDof.find(rowCoords) == coordToDof.end()) { + std::cout << "CANNOT ROW FIND" << std::endl; + rowCoords.print(); + exit(0); + } + + if (coordToDof.find(colCoords) == coordToDof.end()) { + std::cout << "CANNOT COL FIND" << std::endl; + rowCoords.print(); + exit(0); + } + + DegreeOfFreedom rowHere = coordToDof[rowCoords]; + DegreeOfFreedom colHere = coordToDof[colCoords]; + + std::pair<int, int> rowcol = make_pair(rowHere, colHere); + if (nnzValues[i][j].count(rowcol) == 0) + nnzValues[i][j][rowcol] = value; + else + nnzValues[i][j][rowcol] += value; + } + } + } + + for (int i = 0; i < nComponents; i++) { int readNnz; in >> readNnz; - - // Read each entry in file and check it with the corresponding matrix value - // in this problem. for (int k = 0; k < readNnz; k++) { - DegreeOfFreedom row, col; + int row; double value; - + in >> row; - in >> col; in >> value; WorldVector<double> rowCoords = dofToCoord[row]; - WorldVector<double> colCoords = dofToCoord[col]; if (coordToDof.find(rowCoords) == coordToDof.end()) { std::cout << "CANNOT ROW FIND" << std::endl; @@ -1556,34 +1642,129 @@ namespace AMDiS { exit(0); } - if (coordToDof.find(colCoords) == coordToDof.end()) { - std::cout << "CANNOT COL FIND" << std::endl; + DegreeOfFreedom rowHere = coordToDof[rowCoords]; + + if (rhsValues[i].count(rowHere) == 0) + rhsValues[i][rowHere] = value; + else + rhsValues[i][rowHere] += value; + } + } + + for (int i = 0; i < nComponents; i++) { + int readNnz; + in >> readNnz; + for (int k = 0; k < readNnz; k++) { + int row; + double value; + + in >> row; + in >> value; + + WorldVector<double> rowCoords = dofToCoord[row]; + + if (coordToDof.find(rowCoords) == coordToDof.end()) { + std::cout << "CANNOT ROW FIND" << std::endl; rowCoords.print(); exit(0); } DegreeOfFreedom rowHere = coordToDof[rowCoords]; - DegreeOfFreedom colHere = coordToDof[colCoords]; - double valueHere = (dofmatrix->getBaseMatrix())[rowHere][colHere]; - double diff = fabs(valueHere - value); + if (solValues[i].count(rowHere) == 0) { + solValues[i][rowHere] = value; + } else { + double diff = fabs(solValues[i][rowHere] - value); + if (diff > 1e-8) { + std::cout << "DIFFERENT values in solution vector!" << std::endl; + exit(0); + } + } + } + } + + in.close(); + + std::cout << "File read!" << std::endl; + } + + std::cout.precision(15); + + for (int i = 0; i < nComponents; i++) { + for (int j = 0; j < nComponents; j++) { + DOFMatrix *dofmatrix = (*systemMatrix)[i][j]; + + if (!dofmatrix) + continue; + + for (std::map<std::pair<int, int>, double>::iterator nnzIt = + nnzValues[i][j].begin(); nnzIt != nnzValues[i][j].end(); ++nnzIt) { + + int row = nnzIt->first.first; + int col = nnzIt->first.second; + double value = nnzIt->second; + + double valueHere = (dofmatrix->getBaseMatrix())[row][col]; + double diff = fabs(valueHere - value); + // And so we check the difference between the value read from file and the // corresponding value in the matrix. - if (diff > 1e-10) { + if (diff > 1e-8) { std::cout << "WRONG value in matrix[" << i << "][" << j << "]!" << std::endl - << " DOF in other matrix [" << row << "][" << col << "] = " << value << std::endl - << " DOF in this matrix [" << rowHere << "][" << colHere << "] = " << valueHere << std::endl; - - + << " DOF in other matrix[" << row << "][" << col << "] = " << value << std::endl + << " DOF in this matrix[" << row << "][" << col << "] = " << valueHere << std::endl; + + exit(0); } + } + } + } + for (int i = 0; i < nComponents; i++) { + for (std::map<int, double>::iterator rhsIt = rhsValues[i].begin(); + rhsIt != rhsValues[i].end(); ++rhsIt) { + + int row = rhsIt->first; + double value = rhsIt->second; + + double valueHere = (*(rhs->getDOFVector(i)))[row]; + double diff = fabs(valueHere - value); + + if (diff > 1e-8) { + std::cout << "WRONG value in rhs[" << i << "]!" << std::endl + << " DOF in other rhs[" << row << "] = " << value << std::endl + << " DOF in this rhs[" << row << "] = " << valueHere << std::endl; + + exit(0); + } + } + } + + for (int i = 0; i < nComponents; i++) { + for (std::map<int, double>::iterator solIt = solValues[i].begin(); + solIt != solValues[i].end(); ++solIt) { + + int row = solIt->first; + double value = solIt->second; + + double valueHere = (*(solution->getDOFVector(i)))[row]; + double diff = fabs(valueHere - value); + + if (diff > 1e-8) { + std::cout << "WRONG value in sol[" << i << "]!" << std::endl + << " DOF in other sol[" << row << "] = " << value << std::endl + << " DOF in this sol[" << row << "] = " << valueHere << std::endl; + + exit(0); } } } + std::cout << "FINISHED COMPARING!" << std::endl; - in.close(); + exit(0); } + } diff --git a/AMDiS/src/ProblemVec.h b/AMDiS/src/ProblemVec.h index f4081696..7a4de800 100644 --- a/AMDiS/src/ProblemVec.h +++ b/AMDiS/src/ProblemVec.h @@ -473,6 +473,21 @@ namespace AMDiS { return fileWriters; } + /** \brief + * This function writes the system matrix and the system vector to a file + * for debugging. The entries of both, the matrix and the vector, are not + * indicated by the dof indices, but by the world coordinates of the dofs. + * This makes it possible to compare dof matrices, where the dof indices + * are different, e.g., when using domain decomposition parallelization. + */ + void writeDbgMatrix(std::string filename); + + /** \brief + * Reads a file, that was created using the function \ref writeDbgMatrix, and + * compares the date with the system matrix of this problem. + */ + void readAndCompareDbgMatrix(std::vector<std::string> filenames); + protected: /** \brief * If the exact solution is known, the problem can compute the exact @@ -494,21 +509,6 @@ namespace AMDiS { */ void createCoordToDofMap(CoordToDof &dofMap); - /** \brief - * This function writes the system matrix and the system vector to a file - * for debugging. The entries of both, the matrix and the vector, are not - * indicated by the dof indices, but by the world coordinates of the dofs. - * This makes it possible to compare dof matrices, where the dof indices - * are different, e.g., when using domain decomposition parallelization. - */ - void writeDbgMatrix(std::string filename); - - /** \brief - * Reads a file, that was created using the function \ref writeDbgMatrix, and - * compares the date with the system matrix of this problem. - */ - void readAndCompareDbgMatrix(std::string filename); - protected: /// Name of this problem. diff --git a/AMDiS/src/SubAssembler.cc b/AMDiS/src/SubAssembler.cc index ba8d3706..e616e470 100644 --- a/AMDiS/src/SubAssembler.cc +++ b/AMDiS/src/SubAssembler.cc @@ -179,11 +179,10 @@ namespace AMDiS { if (opt && !quad && sameFESpaces) { const BasisFunction *psi = owner->rowFESpace->getBasisFcts(); const BasisFunction *phi = owner->colFESpace->getBasisFcts(); - if (vec->getFESpace()->getBasisFcts() == psi) { + if (vec->getFESpace()->getBasisFcts() == psi) psiFast = updateFastQuadrature(psiFast, psi, INIT_PHI); - } else if(vec->getFESpace()->getBasisFcts() == phi) { - phiFast = updateFastQuadrature(phiFast, phi, INIT_PHI); - } + else if(vec->getFESpace()->getBasisFcts() == phi) + phiFast = updateFastQuadrature(phiFast, phi, INIT_PHI); } // calculate new values @@ -200,7 +199,7 @@ namespace AMDiS { } else { vec->getVecAtQPs(elInfo, localQuad, NULL, values); } - + valuesAtQPs[vec]->valid = true; return values; diff --git a/AMDiS/src/ZeroOrderAssembler.cc b/AMDiS/src/ZeroOrderAssembler.cc index a8d6f083..c7975367 100644 --- a/AMDiS/src/ZeroOrderAssembler.cc +++ b/AMDiS/src/ZeroOrderAssembler.cc @@ -49,10 +49,8 @@ namespace AMDiS { sort(assTerms.begin(), assTerms.end()); - if ((opTerms == assTerms) && - ((*subAssemblers)[i]->getQuadrature() == quad)) { + if (opTerms == assTerms && (*subAssemblers)[i]->getQuadrature() == quad) return dynamic_cast<ZeroOrderAssembler*>((*subAssemblers)[i]); - } } } @@ -69,11 +67,10 @@ namespace AMDiS { if (!optimized) { newAssembler = new StandardZOA(op, assembler, quad); } else { - if (pwConst) { - newAssembler = new PrecalcZOA(op, assembler, quad); - } else { - newAssembler = new FastQuadZOA(op, assembler, quad); - } + if (pwConst) + newAssembler = new PrecalcZOA(op, assembler, quad); + else + newAssembler = new FastQuadZOA(op, assembler, quad); } subAssemblers->push_back(newAssembler); @@ -95,9 +92,8 @@ namespace AMDiS { int myRank = omp_get_thread_num(); std::vector<OperatorTerm*>::iterator termIt; - for (termIt = terms[myRank].begin(); termIt != terms[myRank].end(); ++termIt) { + for (termIt = terms[myRank].begin(); termIt != terms[myRank].end(); ++termIt) (static_cast<ZeroOrderTerm*>((*termIt)))->getC(elInfo, nPoints, c); - } if (symmetric) { TEST_EXIT_DBG(nCol == nRow)("nCol != nRow, but symmetric assembling!\n"); @@ -106,9 +102,8 @@ namespace AMDiS { c[iq] *= elInfo->getDet(); // calculate phi at QPs only once! - for (int i = 0; i < nCol; i++) { + for (int i = 0; i < nCol; i++) phival[i] = (*(phi->getPhi(i)))(quadrature->getLambda(iq)); - } for (int i = 0; i < nRow; i++) { double psival = (*(psi->getPhi(i)))(quadrature->getLambda(iq)); @@ -125,15 +120,13 @@ namespace AMDiS { c[iq] *= elInfo->getDet(); // calculate phi at QPs only once! - for (int i = 0; i < nCol; i++) { + for (int i = 0; i < nCol; i++) phival[i] = (*(phi->getPhi(i)))(quadrature->getLambda(iq)); - } for (int i = 0; i < nRow; i++) { double psival = (*(psi->getPhi(i)))(quadrature->getLambda(iq)); - for (int j = 0; j < nCol; j++) { + for (int j = 0; j < nCol; j++) mat[i][j] += quadrature->getWeight(iq) * c[iq] * psival * phival[j]; - } } } } @@ -143,12 +136,11 @@ namespace AMDiS { { int nPoints = quadrature->getNumPoints(); std::vector<double> c(nPoints, 0.0); - int myRank = omp_get_thread_num(); + std::vector<OperatorTerm*>::iterator termIt; - for (termIt = terms[myRank].begin(); termIt != terms[myRank].end(); ++termIt) { + for (termIt = terms[myRank].begin(); termIt != terms[myRank].end(); ++termIt) (static_cast<ZeroOrderTerm*>((*termIt)))->getC(elInfo, nPoints, c); - } for (int iq = 0; iq < nPoints; iq++) { c[iq] *= elInfo->getDet(); -- GitLab