File: info.c

package info (click to toggle)
alberta 3.1.1-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 19,176 kB
  • sloc: ansic: 135,836; cpp: 6,601; makefile: 2,801; sh: 333; fortran: 180; lisp: 177; xml: 30
file content (105 lines) | stat: -rw-r--r-- 2,891 bytes parent folder | download | duplicates (5)
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
99
100
101
102
103
104
105
#include "alberta_util.h"
#include "alberta_util_intern.h"

/*--------------------------------------------------------------------------*/
/*---  information output for linear solvers  ------------------------------*/
/*--------------------------------------------------------------------------*/

void start_info(const char *funcName, OEM_DATA *oem)
{
  oem->info = oem->info > 10 ? 10 : oem->info;

  INFO(oem->info,6,"with tolerance %le", oem->tolerance);
  if (oem->restart > 0)
    PRINT_INFO(oem->info,6," and restart %d\n", oem->restart);
  else
    PRINT_INFO(oem->info,6,"\n");
  INFO(oem->info,2,"iter. |     residual |  red.\n");
  fflush(stdout);
  return;
}

void break_info(const char *funcName, OEM_DATA *oem, const char *reason, 
		int iter, REAL res, REAL *ores, WORKSPACE *ws)
{
  if (*ores  &&  *ores > 0)
    INFO(oem->info,2,"%5d | %12.5le | %8.2le\n", iter, res, res/(*ores));
  else
    INFO(oem->info,2,"%5d | %12.5le |\n", iter);
  INFO(oem->info,2,"stop due to: %s\n", reason);
  fflush(stdout);

  free_oem_workspace(ws, oem);
  oem->residual = res;
}

int solve_info(const char *funcName, OEM_DATA *oem, int iter, REAL res, 
	       REAL *ores, WORKSPACE *ws)
{
  static int  step[11] = {0, 1000, 500, 200, 100, 50, 20, 10, 5, 2, 1};

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

  if (iter >= oem->max_iter || res <= oem->tolerance) {
    if (res > oem->tolerance) {
      INFO(oem->info,1,"tolerance %le not reached after %d iterations\n", 
	   oem->tolerance, iter);
    } else {
      INFO(oem->info,6,"finished successfully with %d iterations\n",iter);
    }
    fflush(stdout);
    free_oem_workspace(ws, oem);
    return 1;
  }

  fflush(stdout);
  return 0;
}

/*--------------------------------------------------------------------------*/
/*---  checking of workspace, reallocation of workspace if neccesary  ------*/
/*--------------------------------------------------------------------------*/

WORKSPACE *check_workspace(const char *funcName, const char *file, int line,
			   size_t size, WORKSPACE *ws)
{
  if (!ws)
  {
    ws = GET_WORKSPACE(size*sizeof(REAL));
  }
  else if (size*sizeof(REAL) > ws->size)
  {
    WARNING("need workspace for %d REALs\n", size);
    WARNING("reallocating workspace of length %d\n", size*sizeof(REAL));
    REALLOC_WORKSPACE(ws, size*sizeof(REAL));
  }
  return(ws);
}

void free_oem_workspace(WORKSPACE *ws, OEM_DATA *oem)
{
  if (ws != oem->ws)
    FREE_WORKSPACE(ws);
  return;
}