Commit 59ec2774 authored by Thomas Witkowski's avatar Thomas Witkowski
Browse files

Word-around for a bug in solving Rosenbrock system using UMFPACK.

parent 377e20dc
...@@ -241,7 +241,8 @@ namespace AMDiS { ...@@ -241,7 +241,8 @@ namespace AMDiS {
} else { } else {
for (int j = 0; j < nCol; j++) { for (int j = 0; j < nCol; j++) {
DegreeOfFreedom col = colIndices[j]; DegreeOfFreedom col = colIndices[j];
ins[row][col] += elMat[i][j]; if (fabs(elMat[i][j]) > 1e-10)
ins[row][col] += elMat[i][j];
} }
} }
} }
......
...@@ -437,6 +437,7 @@ namespace AMDiS { ...@@ -437,6 +437,7 @@ namespace AMDiS {
std::ofstream out; std::ofstream out;
out.open(filename.c_str()); out.open(filename.c_str());
out.precision(20);
for (cursor_type cursor = begin<major>(mat.getBaseMatrix()), for (cursor_type cursor = begin<major>(mat.getBaseMatrix()),
cend = end<major>(mat.getBaseMatrix()); cursor != cend; ++cursor) cend = end<major>(mat.getBaseMatrix()); cursor != cend; ++cursor)
......
...@@ -45,11 +45,11 @@ namespace AMDiS { ...@@ -45,11 +45,11 @@ namespace AMDiS {
template <typename ITLSolver> template <typename ITLSolver>
class ITL_OEMSolver : public MTL4Solver< MTLTypes::MTLMatrix, MTLTypes::MTLVector, ITL_OEMSolver_runner< ITLSolver > > { class ITL_OEMSolver : public MTL4Solver< MTLTypes::MTLMatrix, MTLTypes::MTLVector, ITL_OEMSolver_runner< ITLSolver > > {
protected: protected:
public: public:
/// The constructor reads needed parameters and sets solvers \ref name. /// The constructor reads needed parameters and sets solvers \ref name.
ITL_OEMSolver(std::string name) : ITL_OEMSolver(std::string name) :
MTL4Solver< MTLTypes::MTLMatrix, MTLTypes::MTLVector, ITL_OEMSolver_runner< ITLSolver > >(name) {} MTL4Solver< MTLTypes::MTLMatrix, MTLTypes::MTLVector, ITL_OEMSolver_runner< ITLSolver > >(name) {}
~ITL_OEMSolver() {} ~ITL_OEMSolver() {}
...@@ -77,19 +77,19 @@ namespace AMDiS { ...@@ -77,19 +77,19 @@ namespace AMDiS {
*/ */
template <typename ITLSolver> template <typename ITLSolver>
class ITL_OEMSolver_para class ITL_OEMSolver_para
: public MTL4Solver< MTLMatrix, MTLVector, ITL_OEMSolver_para_runner< ITLSolver > > // ITL_OEMSolver<ITLSolver> : public MTL4Solver< MTLMatrix, MTLVector, ITL_OEMSolver_para_runner< ITLSolver > > // ITL_OEMSolver<ITLSolver>
{ {
public: public:
/// The constructor reads needed parameters and sets solvers \ref name. /// The constructor reads needed parameters and sets solvers \ref name.
ITL_OEMSolver_para(std::string name) ITL_OEMSolver_para(std::string name)
: MTL4Solver< MTLMatrix, MTLVector, ITL_OEMSolver_para_runner< ITLSolver > >(name) : MTL4Solver< MTLMatrix, MTLVector, ITL_OEMSolver_para_runner< ITLSolver > >(name)
{ {
} }
~ITL_OEMSolver_para() {} ~ITL_OEMSolver_para() {}
/// Set parameter of iterative solver /// Set parameter of iterative solver
class Creator : public OEMSolverCreator class Creator : public OEMSolverCreator
{ {
......
...@@ -9,51 +9,51 @@ namespace AMDiS { ...@@ -9,51 +9,51 @@ namespace AMDiS {
/// Pointer to the right preconditioner /// Pointer to the right preconditioner
ITL_BasePreconditioner< Vector >* r; ITL_BasePreconditioner< Vector >* r;
PreconPair(): PreconPair():
l(NULL), r(NULL) l(NULL), r(NULL)
{} {}
}; };
struct BaseITL_runner { struct BaseITL_runner {
OEMSolver& oem; OEMSolver& oem;
BaseITL_runner(OEMSolver* oemPtr): BaseITL_runner(OEMSolver* oemPtr):
oem(*oemPtr) oem(*oemPtr)
{ {
TEST_EXIT(oemPtr != NULL)("need a real oemsolver\n"); TEST_EXIT(oemPtr != NULL)("need a real oemsolver\n");
} }
template< typename Vector , typename Matrix > template< typename Vector , typename Matrix >
void setPrecon(PreconPair< Vector >& pair, const Matrix& matrix) void setPrecon(PreconPair< Vector >& pair, const Matrix& matrix)
{ {
/// Creator for the left preconditioner /// Creator for the left preconditioner
CreatorInterface< ITL_BasePreconditioner< Vector > >* leftCreator(NULL); CreatorInterface< ITL_BasePreconditioner< Vector > >* leftCreator(NULL);
/// Creator for the right preconditioner /// Creator for the right preconditioner
CreatorInterface< ITL_BasePreconditioner< Vector > >* rightCreator(NULL); CreatorInterface< ITL_BasePreconditioner< Vector > >* rightCreator(NULL);
std::string preconType("no"); std::string preconType("no");
Parameters::get(oem.getName() + "->left precon", preconType); Parameters::get(oem.getName() + "->left precon", preconType);
leftCreator = CreatorMap<ITL_BasePreconditioner< Vector > >::getCreator(preconType); leftCreator = CreatorMap<ITL_BasePreconditioner< Vector > >::getCreator(preconType);
TEST_EXIT(leftCreator != NULL) TEST_EXIT(leftCreator != NULL)
("there is no creator for the given left preconditioner"); ("there is no creator for the given left preconditioner");
preconType = "no"; preconType = "no";
Parameters::get(oem.getName() + "->right precon", preconType); Parameters::get(oem.getName() + "->right precon", preconType);
rightCreator = CreatorMap<ITL_BasePreconditioner< Vector > >::getCreator(preconType); rightCreator = CreatorMap<ITL_BasePreconditioner< Vector > >::getCreator(preconType);
TEST_EXIT(rightCreator != NULL) TEST_EXIT(rightCreator != NULL)
("there is no creator for the given right preconditioner"); ("there is no creator for the given right preconditioner");
pair.l = leftCreator->create(matrix); pair.l = leftCreator->create(matrix);
pair.r = rightCreator->create(matrix); pair.r = rightCreator->create(matrix);
} }
}; };
template< typename ITLSolver > template< typename ITLSolver >
struct ITL_OEMSolver_para_runner : BaseITL_runner { struct ITL_OEMSolver_para_runner : BaseITL_runner {
ITL_OEMSolver_para_runner(OEMSolver* oem_): ITL_OEMSolver_para_runner(OEMSolver* oem_):
BaseITL_runner(oem_), BaseITL_runner(oem_),
ell(1) ell(1)
{ {
ell=oem.getMaxIterations(); ell=oem.getMaxIterations();
Parameters::get(oem.getName() + "->ell", ell); Parameters::get(oem.getName() + "->ell", ell);
...@@ -63,11 +63,11 @@ namespace AMDiS { ...@@ -63,11 +63,11 @@ namespace AMDiS {
int solve(const Matrix& A, Vector& x, Vector& b) int solve(const Matrix& A, Vector& x, Vector& b)
{ {
itl::cyclic_iteration<typename Matrix::value_type> iter(b, oem.getMaxIterations(), oem.getRelative(), itl::cyclic_iteration<typename Matrix::value_type> iter(b, oem.getMaxIterations(), oem.getRelative(),
oem.getTolerance(), oem.getPrint_cycle()); oem.getTolerance(), oem.getPrint_cycle());
static PreconPair< Vector > preconPair; static PreconPair< Vector > preconPair;
if (preconPair.l == NULL || preconPair.r == NULL || !oem.getMultipleRhs()) if (preconPair.l == NULL || preconPair.r == NULL || !oem.getMultipleRhs())
BaseITL_runner::setPrecon(preconPair, A); BaseITL_runner::setPrecon(preconPair, A);
int error = ITLSolver()(A, x, b, *(preconPair.l), *(preconPair.r), iter, ell); int error = ITLSolver()(A, x, b, *(preconPair.l), *(preconPair.r), iter, ell);
oem.setIterations(iter.iterations()); oem.setIterations(iter.iterations());
...@@ -75,7 +75,7 @@ namespace AMDiS { ...@@ -75,7 +75,7 @@ namespace AMDiS {
oem.setErrorCode(error); oem.setErrorCode(error);
return error; return error;
} }
private: private:
int ell; int ell;
}; };
...@@ -84,18 +84,18 @@ namespace AMDiS { ...@@ -84,18 +84,18 @@ namespace AMDiS {
ITL_OEMSolver_runner(OEMSolver* oem): ITL_OEMSolver_runner(OEMSolver* oem):
BaseITL_runner(oem) BaseITL_runner(oem)
{} {}
template< typename Matrix, typename Vector> template< typename Matrix, typename Vector>
int solve(const Matrix& A, Vector& x, Vector& b) int solve(const Matrix& A, Vector& x, Vector& b)
{ {
itl::cyclic_iteration<typename Matrix::value_type> iter(b, oem.getMaxIterations(), oem.getRelative(), itl::cyclic_iteration<typename Matrix::value_type> iter(b, oem.getMaxIterations(), oem.getRelative(),
oem.getTolerance(), oem.getPrint_cycle()); oem.getTolerance(), oem.getPrint_cycle());
static PreconPair< Vector > preconPair; static PreconPair< Vector > preconPair;
if (preconPair.l == NULL || preconPair.r == NULL || !oem.getMultipleRhs()) if (preconPair.l == NULL || preconPair.r == NULL || !oem.getMultipleRhs())
BaseITL_runner::setPrecon(preconPair, A); BaseITL_runner::setPrecon(preconPair, A);
int error = ITLSolver()(A, x, b, *(preconPair.l), *(preconPair.r), iter); int error = ITLSolver()(A, x, b, *(preconPair.l), *(preconPair.r), iter);
oem.setErrorCode(error); oem.setErrorCode(error);
......
...@@ -25,53 +25,49 @@ ...@@ -25,53 +25,49 @@
#include <iostream> #include <iostream>
namespace AMDiS { namespace AMDiS {
template< typename MTLMatrix, typename MTLVector, typename Worker >
class MTL4Solver : public OEMSolver {
protected:
Worker worker; template< typename MTLMatrix, typename MTLVector, typename Worker >
class MTL4Solver : public OEMSolver {
template< typename Matrix, typename Vector, typename Mapper > protected:
int solve(const Matrix& A, Vector& x, Vector& b, Mapper& mapper) Worker worker;
{
MTLMatrix matrix(mapper.nRow(), mapper.nCol());
set_to_zero(matrix);
MatMap< const Matrix, Mapper > matMap(A,mapper);
matrix << matMap;
MTLVector mtl_x(mapper.nRow()); template< typename Matrix, typename Vector, typename Mapper >
set_to_zero(mtl_x); int solve(const Matrix& A, Vector& x, Vector& b, Mapper& mapper)
VecMap< Vector, Mapper > xVecMap(x, mapper); {
mtl_x << xVecMap; MTLMatrix matrix(mapper.nRow(), mapper.nCol());
set_to_zero(matrix);
MatMap< const Matrix, Mapper > matMap(A,mapper);
matrix << matMap;
MTLVector mtl_b(mapper.nRow()); MTLVector mtl_x(mapper.nRow());
set_to_zero(mtl_b); set_to_zero(mtl_x);
VecMap< Vector, Mapper> bVecMap(b, mapper); VecMap< Vector, Mapper > xVecMap(x, mapper);
mtl_b << bVecMap; mtl_x << xVecMap;
error = worker.solve(matrix, mtl_x, mtl_b); MTLVector mtl_b(mapper.nRow());
set_to_zero(mtl_b);
VecMap< Vector, Mapper> bVecMap(b, mapper);
mtl_b << bVecMap;
mtl_x >> xVecMap; error = worker.solve(matrix, mtl_x, mtl_b);
return error;
}
public: mtl_x >> xVecMap;
MTL4Solver(std::string n): return error;
OEMSolver(n), }
worker(this)
{
FUNCNAME("MTL4Solver()");
} public:
MTL4Solver(std::string n):
OEMSolver(n),
worker(this)
{}
virtual int solveSystem(const SolverMatrix<Matrix<DOFMatrix*> >& A, virtual int solveSystem(const SolverMatrix<Matrix<DOFMatrix*> >& A,
SystemVector& x, SystemVector& x,
SystemVector& b, SystemVector& b,
VectorialMapper& m) VectorialMapper& m)
{ {
return solve(A,x,b,m); return solve(A,x,b,m);
} }
}; };
......
...@@ -73,9 +73,7 @@ namespace AMDiS { ...@@ -73,9 +73,7 @@ namespace AMDiS {
print_cycle(100), print_cycle(100),
iterations(-1), iterations(-1),
error(-1), error(-1),
multipleRhs(false)/*, multipleRhs(false)
leftPrecon(NULL),
rightPrecon(NULL)*/
{} {}
/// ///
...@@ -99,47 +97,13 @@ namespace AMDiS { ...@@ -99,47 +97,13 @@ namespace AMDiS {
SystemVector& x, SystemVector& x,
SystemVector& b, SystemVector& b,
VectorialMapper&) = 0; VectorialMapper&) = 0;
#if 0
{
int ns = x.getSize(), // Number of systems.
size = x.getUsedSize(); // Size of all DOFVectors
// Copy vectors
mtl::dense_vector<value_type> xx(size), bb(size);
xx << x;
bb << b
/* for (int i = 0, counter = 0; i < ns; i++) {
DOFVector<double>::Iterator it_b(b.getDOFVector(i), USED_DOFS);
DOFVector<double>::Iterator it_x(x.getDOFVector(i), USED_DOFS);
for (it_b.reset(), it_x.reset(); !it_b.end(); ++it_b, ++it_x) {
bb[counter] = *it_b;
xx[counter] = *it_x;
counter++;
}
}
*/
// Solver on DOFVector for single system
DOFMatrix::base_matrix_type baseA;
baseA << A;
int r = solveSystem(baseA, xx, bb);
for (int i = 0, counter = 0; i < ns; i++) {
DOFVector<double>::Iterator it(x.getDOFVector(i), USED_DOFS);
for (it.reset(); !it.end(); ++it)
*it = xx[counter++];
}
return r;
}
#endif
inline int solveSystem(const SolverMatrix< Matrix< DOFMatrix* > >& A, inline int solveSystem(const SolverMatrix< Matrix< DOFMatrix* > >& A,
SystemVector& x, SystemVector& x,
SystemVector& b) SystemVector& b)
{ {
VectorialMapper mapper(A); VectorialMapper mapper(A);
return solveSystem(A, x, b, mapper); return solveSystem(A, x, b, mapper);
} }
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
...@@ -306,13 +270,6 @@ namespace AMDiS { ...@@ -306,13 +270,6 @@ namespace AMDiS {
* as they can do the factorization of the matrix only once. * as they can do the factorization of the matrix only once.
*/ */
bool multipleRhs; bool multipleRhs;
#if 0
/// Left preconditioner (ignored by some iterative solvers and by UmfPack)
PreconCreator *leftPrecon;
/// Right preconditioner (ignored by some iterative solvers and by UmfPack)
PreconCreator *rightPrecon;
#endif
}; };
/** /**
......
...@@ -634,6 +634,8 @@ namespace AMDiS { ...@@ -634,6 +634,8 @@ namespace AMDiS {
{ {
FUNCNAME("ProblemStat::buildAfterCoarsen()"); FUNCNAME("ProblemStat::buildAfterCoarsen()");
VtkWriter::writeFile(rhs->getDOFVector(0), "test.vtu");
// buildAfterCoarsen_sebastianMode(adaptInfo, flag); // buildAfterCoarsen_sebastianMode(adaptInfo, flag);
// return; // return;
......
...@@ -52,6 +52,8 @@ namespace AMDiS { ...@@ -52,6 +52,8 @@ namespace AMDiS {
store_symbolic(0), store_symbolic(0),
symmetric_strategy(0) symmetric_strategy(0)
{ {
FUNCNAME("Umfpack_runner::Umfpack_runner()");
TEST_EXIT_DBG(oem_ != NULL)("Need real OEMSolver\n"); TEST_EXIT_DBG(oem_ != NULL)("Need real OEMSolver\n");
Parameters::get(oem.getName() + "->store symbolic", store_symbolic); Parameters::get(oem.getName() + "->store symbolic", store_symbolic);
Parameters::get(oem.getName() + "->symmetric strategy", symmetric_strategy); Parameters::get(oem.getName() + "->symmetric strategy", symmetric_strategy);
...@@ -60,15 +62,14 @@ namespace AMDiS { ...@@ -60,15 +62,14 @@ namespace AMDiS {
template< typename Vector> template< typename Vector>
int solve(const Matrix& A, Vector& x, Vector& b) int solve(const Matrix& A, Vector& x, Vector& b)
{ {
FUNCNAME("(UmfPackSolver.h)::solve()"); FUNCNAME("Umfpack_runner::solve()");
if (!solver) { if (!solver) {
if (!symmetric_strategy) if (!symmetric_strategy)
solver = new mtl::matrix::umfpack::solver<matrix_type>(A); solver = new mtl::matrix::umfpack::solver<matrix_type>(A);
else else
solver = new mtl::matrix::umfpack::solver<matrix_type>(A, UMFPACK_STRATEGY_SYMMETRIC); solver = new mtl::matrix::umfpack::solver<matrix_type>(A, UMFPACK_STRATEGY_SYMMETRIC);
} else { } else {
if (!oem.getMultipleRhs()) { if (!oem.getMultipleRhs()) {
if (store_symbolic) if (store_symbolic)
solver->update_numeric(); solver->update_numeric();
else else
...@@ -77,16 +78,14 @@ namespace AMDiS { ...@@ -77,16 +78,14 @@ namespace AMDiS {
} }
int code = (*solver)(x, b); int code = (*solver)(x, b);
if( oem.getInfo() > 0) { if (oem.getInfo() > 0) {
mtl::dense_vector<typename matrix_type::value_type> r(b); mtl::dense_vector<typename matrix_type::value_type> r(b);
r -= A * x; r -= A * x;
double residual = two_norm(r); double residual = two_norm(r);
oem.setResidual(residual); oem.setResidual(residual);
oem.setErrorCode(code); oem.setErrorCode(code);
std::cout << "UmfPackSolver: ||b-Ax|| = " << residual << "\n"; std::cout << "UmfPackSolver: ||b-Ax|| = " << residual << "\n";
if (residual > oem.getTolerance()) { TEST_EXIT(residual <= oem.getTolerance())("Tolerance tol = %e could not be reached!\n Set tolerance by '->solver->tolerance:' \n", oem.getTolerance());
ERROR_EXIT("Tolerance tol=%e could not be reached!\n Set tolerance by '->solver->tolerance:' \n", oem.getTolerance());
}
} }
return code; return code;
...@@ -94,11 +93,11 @@ namespace AMDiS { ...@@ -94,11 +93,11 @@ namespace AMDiS {
~Umfpack_runner() ~Umfpack_runner()
{ {
if(!solver) if (!solver)
delete solver; delete solver;
} }
private: private:
mtl::matrix::umfpack::solver<matrix_type> *solver; mtl::matrix::umfpack::solver<matrix_type> *solver;
int store_symbolic; int store_symbolic;
...@@ -108,7 +107,7 @@ namespace AMDiS { ...@@ -108,7 +107,7 @@ namespace AMDiS {
using namespace MTLTypes; using namespace MTLTypes;
class UmfPackSolver : public MTL4Solver<MTLMatrix, MTLVector, Umfpack_runner< MTLMatrix > > class UmfPackSolver : public MTL4Solver<MTLMatrix, MTLVector, Umfpack_runner< MTLMatrix > >
{ {
protected: protected:
public: public:
/// Creator class used in the OEMSolverMap. /// Creator class used in the OEMSolverMap.
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "ProblemStat.h" #include "ProblemStat.h"
#include "SystemVector.h" #include "SystemVector.h"
#include "OEMSolver.h" #include "OEMSolver.h"
#include "Debug.h"
namespace AMDiS { namespace AMDiS {
...@@ -79,7 +80,7 @@ namespace AMDiS { ...@@ -79,7 +80,7 @@ namespace AMDiS {
} }
ProblemStatSeq::buildAfterCoarsen(adaptInfo, flag, (i == 0), asmVector); ProblemStatSeq::buildAfterCoarsen(adaptInfo, flag, (i == 0), asmVector);
solver->setMultipleRhs(i != 0); // solver->setMultipleRhs(i != 0);
ProblemStatSeq::solve(adaptInfo); ProblemStatSeq::solve(adaptInfo);
*(stageSolutions[i]) = *solution; *(stageSolutions[i]) = *solution;
......
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