Commit edb2158b authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

solvers are reworked and a lot of thingt corrected in the parallel petsc backend

parent d93ad598
...@@ -29,6 +29,10 @@ ...@@ -29,6 +29,10 @@
#endif #endif
#include "boost/program_options.hpp" #include "boost/program_options.hpp"
#if defined HAVE_PETSC || defined HAVE_SEQ_PETSC || defined HAVE_PARALLEL_PETSC
#include <petsc.h>
#endif
namespace AMDiS { namespace AMDiS {
using namespace std; using namespace std;
......
...@@ -154,9 +154,7 @@ ...@@ -154,9 +154,7 @@
#include "parallel/StdMpi.h" #include "parallel/StdMpi.h"
#include "parallel/ParallelProblemStat.h" #include "parallel/ParallelProblemStat.h"
#if HAVE_PARALLEL_MTL4 #if !HAVE_PARALLEL_MTL4
// #include "parallel/PMTL4Solver.h"
#else
#include "parallel/PetscSolver.h" #include "parallel/PetscSolver.h"
#include "parallel/PetscSolverNavierStokes.h" #include "parallel/PetscSolverNavierStokes.h"
#endif #endif
......
...@@ -35,6 +35,7 @@ namespace AMDiS { ...@@ -35,6 +35,7 @@ namespace AMDiS {
class AdaptStationary; class AdaptStationary;
class Assembler; class Assembler;
class BasisFunction; class BasisFunction;
struct BlockMTLMatrix;
class BoundaryManager; class BoundaryManager;
// class CGSolver; // class CGSolver;
class CoarseningManager; class CoarseningManager;
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "MTL4Types.h" #include "MTL4Types.h"
#include "solver/LinearSolver.h" #include "solver/LinearSolver.h"
#include "solver/ITL_Solver.h" #include "solver/ITL_Solver.h"
#include "solver/BITL_Solver.h"
#include "solver/ITL_Preconditioner.h" #include "solver/ITL_Preconditioner.h"
#include "solver/UmfPackSolver.h" #include "solver/UmfPackSolver.h"
#include "solver/KrylovPreconditioner.h" #include "solver/KrylovPreconditioner.h"
...@@ -61,6 +62,9 @@ namespace AMDiS { ...@@ -61,6 +62,9 @@ namespace AMDiS {
{ {
LinearSolverCreator *creator; LinearSolverCreator *creator;
// creators for MTL4 krylov solvers
// _________________________________________________________________________
creator = new CGSolver::Creator; creator = new CGSolver::Creator;
addCreator("mtl_cg", creator); addCreator("mtl_cg", creator);
...@@ -115,18 +119,72 @@ namespace AMDiS { ...@@ -115,18 +119,72 @@ namespace AMDiS {
addCreator("mtl_hypre", creator); addCreator("mtl_hypre", creator);
#endif #endif
// creators for block krylov solvers
// _________________________________________________________________________
creator = new B_CGSolver::Creator;
addCreator("bmtl_cg", creator);
creator = new B_CGSSolver::Creator;
addCreator("bmtl_cgs", creator);
// creator = new B_BiCGSolver::Creator;
// addCreator("mtl_bicg", creator);
creator = new B_BiCGStabSolver::Creator;
addCreator("bmtl_bicgstab", creator);
// creator = new B_BiCGStab2Solver::Creator;
// addCreator("bmtl_bicgstab2", creator); // MTL Error
// creator = new B_BiCGStabEllSolver::Creator;
// addCreator("bmtl_bicgstab_ell", creator); // MTL Error
// creator = new QMRSolver::Creator;
// addCreator("mtl_qmr", creator);
creator = new B_TFQMRSolver::Creator;
addCreator("bmtl_tfqmr", creator);
creator = new B_GMResSolver::Creator;
addCreator("bmtl_gmres", creator);
creator = new B_GcrSolver::Creator;
addCreator("bmtl_gcr", creator);
creator = new B_FGMResSolver::Creator;
addCreator("bmtl_fgmres", creator);
// creator = new B_IDRsSolver::Creator;
// addCreator("bmtl_idr_s", creator); // MTL Error
creator = new B_MinResSolver::Creator;
addCreator("bmtl_minres", creator);
creator = new B_PreOnly::Creator;
addCreator("bmtl_preonly", creator);
addCreator("bmtl_richardson", creator);
// creators for PETSc solvers
// _________________________________________________________________________
#if defined HAVE_SEQ_PETSC #if defined HAVE_SEQ_PETSC
// sequential PETSc-Solver // sequential PETSc-Solver
creator = new PetscSolver<>::Creator; creator = new PetscSolver::Creator;
addCreator("petsc_petsc", creator); // standard creator for petsc solver addCreator("petsc_petsc", creator); // standard creator for petsc solver
addCreator("petsc", creator); addCreator("petsc", creator);
LinearSolverCreator* creator2 = new PetscSolverNested::Creator;
addCreator("bpetsc_petsc", creator2); // standard creator for petsc solver
addCreator("bpetsc", creator2);
std::map<std::string,std::string>::iterator it; std::map<std::string,std::string>::iterator it;
PetscParameters params; PetscParameters params;
for (it = params.solverMap.begin(); for (it = params.solverMap.begin();
it!= params.solverMap.end(); it!= params.solverMap.end();
it++) { it++) {
CreatorMap< LinearSolver >::addCreator("petsc_" + it->first, creator); CreatorMap< LinearSolver >::addCreator("petsc_" + it->first, creator);
CreatorMap< LinearSolver >::addCreator("bpetsc_" + it->first, creator2);
} }
#endif #endif
} }
...@@ -159,6 +217,22 @@ namespace AMDiS { ...@@ -159,6 +217,22 @@ namespace AMDiS {
} }
template<>
void CreatorMap<ITL_BasePreconditioner<BlockMTLMatrix, MTLTypes::MTLVector> >::addDefaultCreators()
{
addCreator("no", new BlockIdentityPreconditioner::Creator);
addCreator("diag", new BlockDiagonalPreconditioner::Creator);
}
#if defined HAVE_SEQ_PETSC
template<>
void CreatorMap<PetscPreconditioner>::addDefaultCreators() { }
template<>
void CreatorMap<PetscPreconditionerNested>::addDefaultCreators() { }
#endif
template<> template<>
void CreatorMap<Estimator>::addDefaultCreators() void CreatorMap<Estimator>::addDefaultCreators()
{ {
......
...@@ -43,13 +43,16 @@ namespace AMDiS { ...@@ -43,13 +43,16 @@ namespace AMDiS {
template<typename BaseClass> template<typename BaseClass>
class CreatorMap class CreatorMap
{ {
public:
typedef std::map< std::string, CreatorInterface<BaseClass>* > CreatorMapType;
public: public:
/// Adds a new creator together with the given key to the map. /// Adds a new creator together with the given key to the map.
static void addCreator(std::string key, CreatorInterface<BaseClass>* creator) static void addCreator(std::string key, CreatorInterface<BaseClass>* creator)
{ {
FUNCNAME("CreatorMap::addCreator()"); FUNCNAME("CreatorMap::addCreator()");
init(); init();
TEST_EXIT(creatorMap[key] == nullptr) TEST_EXIT(creatorMap[key] == NULL)
("there is already a creator for key %s\n",key.c_str()); ("there is already a creator for key %s\n",key.c_str());
creatorMap[key] = creator; creatorMap[key] = creator;
} }
...@@ -66,8 +69,10 @@ namespace AMDiS { ...@@ -66,8 +69,10 @@ namespace AMDiS {
FUNCNAME("CreatorMap::getCreator()"); FUNCNAME("CreatorMap::getCreator()");
init(); init();
CreatorInterface<BaseClass> *creator = creatorMap[key]; CreatorInterface<BaseClass> *creator = creatorMap[key];
TEST_EXIT(creator)("No creator for key \"%s\" defined in init file for parameter \"%s\"\n", TEST_EXIT(creator)
("No creator for key \"%s\" defined in init file for parameter \"%s\"\n",
key.c_str(), initFileStr.c_str()); key.c_str(), initFileStr.c_str());
return creator; return creator;
} }
...@@ -89,13 +94,13 @@ namespace AMDiS { ...@@ -89,13 +94,13 @@ namespace AMDiS {
protected: protected:
/// STL map containing the pairs of keys and creators. /// STL map containing the pairs of keys and creators.
static std::map< std::string, CreatorInterface<BaseClass>* > creatorMap; static CreatorMapType creatorMap;
static bool initialized; static bool initialized;
}; };
template<typename BaseClass> template<typename BaseClass>
std::map< std::string, CreatorInterface<BaseClass>* > CreatorMap<BaseClass>::creatorMap; typename CreatorMap<BaseClass>::CreatorMapType CreatorMap<BaseClass>::creatorMap;
template<typename BaseClass> template<typename BaseClass>
bool CreatorMap<BaseClass>::initialized = false; bool CreatorMap<BaseClass>::initialized = false;
......
...@@ -67,10 +67,6 @@ namespace AMDiS { ...@@ -67,10 +67,6 @@ namespace AMDiS {
if (!colFeSpace) if (!colFeSpace)
colFeSpace = rowFeSpace; colFeSpace = rowFeSpace;
#if 0
if (rowFeSpace && rowFeSpace->getAdmin())
(const_cast<DOFAdmin*>(rowFeSpace->getAdmin()))->addDOFIndexed(this);
#endif
boundaryManager = new BoundaryManager(rowFeSpace); boundaryManager = new BoundaryManager(rowFeSpace);
nRow = rowFeSpace->getBasisFcts()->getNumber(); nRow = rowFeSpace->getBasisFcts()->getNumber();
...@@ -87,10 +83,6 @@ namespace AMDiS { ...@@ -87,10 +83,6 @@ namespace AMDiS {
FUNCNAME("DOFMatrix::DOFMatrix()"); FUNCNAME("DOFMatrix::DOFMatrix()");
*this = rhs; *this = rhs;
#if 0
if (rowFeSpace && rowFeSpace->getAdmin())
(const_cast<DOFAdmin*>( rowFeSpace->getAdmin()))->addDOFIndexed(this);
#endif
TEST_EXIT(rhs.inserter == 0)("Cannot copy during insertion!\n"); TEST_EXIT(rhs.inserter == 0)("Cannot copy during insertion!\n");
inserter = 0; inserter = 0;
} }
...@@ -98,10 +90,6 @@ namespace AMDiS { ...@@ -98,10 +90,6 @@ namespace AMDiS {
DOFMatrix::~DOFMatrix() DOFMatrix::~DOFMatrix()
{ {
#if 0
if (rowFeSpace && rowFeSpace->getAdmin())
(const_cast<DOFAdmin*>(rowFeSpace->getAdmin()))->removeDOFIndexed(this);
#endif
if (boundaryManager) if (boundaryManager)
delete boundaryManager; delete boundaryManager;
if (inserter) if (inserter)
...@@ -116,43 +104,6 @@ namespace AMDiS { ...@@ -116,43 +104,6 @@ namespace AMDiS {
} }
bool DOFMatrix::symmetric()
{
double tol = 1e-5;
using mtl::tag::major; using mtl::tag::nz; using mtl::begin; using mtl::end;
namespace traits= mtl::traits;
typedef base_matrix_type Matrix;
traits::row<Matrix>::type row(matrix);
traits::col<Matrix>::type col(matrix);
traits::const_value<Matrix>::type value(matrix);
typedef traits::range_generator<major, Matrix>::type cursor_type;
typedef traits::range_generator<nz, cursor_type>::type icursor_type;
for (cursor_type cursor = begin<major>(matrix), cend = end<major>(matrix); cursor != cend; ++cursor)
for (icursor_type icursor = begin<nz>(cursor), icend = end<nz>(cursor); icursor != icend; ++icursor)
// Compare each non-zero entry with its transposed
if (abs(value(*icursor) - matrix[col(*icursor)][row(*icursor)]) > tol)
return false;
return true;
}
void DOFMatrix::test()
{
FUNCNAME("DOFMatrix::test()");
int non_symmetric = !symmetric();
if (non_symmetric)
MSG("Matrix `%s' not symmetric.\n", name.data());
else
MSG("Matrix `%s' is symmetric.\n", name.data());
}
DOFMatrix& DOFMatrix::operator=(const DOFMatrix& rhs) DOFMatrix& DOFMatrix::operator=(const DOFMatrix& rhs)
{ {
rowFeSpace = rhs.rowFeSpace; rowFeSpace = rhs.rowFeSpace;
...@@ -290,14 +241,11 @@ namespace AMDiS { ...@@ -290,14 +241,11 @@ namespace AMDiS {
} }
#if 0
double DOFMatrix::logAcc(DegreeOfFreedom a, DegreeOfFreedom b) const double DOFMatrix::logAcc(DegreeOfFreedom a, DegreeOfFreedom b) const
{ {
return matrix[a][b]; return matrix[a][b];
} }
#if 0
void DOFMatrix::freeDOFContent(int index)
{}
#endif #endif
void DOFMatrix::assemble(double factor, void DOFMatrix::assemble(double factor,
...@@ -418,7 +366,7 @@ namespace AMDiS { ...@@ -418,7 +366,7 @@ namespace AMDiS {
void DOFMatrix::finishAssembling() void DOFMatrix::finishAssembling()
{ {
// call the operatos cleanup procedures // call the operators cleanup procedures
for (std::vector<Operator*>::iterator it = operators.begin(); for (std::vector<Operator*>::iterator it = operators.begin();
it != operators.end(); ++it) it != operators.end(); ++it)
(*it)->finishAssembling(); (*it)->finishAssembling();
...@@ -436,7 +384,7 @@ namespace AMDiS { ...@@ -436,7 +384,7 @@ namespace AMDiS {
return fillFlag; return fillFlag;
} }
#if 0
void DOFMatrix::axpy(double a, const DOFMatrix& x, const DOFMatrix& y) void DOFMatrix::axpy(double a, const DOFMatrix& x, const DOFMatrix& y)
{ {
matrix += a * x.matrix + y.matrix; matrix += a * x.matrix + y.matrix;
...@@ -447,7 +395,7 @@ namespace AMDiS { ...@@ -447,7 +395,7 @@ namespace AMDiS {
{ {
matrix *= b; matrix *= b;
} }
#endif
void DOFMatrix::addOperator(Operator *op, double* factor, double* estFactor) void DOFMatrix::addOperator(Operator *op, double* factor, double* estFactor)
{ {
......
...@@ -70,6 +70,9 @@ namespace AMDiS { ...@@ -70,6 +70,9 @@ namespace AMDiS {
/// used entry in this row /// used entry in this row
static const int NO_MORE_ENTRIES = -2; static const int NO_MORE_ENTRIES = -2;
/// Minimal slot-size used for the inserter. See \ref startInsertion for details.
static const int MIN_NNZ_PER_ROW = 20;
public: public:
DOFMatrix(); DOFMatrix();
...@@ -100,56 +103,7 @@ namespace AMDiS { ...@@ -100,56 +103,7 @@ namespace AMDiS {
{ {
return matrix; return matrix;
} }
#if 0
// Only to get rid of the abstract functions, I hope they are not used
std::vector<bool>::iterator begin()
{
ERROR_EXIT("Shouldn't be used, only fake."); std::vector<bool> v;
return v.begin();
}
std::vector<bool>::iterator end()
{
ERROR_EXIT("Shouldn't be used, only fake."); std::vector<bool> v;
return v.end();
}
// Only to get rid of the abstract functions, I hope they are not used
std::vector<bool>::const_iterator begin() const
{
ERROR_EXIT("Shouldn't be used, only fake."); std::vector<bool> v;
return v.begin();
}
std::vector<bool>::const_iterator end() const
{
ERROR_EXIT("Shouldn't be used, only fake."); std::vector<bool> v;
return v.end();
}
bool dummy; // Must be deleted later
reference operator[](DegreeOfFreedom i)
{
ERROR_EXIT("Shouldn't be used, only fake.");
std::vector<bool> d; d.push_back(dummy);
return d[0];
}
const_reference operator[](DegreeOfFreedom i) const
{
ERROR_EXIT("Shouldn't be used, only fake.");
std::vector<bool> d; d.push_back(dummy);
return d[0];
}
/// DOFMatrix does not need to be compressed before assembling, when using MTL4.
void compressDOFIndexed(int first, int last, std::vector<DegreeOfFreedom> &newDOF)
{}
/// Implements DOFIndexedBase::freeDOFContent()
virtual void freeDOFContent(int index);
#endif
/// Returns \ref coupleMatrix. /// Returns \ref coupleMatrix.
inline bool isCoupleMatrix() inline bool isCoupleMatrix()
{ {
...@@ -162,11 +116,13 @@ namespace AMDiS { ...@@ -162,11 +116,13 @@ namespace AMDiS {
coupleMatrix = c; coupleMatrix = c;
} }
#if 0
/// a * x + y /// a * x + y
void axpy(double a, const DOFMatrix& x, const DOFMatrix& y); void axpy(double a, const DOFMatrix& x, const DOFMatrix& y);
/// Multiplication with a scalar. /// Multiplication with a scalar.
void scal(double s); void scal(double s);
#endif
/// Adds an operator to the DOFMatrix. A factor, that is multipled to the /// Adds an operator to the DOFMatrix. A factor, that is multipled to the
/// operator, and a multilier factor for the estimator may be also given. /// operator, and a multilier factor for the estimator may be also given.
...@@ -267,7 +223,7 @@ namespace AMDiS { ...@@ -267,7 +223,7 @@ namespace AMDiS {
/// entries per row (per column for CCS matrices). Choosing this parameter /// entries per row (per column for CCS matrices). Choosing this parameter
/// too small can induce perceivable overhead for compressed matrices. Thus, /// too small can induce perceivable overhead for compressed matrices. Thus,
/// it's better to choose a bit too large than too small. /// it's better to choose a bit too large than too small.
void startInsertion(int nnz_per_row = 10); void startInsertion(int nnz_per_row = MIN_NNZ_PER_ROW);
/// Finishes insertion. For compressed matrix types, this is where the /// Finishes insertion. For compressed matrix types, this is where the
/// compression happens. /// compression happens.
...@@ -281,15 +237,6 @@ namespace AMDiS { ...@@ -281,15 +237,6 @@ namespace AMDiS {
inserter= 0; inserter= 0;
} }
#if 0
/// Returns whether restriction should be performed after coarsening
/// (false by default)
virtual bool coarseRestrict()
{
return false;
}
#endif
/// Returns const \ref rowFeSpace /// Returns const \ref rowFeSpace
const FiniteElemSpace* getRowFeSpace() const const FiniteElemSpace* getRowFeSpace() const
{ {
...@@ -332,12 +279,6 @@ namespace AMDiS { ...@@ -332,12 +279,6 @@ namespace AMDiS {
return name; return name;
} }
#if 0 #if 0
/// Resizes \ref matrix to n rows
inline void resize(int n)
{
TEST_EXIT_DBG(n >= 0)("Can't resize DOFMatrix to negative size\n");
}
#endif
/// Returns value at logical indices a,b /// Returns value at logical indices a,b
double logAcc(DegreeOfFreedom a, DegreeOfFreedom b) const; double logAcc(DegreeOfFreedom a, DegreeOfFreedom b) const;
...@@ -349,6 +290,7 @@ namespace AMDiS { ...@@ -349,6 +290,7 @@ namespace AMDiS {
void addSparseDOFEntry(double sign, void addSparseDOFEntry(double sign,
int irow, int jcol, double entry, int irow, int jcol, double entry,
bool add = true); bool add = true);
#endif
void clearDirichletRows(); void clearDirichletRows();
...@@ -361,11 +303,6 @@ namespace AMDiS { ...@@ -361,11 +303,6 @@ namespace AMDiS {
set_to_zero(matrix); set_to_zero(matrix);
} }
/// Test whether \ref matrix is symmetric. Exits if not.
void test();
bool symmetric();
inline std::vector<Operator*>& getOperators() inline std::vector<Operator*>& getOperators()
{ {
return operators; return operators;
...@@ -398,8 +335,8 @@ namespace AMDiS { ...@@ -398,8 +335,8 @@ namespace AMDiS {
if (num_rows(matrix) != 0) if (num_rows(matrix) != 0)
nnzPerRow = int(double(matrix.nnz()) / num_rows(matrix) * 1.2); nnzPerRow = int(double(matrix.nnz()) / num_rows(matrix) * 1.2);
if (nnzPerRow < 20) if (nnzPerRow < MIN_NNZ_PER_ROW)
nnzPerRow = 20; nnzPerRow = MIN_NNZ_PER_ROW;
} }
/// Returns \ref nnzPerRow. /// Returns \ref nnzPerRow.
......
...@@ -122,7 +122,7 @@ namespace AMDiS { ...@@ -122,7 +122,7 @@ namespace AMDiS {
value = basFcts->evalUh(lambda, uh); value = basFcts->evalUh(lambda, uh);
} else { } else {
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
return 0.0; value = 0.0;
#else #else
ERROR_EXIT("Can not eval DOFVector at point p, because point is outside geometry."); ERROR_EXIT("Can not eval DOFVector at point p, because point is outside geometry.");
#endif #endif
...@@ -132,6 +132,9 @@ namespace AMDiS { ...@@ -132,6 +132,9 @@ namespace AMDiS {
if (oldElInfo == nullptr) if (oldElInfo == nullptr)
delete elInfo; delete elInfo;
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
Parallel::mpi::globalAdd(value);
#endif
return value;