213{
214 const size_t maxIter = nAllVars + 1;
215 std::vector<double> x(nAllVars, 0.0);
216 std::vector<double> y(nAllVars, 0.0);
217 std::vector<double> residual(nAllVars, 0.0);
218 std::vector<double> r(nAllVars, 0.0);
219 std::vector<double>
w(nAllVars, 0.0);
220 std::vector<double> wOld(nAllVars, 0.0);
221 std::vector<double>
g(nAllVars, 0.0);
222 std::vector<double>
c(nAllVars, 0.0);
223 std::vector<double>
s(nAllVars, 0.0);
224 std::vector<double> hisGs(nAllVars + 1, 0.0);
225 std::vector<double> v(nAllVars * (maxIter + 1), 0.0);
226
227 std::vector<double> vecFromV(nAllVars, 0.0);
228
229 std::vector<double> h((nAllVars + 1) * maxIter, 0.0);
230 double beta = 0.0, gs, normb = 0.0;
231 size_t m = 0;
232
233 for (size_t i = 0; i < nAllVars; ++i)
234 normb += rhsDir[i] * rhsDir[i];
235 normb = sqrt(normb);
236
237 for (size_t i = 0; i < nAllVars; ++i)
238 residual[i] = rhsDir[i];
239
240#pragma omp parallel for
241 for (int aflI = 0; aflI < nafl; ++aflI)
242 {
243
244 r = residual;
245 }
246
247 for (size_t i = 0; i < nAllVars; ++i)
248 beta += r[i] * r[i];
249 beta = sqrt(beta);
250 gs = beta;
252
253
254 if (beta == 0)
255 {
256 for (size_t aflI = 0; aflI < nafl; ++aflI)
257 {
258 for (size_t i = 0; i < vsize[aflI]; ++i)
259 gam[aflI][i] = 0.0;
260 R[aflI] = 0.0;
261 }
262 return;
263 }
264
265 for (size_t aflI = 0; aflI < nafl; ++aflI)
266 R[aflI] = x[x.size() - nafl + aflI];
267
268 for (size_t i = 0; i < nAllVars; ++i)
269 v[i * (maxIter + 1) + 0] = r[i] / beta;
270
271 for (size_t j = 0; j < nAllVars; ++j)
272 {
273 double timer1 = omp_get_wtime();
274
275 for (size_t p = 0; p < nAllVars; ++p)
276 vecFromV[p] = v[p * (maxIter + 1) + j];
277
278
279
280 for (int i = 0; i < nAllVars; ++i)
281 {
282 wOld[i] = 0.0;
283 for (int jj = 0; jj < nAllVars; ++jj)
284 {
285 wOld[i] += mtrDir[i * nAllVars + jj] * vecFromV[jj];
286 }
287 }
288
289 double timer2 = omp_get_wtime();
290
291#pragma omp parallel for
292 for (int aflI = 0; aflI < nafl; ++aflI)
293 {
294
296 }
297
298 for (size_t i = 0; i <= j; ++i)
299 {
300 h[i * maxIter + j] = 0.0;
301 for (size_t q = 0; q < nAllVars; ++q)
302 h[i * maxIter + j] +=
w[q] * v[q * (maxIter + 1) + i];
303
304 for (size_t q = 0; q < nAllVars; ++q)
305 w[q] -= h[i * maxIter + j] * v[q * (maxIter + 1) + i];
306 }
307
308 h[(j + 1) * maxIter + j] = 0.0;
309 for (size_t p = 0; p < nAllVars; ++p)
310 h[(j + 1) * maxIter + j] +=
w[p] *
w[p];
311 h[(j + 1) * maxIter + j] = sqrt(h[(j + 1) * maxIter + j]);
312
313 for (size_t p = 0; p < nAllVars; ++p)
314 v[p * (maxIter + 1) + (j + 1)] =
w[p] / h[(j + 1) * maxIter + j];
315
316 for (size_t i = 0; i < j; ++i)
317 {
318 double buf = h[i * maxIter + j];
319 h[i * maxIter + j] =
c[i] * buf +
s[i] * h[(i + 1) * maxIter + j];
320 h[(i + 1) * maxIter + j] = -
s[i] * buf +
c[i] * h[(i + 1) * maxIter + j];
321 }
322
323 double zn = sqrt(h[j * maxIter + j] * h[j * maxIter + j] + h[(j + 1) * maxIter + j] * h[(j + 1) * maxIter + j]);
324 c[j] = fabs(h[j * maxIter + j] / zn);
325 s[j] =
c[j] * h[(j + 1) * maxIter + j] / h[j * maxIter + j];
326
328
329 h[j * maxIter + j] =
c[j] * h[j * maxIter + j] +
s[j] * h[(j + 1) * maxIter + j];
330 h[(j + 1) * maxIter + j] = 0.0;
331 hisGs[j] = fabs(gs) / normb;
332
334 {
335 m = j + 1;
336 break;
337 }
338 }
339
340
341 for (size_t i = 0; i < m; ++i)
342 {
345 if (i < (m - 1))
346 g[i + 1] = -
s[i] * buf;
347
348 }
349 y[m - 1] =
g[m - 1] / h[(m - 1) * maxIter + (m - 1)];
350
351 for (size_t i = m - 2; i + 1 > 0; --i)
352 {
353 double sum = 0;
354 for (size_t j = i + 1; j < m; ++j)
355 sum += h[i * maxIter + j] * y[j];
356
357 y[i] = (
g[i] - sum) / h[i * maxIter + i];
358 }
359
360 for (size_t p = 0; p < nAllVars; ++p)
361 {
362 for (size_t q = 0; q < m; ++q)
363 x[p] += v[p * (maxIter + 1) + q] * y[q];
364 }
365
366 std::cout << "#iterations: " << m << std::endl;
367
368 for (size_t aflI = 0; aflI < nafl; ++aflI)
369 {
370 for (size_t i = 0; i < vsize[aflI]; ++i)
371 gam[aflI][i] = x[pos[aflI] + i];
372 }
373
374 for (size_t aflI = 0; aflI < nafl; ++aflI)
375 R[aflI] = x[x.size() - nafl + aflI];
376}