OEMSolver.hh 2.54 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include "CreatorInterface.h"
#include "Parameters.h"
#include "Preconditioner.h"
#include "CreatorMap.h"
#include "MatVecMultiplier.h"

namespace AMDiS {

  template<typename VectorType>
  OEMSolver<VectorType>::OEMSolver(::std::string name_)
    : name(name_),
      tolerance(1.e-8),
      relative(false),
      max_iter(1000),
      info(0),
      residual(0),
      leftPrecon(NULL),
      rightPrecon(NULL),
      vectorCreator(NULL)
  {
    FUNCNAME("OEMSolver::OEMSolver");
  }


  template<typename VectorType>
  void OEMSolver<VectorType>::initParameters()
  {
    FUNCNAME("OEMSolver::initParameters()");

    GET_PARAMETER(0, name + "->tolerance", "%f", &tolerance);
    GET_PARAMETER(0, name + "->relative", "%d", &relative);
    GET_PARAMETER(0, name + "->max iteration", "%d", &max_iter);
    GET_PARAMETER(0, name + "->info", "%d", &info);
  }

  template<typename VectorType>
  OEMSolver<VectorType>::~OEMSolver()
  {
    FUNCNAME("OEMSolver::~OEMSolver");
  }


  template<typename VectorType>
  void OEMSolver<VectorType>::start_info(const char *funcName)
  {
    info = info > 10 ? 10 : info;

    INFO(info,6)("with tolerance %e\n", tolerance);
    PRINT_INFO(info,6)("\n");
    INFO(info,2)("iter. |     residual |  red.\n");
    return;
  }

  template<typename VectorType>
  void OEMSolver<VectorType>::break_info(const char *funcName,
					 const char *reason,
					 int        iter,
					 double     res,
					 double     *ores)
  {
    if (ores  &&  *ores > 0) {
      INFO(info,2)("%5d | %12.5e | %8.2e\n", iter, res, res / (*ores));
    } else {
      INFO(info,2)("%5d | %12.5e |\n", iter, res);
    }
    INFO(info,2)("stop due to: %s\n", reason);

    residual = res;
  }

  template<typename VectorType>
  int OEMSolver<VectorType>::solve_info(const char * funcName, int iter,
					double res, double *ores)
  {
    static int  step[11] = {0, 1000, 500, 200, 100, 50, 20, 10, 5, 2, 1};

    if (res <= tolerance || (info && (iter%step[info] == 0)) || iter == max_iter) {
	if (ores) {
	    if (*ores > 0.0) {
		double red = res/(*ores);
		INFO(info,2)("%5d | %12.5e | %8.2e\n", iter, res, red);
	    } else {
		INFO(info,2)("%5d | %12.5e | --------\n", iter, res);
	    }
	    *ores = res;
	} else {
	    INFO(info,2)("%5d | %12.5e |\n", iter, res);
	}
    }

    residual = res;

    if (iter == max_iter && res > tolerance) {
	INFO(info,1)("tolerance %e not reached after %d iterations\n", tolerance, iter);
	return(2);
    }

    if (res <= tolerance) {
99
      INFO(info,6)("finished successfully with %d iterations\n",iter);
100
101
102
103
104
105
106
	return(1);
    }

    return 0;
  }

}