Bridge++
Ver. 2.0.2
shiftsolver_CG.cpp
Go to the documentation of this file.
1
14
#include "
Solver/ashiftsolver_CG.h
"
15
#include "
Solver/ashiftsolver_CG-tmpl.h
"
16
#include "
Solver/shiftsolver_CG.h
"
17
18
template
<>
19
const
std::string
AShiftsolver_CG<Field, Fopr>::class_name
20
=
"Shiftsolver_CG"
;
21
22
template
class
AShiftsolver_CG<Field, Fopr>
;
23
24
/*
25
//====================================================================
26
void Shiftsolver_CG::set_parameters(const Parameters& params)
27
{
28
std::string vlevel;
29
if (!params.fetch_string("verbose_level", vlevel)) {
30
m_vl = vout.set_verbose_level(vlevel);
31
}
32
33
//- fetch and check input parameters
34
int Niter;
35
double Stop_cond;
36
37
int err = 0;
38
err += params.fetch_int("maximum_number_of_iteration", Niter);
39
err += params.fetch_double("convergence_criterion_squared", Stop_cond);
40
41
if (err) {
42
vout.crucial(m_vl, "Error at %s: input parameter not found.\n", class_name.c_str());
43
exit(EXIT_FAILURE);
44
}
45
46
set_parameters(Niter, Stop_cond);
47
}
48
49
50
//====================================================================
51
void Shiftsolver_CG::set_parameters(const int Niter, const double Stop_cond)
52
{
53
//- print input parameters
54
vout.general(m_vl, "%s:\n", class_name.c_str());
55
vout.general(m_vl, " Niter = %d\n", Niter);
56
vout.general(m_vl, " Stop_cond = %8.2e\n", Stop_cond);
57
58
//- range check
59
int err = 0;
60
err += ParameterCheck::non_negative(Niter);
61
err += ParameterCheck::square_non_zero(Stop_cond);
62
63
if (err) {
64
vout.crucial(m_vl, "Error at %s: parameter range check failed.\n", class_name.c_str());
65
exit(EXIT_FAILURE);
66
}
67
68
//- store values
69
m_Niter = Niter;
70
m_Stop_cond = Stop_cond;
71
}
72
73
74
//====================================================================
75
void Shiftsolver_CG::solve(std::vector<Field>& xq,
76
const std::vector<double>& sigma,
77
const Field& b,
78
int& Nconv, double& diff)
79
{
80
int Nshift = sigma.size();
81
82
vout.paranoiac(m_vl, " Shift CG solver start.\n");
83
vout.paranoiac(m_vl, " number of shift = %d\n", Nshift);
84
vout.paranoiac(m_vl, " values of shift:\n");
85
for (int i = 0; i < Nshift; ++i) {
86
vout.paranoiac(m_vl, " %d %12.8f\n", i, sigma[i]);
87
}
88
89
m_snorm = 1.0 / b.norm2();
90
91
int Nconv2 = -1;
92
93
reset_field(b, sigma, Nshift);
94
95
copy(m_s, b);
96
copy(m_r, b);
97
98
double rr = 0.0;
99
100
solve_init(rr);
101
102
vout.detailed(m_vl, " iter: %8d %22.15e\n", 0, rr * m_snorm);
103
104
bool is_converged = false;
105
106
for (int iter = 0; iter < m_Niter; iter++) {
107
solve_step(rr);
108
109
Nconv2 += 1;
110
111
vout.detailed(m_vl, " iter: %8d %22.15e %4d\n", (iter + 1), rr * m_snorm, m_Nshift2);
112
113
if (rr * m_snorm < m_Stop_cond) {
114
is_converged = true;
115
break;
116
}
117
}
118
119
if (!is_converged) {
120
vout.crucial(m_vl, "Error at %s: not converged.\n", class_name.c_str());
121
exit(EXIT_FAILURE);
122
}
123
124
125
std::vector<double> diffs(Nshift);
126
for (int i = 0; i < Nshift; ++i) {
127
diffs[i] = 0.0;
128
}
129
130
for (int i = 0; i < Nshift; ++i) {
131
m_fopr->mult(m_s, m_x[i]);
132
axpy(m_s, sigma[i], m_x[i]);
133
axpy(m_s, -1.0, b);
134
135
double diff1 = sqrt(m_s.norm2() * m_snorm);
136
137
vout.paranoiac(m_vl, " %4d %22.15e\n", i, diff1);
138
139
// if (diff1 > diff2) diff2 = diff1;
140
diffs[i] = diff1;
141
}
142
143
#pragma omp barrier
144
#pragma omp master
145
{
146
double diff2 = -1.0;
147
148
for (int i = 0; i < Nshift; ++i) {
149
if (diffs[i] > diff2) diff2 = diffs[i];
150
}
151
152
diff = diff2;
153
154
Nconv = Nconv2;
155
}
156
#pragma omp barrier
157
158
for (int i = 0; i < Nshift; ++i) {
159
copy(xq[i], m_x[i]);
160
}
161
162
vout.paranoiac(m_vl, " diff(max) = %22.15e \n", diff);
163
}
164
165
166
//====================================================================
167
void Shiftsolver_CG::solve_init(double& rr)
168
{
169
int Nshift = m_p.size();
170
171
vout.paranoiac(m_vl, "number of shift = %d\n", Nshift);
172
173
for (int i = 0; i < Nshift; ++i) {
174
copy(m_p[i], m_s);
175
scal(m_x[i], 0.0);
176
}
177
178
copy(m_r, m_s);
179
rr = m_r.norm2();
180
181
#pragma omp barrier
182
#pragma omp master
183
{
184
m_alpha_p = 0.0;
185
m_beta_p = 1.0;
186
}
187
#pragma omp barrier
188
}
189
190
191
//====================================================================
192
void Shiftsolver_CG::solve_step(double& rr)
193
{
194
m_fopr->mult(m_s, m_p[0]);
195
axpy(m_s, m_sigma0, m_p[0]);
196
197
double rr_p = rr;
198
double pa_p = dot(m_s, m_p[0]);
199
double beta = -rr_p / pa_p;
200
201
axpy(m_x[0], -beta, m_p[0]);
202
axpy(m_r, beta, m_s);
203
rr = m_r.norm2();
204
205
double alpha = rr / rr_p;
206
207
aypx(alpha, m_p[0], m_r);
208
209
#pragma omp barrier
210
#pragma omp master
211
{
212
m_pp[0] = rr;
213
}
214
#pragma omp barrier
215
216
double alpha_h = 1.0 + m_alpha_p * beta / m_beta_p;
217
218
for (int ish = 1; ish < m_Nshift2; ++ish) {
219
double zeta = (alpha_h - m_csh2[ish] * beta) / m_zeta1[ish]
220
+ (1.0 - alpha_h) / m_zeta2[ish];
221
zeta = 1.0 / zeta;
222
double zr = zeta / m_zeta1[ish];
223
double beta_s = beta * zr;
224
double alpha_s = alpha * zr * zr;
225
226
axpy(m_x[ish], -beta_s, m_p[ish]);
227
scal(m_p[ish], alpha_s);
228
axpy(m_p[ish], zeta, m_r);
229
230
double ppr = m_p[ish].norm2();
231
232
#pragma omp barrier
233
#pragma omp master
234
{
235
m_pp[ish] = ppr * m_snorm;
236
237
m_zeta2[ish] = m_zeta1[ish];
238
m_zeta1[ish] = zeta;
239
}
240
#pragma omp barrier
241
}
242
243
int ish1 = m_Nshift2;
244
245
for (int ish = m_Nshift2 - 1; ish >= 0; --ish) {
246
vout.paranoiac(m_vl, "%4d %16.8e\n", ish, m_pp[ish]);
247
if (m_pp[ish] > m_Stop_cond) {
248
ish1 = ish + 1;
249
break;
250
}
251
}
252
253
#pragma omp barrier
254
#pragma omp master
255
{
256
m_Nshift2 = ish1;
257
258
m_alpha_p = alpha;
259
m_beta_p = beta;
260
}
261
#pragma omp barrier
262
}
263
264
265
//====================================================================
266
void Shiftsolver_CG::reset_field(const FIELD& b,
267
const std::vector<double>& sigma,
268
const int Nshift)
269
{
270
#pragma omp barrier
271
#pragma omp master
272
{
273
int Nin = b.nin();
274
int Nvol = b.nvol();
275
int Nex = b.nex();
276
277
m_p.resize(Nshift);
278
m_x.resize(Nshift);
279
m_zeta1.resize(Nshift);
280
m_zeta2.resize(Nshift);
281
m_csh2.resize(Nshift);
282
m_pp.resize(Nshift);
283
284
for (int i = 0; i < Nshift; ++i) {
285
m_p[i].reset(Nin, Nvol, Nex);
286
m_x[i].reset(Nin, Nvol, Nex);
287
m_zeta1[i] = 1.0;
288
m_zeta2[i] = 1.0;
289
m_csh2[i] = sigma[i] - sigma[0];
290
291
m_pp[i] = 0.0;
292
}
293
294
m_s.reset(Nin, Nvol, Nex);
295
m_r.reset(Nin, Nvol, Nex);
296
297
m_sigma0 = sigma[0];
298
299
m_Nshift2 = Nshift;
300
}
301
#pragma omp barrier
302
}
303
*/
304
305
//====================================================================
306
//============================================================END=====
shiftsolver_CG.h
ashiftsolver_CG.h
ashiftsolver_CG-tmpl.h
AShiftsolver_CG
Multishift Conjugate Gradient solver.
Definition:
ashiftsolver_CG.h:32
src
lib
Solver
shiftsolver_CG.cpp
Generated on Sat Feb 10 2024 14:20:00 for Bridge++ by
1.8.17