TheBoussinesqModel  3.2.1
 All Data Structures Files Functions Variables Typedefs Macros Pages
preconditioned_conjugate_gradient.c
Go to the documentation of this file.
1 
30 #include "turtle.h"
31 #include "t_utilities.h"
32 #include "doublevector_utilities.h"
34 
35 #define MAX_VALUE_DIAG 1e-10
36 #define MAX_REITERTION 1 //50
37 // CG_CONVERGENCE 1e-10
38 
40 
41 int get_diagonal(DOUBLEVECTOR *diagonal, t_Matrix_element Matrix) {
42  /*
43  *
44  * \author Emanuele Cordano
45  * \date May 2008
46  *
47  *\param diagonal (DOUBLEVECTOR *) - the diagonal doublevector of the matrix
48  *\param Matrix (t_Matrix) - a matrix from which the diagonal is extracted
49  *
50  *\brief it saved the square root of diagonal of Matrix in a doublevector
51  *
52  *\return 0 in case of success , -1 otherwise
53  *
54  */
55 
56  long i;
57  DOUBLEVECTOR *x_v;
58 
59 
60  x_v=new_doublevector(diagonal->nh);
61 // y_v=new_doublevector(diagonal->nh);
62  for (i=x_v->nl;i<=x_v->nh;i++) {
63  x_v->element[i]=0.0;
64 
65  }
66  for (i=x_v->nl;i<=x_v->nh;i++) {
67  x_v->element[i]=1.0;
68  diagonal->element[i]=(*Matrix)(i,x_v);
69 
70  x_v->element[i]=0.0;
71  }
72 
73  free_doublevector(x_v);
74  //free_doublevector(y_v);
75 
76 
77  return 0;
78 }
79 
81 
99  double delta,delta_new,alpha,beta,delta0;
100  DOUBLEVECTOR *r, *d,*q,*y,*sr,*diag;
101 
102  int sl;
103  long icnt_max;
104  long j;
105  double p;
106 
107  r=new_doublevector(x->nh);
108  d=new_doublevector(x->nh);
109  q=new_doublevector(x->nh);
110  y=new_doublevector(x->nh);
111  sr=new_doublevector(x->nh);
112  diag=new_doublevector(x->nh);
113 
114  icnt=0;
115  icnt_max=x->nh;
116 
117 
118  for (j=x->nl;j<=x->nh;j++){
119  y->element[j]=(*funz)(j,x);
120 
121  }
122 
123  get_diagonal(diag,funz);
124 // print_doublevector_elements(diag,PRINT);
125 // stop_execution();
126 
127  delta_new=0.0;
128 
129  for (j=y->nl;j<=y->nh;j++) {
130 
131  r->element[j]=b->element[j]-y->element[j];
132  if (diag->element[j]<0.0) {
133  diag->element[j]=1.0;
134  printf("\n Error in jacobi_preconditioned_conjugate_gradient_search function: diagonal of the matrix (%lf) is negative at %ld \n",diag->element[j],j);
135  stop_execution();
136  }
137  // diag->element[j]=fmax(diag->element[j],MAX_VALUE_DIAG*fabs(r->element[j]));
138 
139  //d->element[j]=r->element[j]/diag->element[j];
140  if (diag->element[j]==0.0) { //ec 20100315
141  d->element[j]=0.0;
142  } else {
143  d->element[j]=r->element[j]/(diag->element[j]);
144  }
145 
146  delta_new+=r->element[j]*d->element[j];
147  }
148 
149 
150  // printf("delta0 =%le", delta0);
151 
152  // double epsilon0=epsilon;
153 // double pe=5.0;
154 
155 
156  while ((icnt<=icnt_max) && (max_doublevector(r)>epsilon)) {
157 
158  delta=delta_new;
159  // s=(* funz)(q,d);
160  p=0.0;
161 
162  for(j=q->nl;j<=q->nh;j++) {
163  q->element[j]=(*funz)(j,d);
164  p+=q->element[j]*d->element[j];
165 
166  }
167  alpha=delta_new/p;
168  for(j=x->nl;j<=x->nh;j++) {
169  x->element[j]=x->element[j]+alpha*d->element[j];
170  }
171 
172 
173  delta_new=0.0;
174  sl=0;
175  for (j=y->nl;j<=y->nh;j++) {
176  if (icnt%MAX_REITERTION==0) {
177  y->element[j]=(*funz)(j,x);
178  r->element[j]=b->element[j]-y->element[j];
179  } else {
180  r->element[j]=r->element[j]-alpha*q->element[j];
181  }
182  if (diag->element[j]==0.0) { // ec_20100315
183  sr->element[j]=0.0;
184  d->element[j]=0.0;
185  } else {
186  sr->element[j]=r->element[j]/diag->element[j];
187  }
188 
189  delta_new+=sr->element[j]*r->element[j];
190 /* if (((j==y->nl) && sl==0 ) || (sl==1)) {
191  printf("delta_new =%le (j=%ld) ",delta_new,j);
192  // if (delta_new==0.0) sl=1;
193  }*/
194  }
195  beta=delta_new/delta;
196  // double aa=1.0e-21;
197  // ec Initial residual: printf("delta_new =%le p=%le alpha=%le beta=%le delta_max=%le\n",delta_new,p,alpha,beta,max_doublevector(r));
198 
199  for (j=d->nl;j<=d->nh;j++) {
200  d->element[j]=sr->element[j]+beta*d->element[j];
201  }
202 
203  icnt++;
204 
205 
206  }
207  free_doublevector(diag);
208  free_doublevector(sr);
213 
214 
215 
216  return icnt;
217 
218 }
219 
220 
221 
222