13 #include "../general/annotation.hpp"
14 #include "../general/forall.hpp"
15 #include "../general/globals.hpp"
16 #include "../fem/bilinearform.hpp"
60 if (dot_prod_type == 0)
76 if (dot_prod_type == 0)
83 MPI_Comm_rank(comm, &rank);
110 const Vector& x,
bool final)
const
121 ess_tdof_list(nullptr),
130 Solver(a.FESpace()->GetTrueVSize()),
133 ess_tdof_list(&ess_tdofs),
152 ess_tdof_list(&ess_tdofs),
185 MFEM_ASSERT(
height ==
width,
"not a square matrix!");
187 ess_tdof_list =
nullptr;
199 const double delta = damping;
200 auto D = diag.
Read();
201 auto DI = dinv.
Write();
202 MFEM_FORALL(i,
height, DI[i] = delta / D[i]; );
203 if (ess_tdof_list && ess_tdof_list->
Size() > 0)
205 auto I = ess_tdof_list->
Read();
206 MFEM_FORALL(i, ess_tdof_list->
Size(), DI[I[i]] =
delta; );
214 MFEM_ASSERT(x.
Size() ==
Width(),
"invalid input vector");
215 MFEM_ASSERT(y.
Size() ==
Height(),
"invalid output vector");
219 MFEM_VERIFY(oper,
"iterative_mode == true requires the forward operator");
220 oper->
Mult(y, residual);
229 auto DI = dinv.
Read();
230 auto R = residual.
Read();
232 MFEM_FORALL(i,
height, Y[i] += DI[i] * R[i]; );
238 int order_,
double max_eig_estimate_)
242 max_eig_estimate(max_eig_estimate_),
247 ess_tdof_list(ess_tdofs),
249 oper(&oper_) {
Setup(); }
255 int order_, MPI_Comm comm,
int power_iterations,
double power_tolerance)
260 int order_,
int power_iterations,
double power_tolerance)
268 ess_tdof_list(ess_tdofs),
282 power_iterations, power_tolerance);
290 int order_,
double max_eig_estimate_)
297 int order_, MPI_Comm comm,
int power_iterations,
double power_tolerance)
299 power_iterations, power_tolerance) { }
304 int order_,
int power_iterations,
double power_tolerance)
313 auto D = diag.
Read();
314 auto X = dinv.
Write();
315 MFEM_FORALL(i, N, X[i] = 1.0 / D[i]; );
316 auto I = ess_tdof_list.
Read();
317 MFEM_FORALL(i, ess_tdof_list.
Size(), X[I[i]] = 1.0; );
322 double upper_bound = 1.2 * max_eig_estimate;
323 double lower_bound = 0.3 * max_eig_estimate;
324 double theta = 0.5 * (upper_bound + lower_bound);
325 double delta = 0.5 * (upper_bound - lower_bound);
331 coeffs[0] = 1.0 / theta;
336 double tmp_0 = 1.0/(pow(delta, 2) - 2*pow(theta, 2));
337 coeffs[0] = -4*theta*tmp_0;
343 double tmp_0 = 3*pow(delta, 2);
344 double tmp_1 = pow(theta, 2);
345 double tmp_2 = 1.0/(-4*pow(theta, 3) + theta*tmp_0);
346 coeffs[0] = tmp_2*(tmp_0 - 12*tmp_1);
347 coeffs[1] = 12/(tmp_0 - 4*tmp_1);
348 coeffs[2] = -4*tmp_2;
353 double tmp_0 = pow(delta, 2);
354 double tmp_1 = pow(theta, 2);
355 double tmp_2 = 8*tmp_0;
356 double tmp_3 = 1.0/(pow(delta, 4) + 8*pow(theta, 4) - tmp_1*tmp_2);
357 coeffs[0] = tmp_3*(32*pow(theta, 3) - 16*theta*tmp_0);
358 coeffs[1] = tmp_3*(-48*tmp_1 + tmp_2);
359 coeffs[2] = 32*theta*tmp_3;
360 coeffs[3] = -8*tmp_3;
365 double tmp_0 = 5*pow(delta, 4);
366 double tmp_1 = pow(theta, 4);
367 double tmp_2 = pow(theta, 2);
368 double tmp_3 = pow(delta, 2);
369 double tmp_4 = 60*tmp_3;
370 double tmp_5 = 20*tmp_3;
371 double tmp_6 = 1.0/(16*pow(theta, 5) - pow(theta, 3)*tmp_5 + theta*tmp_0);
372 double tmp_7 = 160*tmp_2;
373 double tmp_8 = 1.0/(tmp_0 + 16*tmp_1 - tmp_2*tmp_5);
374 coeffs[0] = tmp_6*(tmp_0 + 80*tmp_1 - tmp_2*tmp_4);
375 coeffs[1] = tmp_8*(tmp_4 - tmp_7);
376 coeffs[2] = tmp_6*(-tmp_5 + tmp_7);
377 coeffs[3] = -80*tmp_8;
378 coeffs[4] = 16*tmp_6;
382 MFEM_ABORT(
"Chebyshev smoother not implemented for order = " << order);
390 MFEM_ABORT(
"Chebyshev smoother not implemented for iterative mode");
395 MFEM_ABORT(
"Chebyshev smoother requires operator");
404 for (
int k = 0; k < order; ++k)
409 oper->
Mult(residual, helperVector);
410 residual = helperVector;
415 auto Dinv = dinv.
Read();
417 MFEM_FORALL(i, n, R[i] *= Dinv[i]; );
421 auto C = coeffs.
Read();
422 MFEM_FORALL(i, n, Y[i] += C[k] * R[i]; );
471 double r0, nom, nom0, nomold = 1, cf;
487 nom0 = nom = sqrt(
Dot(
z,
z));
491 nom0 = nom = sqrt(
Dot(
r,
r));
495 mfem::out <<
" Iteration : " << setw(3) << 0 <<
" ||Br|| = "
527 nom = sqrt(
Dot(
z,
z));
531 nom = sqrt(
Dot(
r,
r));
536 mfem::out <<
" Iteration : " << setw(3) << i <<
" ||Br|| = "
537 << nom <<
"\tConv. rate: " << cf <<
'\n';
543 mfem::out <<
"Number of SLI iterations: " << i <<
'\n'
544 <<
"Conv. rate: " << cf <<
'\n';
546 mfem::out <<
"||Br_0|| = " << nom0 <<
'\n'
547 <<
"||Br_N|| = " << nom <<
'\n'
548 <<
"Number of SLI iterations: " << i <<
'\n';
562 mfem::err <<
"SLI: No convergence!" <<
'\n';
563 mfem::out <<
"||Br_0|| = " << nom0 <<
'\n'
564 <<
"||Br_N|| = " << nom <<
'\n'
565 <<
"Number of SLI iterations: " <<
final_iter <<
'\n';
569 mfem::out <<
"Average reduction factor = "
576 int print_iter,
int max_num_iter,
577 double RTOLERANCE,
double ATOLERANCE)
591 int print_iter,
int max_num_iter,
592 double RTOLERANCE,
double ATOLERANCE)
619 double r0, den, nom, nom0, betanom,
alpha, beta;
642 nom0 = nom =
Dot(d,
r);
643 MFEM_ASSERT(
IsFinite(nom),
"nom = " << nom);
646 mfem::out <<
" Iteration : " << setw(3) << 0 <<
" (B r, r) = "
655 mfem::out <<
"PCG: The preconditioner is not positive definite. (Br, r) = "
674 MFEM_ASSERT(
IsFinite(den),
"den = " << den);
679 mfem::out <<
"PCG: The operator is not positive definite. (Ad, d) = "
709 MFEM_ASSERT(
IsFinite(betanom),
"betanom = " << betanom);
714 mfem::out <<
"PCG: The preconditioner is not positive definite. (Br, r) = "
724 mfem::out <<
" Iteration : " << setw(3) << i <<
" (B r, r) = "
734 mfem::out <<
"Number of PCG iterations: " << i <<
'\n';
738 mfem::out <<
" Iteration : " << setw(3) << i <<
" (B r, r) = "
762 MFEM_ASSERT(
IsFinite(den),
"den = " << den);
767 mfem::out <<
"PCG: The operator is not positive definite. (Ad, d) = "
784 mfem::out <<
" Iteration : " << setw(3) << 0 <<
" (B r, r) = "
790 mfem::out <<
"PCG: No convergence!" <<
'\n';
794 mfem::out <<
"Average reduction factor = "
795 << pow (betanom/nom0, 0.5/
final_iter) <<
'\n';
803 int print_iter,
int max_num_iter,
804 double RTOLERANCE,
double ATOLERANCE)
818 int print_iter,
int max_num_iter,
819 double RTOLERANCE,
double ATOLERANCE)
835 double &cs,
double &sn)
842 else if (fabs(dy) > fabs(dx))
844 double temp = dx / dy;
845 sn = 1.0 / sqrt( 1.0 + temp*temp );
850 double temp = dy / dx;
851 cs = 1.0 / sqrt( 1.0 + temp*temp );
858 double temp = cs * dx + sn * dy;
859 dy = -sn * dx + cs * dy;
869 for (
int i = k; i >= 0; i--)
872 for (
int j = i - 1; j >= 0; j--)
874 y(j) -= h(j,i) * y(i);
878 for (
int j = 0; j <= k; j++)
931 double beta =
Norm(r);
932 MFEM_ASSERT(
IsFinite(beta),
"beta = " << beta);
947 <<
" Iteration : " << setw(3) << 0
948 <<
" ||B r|| = " << beta << (
print_level == 3 ?
" ...\n" :
"\n");
957 if (v[0] == NULL) { v[0] =
new Vector(n); }
958 v[0]->Set(1.0/beta, r);
959 s = 0.0;
s(0) = beta;
961 for (i = 0; i <
m && j <=
max_iter; i++, j++)
973 for (k = 0; k <= i; k++)
975 H(k,i) =
Dot(w, *v[k]);
976 w.
Add(-H(k,i), *v[k]);
980 MFEM_ASSERT(
IsFinite(H(i+1,i)),
"Norm(w) = " << H(i+1,i));
981 if (v[i+1] == NULL) { v[i+1] =
new Vector(n); }
982 v[i+1]->Set(1.0/H(i+1,i), w);
984 for (k = 0; k < i; k++)
993 resid = fabs(
s(i+1));
994 MFEM_ASSERT(
IsFinite(resid),
"resid = " << resid);
1007 mfem::out <<
" Pass : " << setw(2) << (j-1)/
m+1
1008 <<
" Iteration : " << setw(3) << j
1009 <<
" ||B r|| = " << resid <<
'\n';
1033 MFEM_ASSERT(
IsFinite(beta),
"beta = " << beta);
1060 mfem::out <<
"GMRES: No convergence!\n";
1065 for (i = 0; i < v.
Size(); i++)
1090 double beta =
Norm(r);
1091 MFEM_ASSERT(
IsFinite(beta),
"beta = " << beta);
1106 <<
" Iteration : " << setw(3) << 0
1107 <<
" || r || = " << beta << endl;
1114 for (i= 0; i<=
m; i++)
1123 if (v[0] == NULL) { v[0] =
new Vector(b.
Size()); }
1125 v[0] ->
Add (1.0/beta, r);
1126 s = 0.0;
s(0) = beta;
1128 for (i = 0; i <
m && j <=
max_iter; i++, j++)
1131 if (z[i] == NULL) { z[i] =
new Vector(b.
Size()); }
1144 for (k = 0; k <= i; k++)
1146 H(k,i) =
Dot( r, *v[k]);
1147 r.Add(-H(k,i), (*v[k]));
1151 if (v[i+1] == NULL) { v[i+1] =
new Vector(b.
Size()); }
1153 v[i+1] ->
Add (1.0/H(i+1,i), r);
1155 for (k = 0; k < i; k++)
1164 double resid = fabs(
s(i+1));
1165 MFEM_ASSERT(
IsFinite(resid),
"resid = " << resid);
1168 mfem::out <<
" Pass : " << setw(2) << (j-1)/
m+1
1169 <<
" Iteration : " << setw(3) << j
1170 <<
" || r || = " << resid << endl;
1186 for (i= 0; i<=
m; i++)
1188 if (v[i]) {
delete v[i]; }
1189 if (z[i]) {
delete z[i]; }
1205 MFEM_ASSERT(
IsFinite(beta),
"beta = " << beta);
1217 for (i= 0; i<=
m; i++)
1219 if (v[i]) {
delete v[i]; }
1220 if (z[i]) {
delete z[i]; }
1226 for (i = 0; i <=
m; i++)
1228 if (v[i]) {
delete v[i]; }
1229 if (z[i]) {
delete z[i]; }
1235 mfem::out <<
"FGMRES: No convergence!" << endl;
1243 int &max_iter,
int m,
double &tol,
double atol,
int printit)
1262 int print_iter,
int max_num_iter,
int m,
double rtol,
double atol)
1264 GMRES(A, x, b, B, max_num_iter, m, rtol, atol, print_iter);
1286 double resid, tol_goal;
1287 double rho_1, rho_2=1.0,
alpha=1.0, beta,
omega=1.0;
1302 MFEM_ASSERT(
IsFinite(resid),
"resid = " << resid);
1304 mfem::out <<
" Iteration : " << setw(3) << 0
1305 <<
" ||r|| = " << resid <<
'\n';
1311 if (resid <= tol_goal)
1325 mfem::out <<
" Iteration : " << setw(3) << i
1326 <<
" ||r|| = " << resid <<
'\n';
1341 beta = (rho_1/rho_2) * (
alpha/omega);
1357 MFEM_ASSERT(
IsFinite(resid),
"resid = " << resid);
1358 if (resid < tol_goal)
1362 mfem::out <<
" Iteration : " << setw(3) << i
1363 <<
" ||s|| = " << resid <<
'\n';
1370 mfem::out <<
" Iteration : " << setw(3) << i
1371 <<
" ||s|| = " << resid;
1389 MFEM_ASSERT(
IsFinite(resid),
"resid = " << resid);
1392 mfem::out <<
" ||r|| = " << resid <<
'\n';
1395 if (resid < tol_goal)
1417 int &max_iter,
double &tol,
double atol,
int printit)
1426 bicgstab.
Mult(b, x);
1433 int print_iter,
int max_num_iter,
double rtol,
double atol)
1435 BiCGSTAB(A, x, b, B, max_num_iter, rtol, atol, print_iter);
1461 double beta, eta, gamma0, gamma1, sigma0, sigma1;
1462 double alpha,
delta, rho1, rho2, rho3, norm_goal;
1482 eta = beta = sqrt(
Dot(*z,
v1));
1483 MFEM_ASSERT(
IsFinite(eta),
"eta = " << eta);
1484 gamma0 = gamma1 = 1.;
1485 sigma0 = sigma1 = 0.;
1489 if (eta <= norm_goal)
1497 mfem::out <<
"MINRES: iteration " << setw(3) << 0 <<
": ||r||_B = "
1511 MFEM_ASSERT(
IsFinite(alpha),
"alpha = " << alpha);
1518 delta = gamma1*alpha - gamma0*sigma1*beta;
1520 rho2 = sigma1*alpha + gamma0*gamma1*beta;
1530 MFEM_ASSERT(
IsFinite(beta),
"beta = " << beta);
1531 rho1 = hypot(delta, beta);
1535 w0.
Set(1./rho1, *z);
1539 add(1./rho1, *z, -rho2/rho1,
w1,
w0);
1543 add(-rho3/rho1,
w0, -rho2/rho1,
w1,
w0);
1544 w0.
Add(1./rho1, *z);
1548 gamma1 = delta/rho1;
1550 x.
Add(gamma1*eta,
w0);
1556 MFEM_ASSERT(
IsFinite(eta),
"eta = " << eta);
1558 if (fabs(eta) <= norm_goal)
1565 mfem::out <<
"MINRES: iteration " << setw(3) << it <<
": ||r||_B = "
1566 << fabs(eta) <<
'\n';
1568 Monitor(it, fabs(eta), *z, x);
1603 eta = sqrt(
Dot(*z,
v1));
1604 mfem::out <<
"MINRES: iteration " << setw(3) << it <<
": ||r||_B = "
1605 << eta <<
" (re-computed)" <<
'\n';
1610 mfem::out <<
"MINRES: No convergence!\n";
1615 int max_it,
double rtol,
double atol)
1629 int print_it,
int max_it,
double rtol,
double atol)
1647 MFEM_ASSERT(
height ==
width,
"square Operator is required.");
1655 MFEM_ASSERT(
oper != NULL,
"the Operator is not set (use SetOperator).");
1656 MFEM_ASSERT(
prec != NULL,
"the Solver is not set (use SetSolver).");
1659 double norm0, norm, norm_goal;
1675 norm0 = norm =
Norm(
r);
1681 for (it = 0;
true; it++)
1683 MFEM_ASSERT(
IsFinite(norm),
"norm = " << norm);
1686 mfem::out <<
"Newton iteration " << setw(2) << it
1687 <<
" : ||r|| = " << norm;
1690 mfem::out <<
", ||r||/||r_0|| = " << norm/norm0;
1696 if (norm <= norm_goal)
1729 add(x, -c_scale,
c, x);
1747 const double rtol_max,
1754 this->alpha =
alpha;
1755 this->gamma =
gamma;
1760 const double fnorm)
const
1768 double sg_threshold = 0.1;
1788 MFEM_ABORT(
"Unknown adaptive linear solver rtol version");
1793 if (sg_eta > sg_threshold) { eta = std::max(eta, sg_eta); }
1797 iterative_solver->SetRelTol(eta);
1801 mfem::out <<
"Eisenstat-Walker rtol = " << eta <<
"\n";
1808 const double fnorm)
const
1827 MFEM_VERIFY(
oper != NULL,
"the Operator is not set (use SetOperator).");
1839 int last_saved_id = -1;
1842 double norm0, norm, norm_goal;
1854 if (have_b) {
r -=
b; }
1858 norm0 = norm =
Norm(
r);
1860 for (it = 0;
true; it++)
1862 MFEM_ASSERT(
IsFinite(norm),
"norm = " << norm);
1866 <<
" : ||r|| = " << norm;
1869 mfem::out <<
", ||r||/||r_0|| = " << norm/norm0;
1874 if (norm <= norm_goal)
1893 add(x, -c_scale,
c, x);
1905 sk =
c; sk *= -c_scale;
1909 last_saved_id = (last_saved_id ==
m-1) ? 0 : last_saved_id+1;
1910 skM.SetCol(last_saved_id, sk);
1911 ykM.
SetCol(last_saved_id, yk);
1914 for (
int i = last_saved_id; i > -1; i--)
1916 skM.GetColumn(i, sk);
1918 rho(i) = 1./
Dot(sk, yk);
1924 for (
int i =
m-1; i > last_saved_id; i--)
1926 skM.GetColumn(i, sk);
1928 rho(i) = 1./
Dot(sk, yk);
1937 for (
int i = last_saved_id+1; i <
m ; i++)
1939 skM.GetColumn(i,sk);
1941 double betai = rho(i)*
Dot(yk,
c);
1945 for (
int i = 0; i < last_saved_id+1 ; i++)
1947 skM.GetColumn(i,sk);
1949 double betai = rho(i)*
Dot(yk,
c);
1962 int m_max,
int m_min,
int m_step,
double cf,
1963 double &tol,
double &atol,
int printit)
1970 Vector s(m+1), cs(m+1), sn(m+1);
1977 double normb = w.Norml2();
1987 double beta = r.
Norml2();
1989 resid = beta / normb;
1991 if (resid * resid <= tol)
1993 tol = resid * resid;
2000 <<
" Iteration : " << setw(3) << 0
2001 <<
" (r, r) = " << beta*beta <<
'\n';
2003 tol *= (normb*normb);
2004 tol = (atol > tol) ? atol : tol;
2008 for (i= 0; i<=m; i++)
2015 while (j <= max_iter)
2018 v[0] ->
Add (1.0/beta, r);
2019 s = 0.0;
s(0) = beta;
2023 for (i = 0; i < m && j <= max_iter; i++)
2028 for (k = 0; k <= i; k++)
2030 H(k,i) = w * (*v[k]);
2031 w.
Add(-H(k,i), (*v[k]));
2034 H(i+1,i) = w.Norml2();
2036 v[i+1] ->
Add (1.0/H(i+1,i), w);
2038 for (k = 0; k < i; k++)
2047 resid = fabs(
s(i+1));
2050 <<
" Iteration : " << setw(3) << i+1
2051 <<
" (r, r) = " << resid*resid <<
'\n';
2053 if ( resid*resid < tol)
2056 tol = resid * resid;
2058 for (i= 0; i<=m; i++)
2077 if ( resid*resid < tol)
2079 tol = resid * resid;
2081 for (i= 0; i<=m; i++)
2090 if (m - m_step >= m_min)
2103 tol = resid * resid;
2104 for (i= 0; i<=m; i++)
2114 : C(C_), D(D_), c_e(NULL), d_lo(NULL), d_hi(NULL), x_lo(NULL), x_hi(NULL),
2123 MFEM_ASSERT(
C,
"The C operator is unspecified -- can't set constraints.");
2124 MFEM_ASSERT(c.
Size() ==
C->
Height(),
"Wrong size of the constraint.");
2132 MFEM_ASSERT(
D,
"The D operator is unspecified -- can't set constraints.");
2134 "Wrong size of the constraint.");
2142 "Wrong size of the constraint.");
2159 MFEM_WARNING(
"Objective functional is ignored as SLBQP always minimizes"
2160 "the l2 norm of (x - x_target).");
2162 MFEM_ASSERT(prob.
GetC(),
"Linear constraint is not set.");
2163 MFEM_ASSERT(prob.
GetC()->
Height() == 1,
"Solver expects scalar constraint.");
2183 mfem::out <<
"SLBQP iteration " << it <<
": residual = " << r
2184 <<
", lambda = " << l <<
'\n';
2206 const double smin = 0.1;
2213 mfem::out <<
"SLBQP bracketing phase" <<
'\n';
2217 r =
solve(l,xt,x,nclip);
2231 llow = l; rlow = r; l = l + dl;
2234 r =
solve(l,xt,x,nclip);
2237 while ((r < 0) && (nclip <
max_iter))
2241 if (s < smin) { s = smin; }
2246 r =
solve(l,xt,x,nclip);
2254 lupp = l; rupp = r; l = l - dl;
2257 r =
solve(l,xt,x,nclip);
2260 while ((r > 0) && (nclip <
max_iter))
2264 if (s < smin) { s = smin; }
2269 r =
solve(l,xt,x,nclip);
2282 mfem::out <<
"SLBQP secant phase" <<
'\n';
2285 s = 1.0 - rlow/rupp; dl = dl/
s; l = lupp - dl;
2288 r =
solve(l,xt,x,nclip);
2291 while ( (fabs(r) > tol) && (nclip <
max_iter) )
2297 lupp = l; rupp = r; s = 1.0 - rlow/rupp;
2298 dl = (lupp - llow)/s; l = lupp - dl;
2303 if (s < smin) { s = smin; }
2305 lnew = 0.75*llow + 0.25*l;
2306 if (lnew < l-dl) { lnew = l-dl; }
2307 lupp = l; rupp = r; l = lnew;
2308 s = (lupp - llow)/(lupp - l);
2316 llow = l; rlow = r; s = 1.0 - rlow/rupp;
2317 dl = (lupp - llow)/s; l = lupp - dl;
2322 if (s < smin) { s = smin; }
2324 lnew = 0.75*lupp + 0.25*l;
2325 if (lnew < l+dl) { lnew = l+dl; }
2326 llow = l; rlow = r; l = lnew;
2327 s = (lupp - llow)/(lupp - l);
2332 r =
solve(l,xt,x,nclip);
2341 mfem::err <<
"SLBQP not converged!" <<
'\n';
2351 mfem::out <<
"SLBQP iterations = " << nclip <<
'\n';
2352 mfem::out <<
"SLBQP lambda = " << l <<
'\n';
2353 mfem::out <<
"SLBQP residual = " << r <<
'\n';
2357 struct WeightMinHeap
2359 const std::vector<double> &w;
2360 std::vector<size_t> c;
2361 std::vector<int> loc;
2363 WeightMinHeap(
const std::vector<double> &w_) : w(w_)
2365 c.reserve(w.size());
2366 loc.resize(w.size());
2367 for (
size_t i=0; i<w.size(); ++i) { push(i); }
2370 size_t percolate_up(
size_t pos,
double val)
2372 for (; pos > 0 && w[c[(pos-1)/2]] > val; pos = (pos-1)/2)
2374 c[pos] = c[(pos-1)/2];
2375 loc[c[(pos-1)/2]] = pos;
2380 size_t percolate_down(
size_t pos,
double val)
2382 while (2*pos+1 < c.size())
2384 size_t left = 2*pos+1;
2385 size_t right = left+1;
2387 if (right < c.size() && w[c[right]] < w[c[left]]) { tgt = right; }
2388 else { tgt = left; }
2389 if (w[c[tgt]] < val)
2407 size_t pos = c.size()-1;
2408 pos = percolate_up(pos, val);
2416 size_t j = c.back();
2420 if (c.empty()) {
return i; }
2423 pos = percolate_down(pos, val);
2429 void update(
size_t i)
2431 size_t pos = loc[i];
2433 pos = percolate_up(pos, val);
2434 pos = percolate_down(pos, val);
2439 bool picked(
size_t i)
2454 for (
int i=0; i<n; ++i)
2456 for (
int j=I[i]; j<I[i+1]; ++j)
2458 V[j] = abs(V[j]/D[i]);
2462 std::vector<double> w(n, 0.0);
2463 for (
int k=0; k<n; ++k)
2466 for (
int ii=I[k]; ii<I[k+1]; ++ii)
2471 for (
int kk=I[i]; kk<I[i+1]; ++kk)
2479 for (
int jj=I[k]; jj<I[k+1]; ++jj)
2482 if (j == k) {
continue; }
2483 double C_kj = V[jj];
2484 bool ij_exists =
false;
2485 for (
int jj2=I[i]; jj2<I[i+1]; ++jj2)
2493 if (!ij_exists) { w[k] += pow(C_ik*C_kj,2); }
2499 WeightMinHeap w_heap(w);
2503 for (
int ii=0; ii<n; ++ii)
2505 int pi = w_heap.pop();
2508 for (
int kk=I[pi]; kk<I[pi+1]; ++kk)
2511 if (w_heap.picked(k)) {
continue; }
2515 for (
int ii2=I[k]; ii2<I[k+1]; ++ii2)
2518 if (w_heap.picked(i)) {
continue; }
2521 for (
int kk2=I[i]; kk2<I[i+1]; ++kk2)
2529 for (
int jj=I[k]; jj<I[k+1]; ++jj)
2532 if (j == k || w_heap.picked(j)) {
continue; }
2533 double C_kj = V[jj];
2534 bool ij_exists =
false;
2535 for (
int jj2=I[i]; jj2<I[i+1]; ++jj2)
2543 if (!ij_exists) { w[k] += pow(C_ik*C_kj,2); }
2556 block_size(block_size_),
2558 reordering(reordering_)
2565 :
BlockILU(block_size_, reordering_, k_fill_)
2587 MFEM_ABORT(
"BlockILU must be created with a SparseMatrix or HypreParMatrix");
2592 MFEM_ASSERT(A->
Finalized(),
"Matrix must be finalized.");
2593 CreateBlockPattern(*A);
2597 void BlockILU::CreateBlockPattern(
const SparseMatrix &A)
2599 MFEM_VERIFY(k_fill == 0,
"Only block ILU(0) is currently supported.");
2600 if (A.
Height() % block_size != 0)
2602 MFEM_ABORT(
"BlockILU: block size must evenly divide the matrix size");
2606 const int *I = A.
GetI();
2607 const int *J = A.
GetJ();
2608 const double *V = A.
GetData();
2610 int nblockrows = nrows / block_size;
2612 std::vector<std::set<int>> unique_block_cols(nblockrows);
2614 for (
int iblock = 0; iblock < nblockrows; ++iblock)
2616 for (
int bi = 0; bi < block_size; ++bi)
2618 int i = iblock * block_size + bi;
2619 for (
int k = I[i]; k < I[i + 1]; ++k)
2621 unique_block_cols[iblock].insert(J[k] / block_size);
2624 nnz += unique_block_cols[iblock].size();
2629 SparseMatrix C(nblockrows, nblockrows);
2630 for (
int iblock = 0; iblock < nblockrows; ++iblock)
2632 for (
int jblock : unique_block_cols[iblock])
2634 for (
int bi = 0; bi < block_size; ++bi)
2636 int i = iblock * block_size + bi;
2637 for (
int k = I[i]; k < I[i + 1]; ++k)
2640 if (j >= jblock * block_size && j < (jblock + 1) * block_size)
2642 C.Add(iblock, jblock, V[k]*V[k]);
2649 double *CV = C.GetData();
2650 for (
int i=0; i<C.NumNonZeroElems(); ++i)
2652 CV[i] = sqrt(CV[i]);
2661 MFEM_ABORT(
"BlockILU: unknown reordering")
2668 for (
int i=0; i<nblockrows; ++i)
2676 for (
int i=0; i<nblockrows; ++i)
2682 std::vector<std::vector<int>> unique_block_cols_perminv(nblockrows);
2683 for (
int i=0; i<nblockrows; ++i)
2685 std::vector<int> &cols = unique_block_cols_perminv[i];
2686 for (
int j : unique_block_cols[P[i]])
2688 cols.push_back(Pinv[j]);
2690 std::sort(cols.begin(), cols.end());
2697 AB.
SetSize(block_size, block_size, nnz);
2698 DB.
SetSize(block_size, block_size, nblockrows);
2701 ipiv.
SetSize(block_size*nblockrows);
2704 for (
int iblock = 0; iblock < nblockrows; ++iblock)
2706 int iblock_perm = P[iblock];
2707 for (
int jblock : unique_block_cols_perminv[iblock])
2709 int jblock_perm = P[jblock];
2710 if (iblock == jblock)
2712 ID[iblock] = counter;
2714 JB[counter] = jblock;
2715 for (
int bi = 0; bi < block_size; ++bi)
2717 int i = iblock_perm*block_size + bi;
2718 for (
int k = I[i]; k < I[i + 1]; ++k)
2721 if (j >= jblock_perm*block_size && j < (jblock_perm + 1)*block_size)
2723 int bj = j - jblock_perm*block_size;
2725 AB(bi, bj, counter) = val;
2727 if (iblock == jblock)
2729 DB(bi, bj, iblock) = val;
2736 IB[iblock + 1] = counter;
2740 void BlockILU::Factorize()
2742 int nblockrows =
Height()/block_size;
2745 for (
int i=0; i<nblockrows; ++i)
2747 LUFactors factorization(DB.
GetData(i), &ipiv[i*block_size]);
2748 factorization.Factor(block_size);
2754 DenseMatrix A_ik, A_ij, A_kj;
2756 for (
int i=1; i<nblockrows; ++i)
2759 for (
int kk=IB[i]; kk<IB[i+1]; ++kk)
2763 if (k == i) {
break; }
2766 MFEM_ABORT(
"Matrix must be sorted with nonzero diagonal");
2768 LUFactors A_kk_inv(DB.
GetData(k), &ipiv[k*block_size]);
2769 A_ik.UseExternalData(&AB(0,0,kk), block_size, block_size);
2771 A_kk_inv.RightSolve(block_size, block_size, A_ik.GetData());
2773 for (
int jj=kk+1; jj<IB[i+1]; ++jj)
2776 if (j <= k) {
continue; }
2777 A_ij.UseExternalData(&AB(0,0,jj), block_size, block_size);
2778 for (
int ll=IB[k]; ll<IB[k+1]; ++ll)
2783 A_kj.UseExternalData(&AB(0,0,ll), block_size, block_size);
2790 LUFactors factorization(DB.
GetData(i), &ipiv[i*block_size]);
2791 factorization.Factor(block_size);
2803 MFEM_ASSERT(
height > 0,
"BlockILU(0) preconditioner is not constructed");
2804 int nblockrows =
Height()/block_size;
2813 for (
int i=0; i<nblockrows; ++i)
2816 for (
int ib=0; ib<block_size; ++ib)
2818 yi[ib] = b[ib + P[i]*block_size];
2820 for (
int k=IB[i]; k<ID[i]; ++k)
2830 for (
int i=nblockrows-1; i >= 0; --i)
2833 for (
int ib=0; ib<block_size; ++ib)
2835 xi[ib] = y[ib + i*block_size];
2837 for (
int k=ID[i]+1; k<IB[i+1]; ++k)
2845 LUFactors A_ii_inv(&DB(0,0,i), &ipiv[i*block_size]);
2847 A_ii_inv.
Solve(block_size, 1, xi);
2853 int it,
double norm,
const Vector &r,
bool final)
2857 double bc_norm_squared = 0.0;
2863 bc_norm_squared += r_entry*r_entry;
2868 if (comm != MPI_COMM_NULL)
2870 double glob_bc_norm_squared = 0.0;
2871 MPI_Reduce(&bc_norm_squared, &glob_bc_norm_squared, 1, MPI_DOUBLE,
2873 bc_norm_squared = glob_bc_norm_squared;
2875 MPI_Comm_rank(comm, &rank);
2876 print = (rank == 0);
2879 if ((it == 0 ||
final || bc_norm_squared > 0.0) && print)
2881 mfem::out <<
" ResidualBCMonitor : b.c. residual norm = "
2882 << sqrt(bc_norm_squared) << endl;
2887 #ifdef MFEM_USE_SUITESPARSE
2912 umfpack_di_free_numeric(&
Numeric);
2916 umfpack_dl_free_numeric(&
Numeric);
2921 MFEM_VERIFY(
mat,
"not a SparseMatrix");
2930 MFEM_VERIFY(
width ==
height,
"not a square matrix");
2938 int status = umfpack_di_symbolic(
width,
width, Ap, Ai, Ax, &Symbolic,
2943 umfpack_di_report_status(
Control, status);
2945 " umfpack_di_symbolic() failed!");
2948 status = umfpack_di_numeric(Ap, Ai, Ax, Symbolic, &
Numeric,
2953 umfpack_di_report_status(
Control, status);
2955 " umfpack_di_numeric() failed!");
2957 umfpack_di_free_symbolic(&Symbolic);
2961 SuiteSparse_long status;
2965 AI =
new SuiteSparse_long[
width + 1];
2966 AJ =
new SuiteSparse_long[Ap[
width]];
2967 for (
int i = 0; i <=
width; i++)
2969 AI[i] = (SuiteSparse_long)(Ap[i]);
2971 for (
int i = 0; i < Ap[
width]; i++)
2973 AJ[i] = (SuiteSparse_long)(Ai[i]);
2976 status = umfpack_dl_symbolic(
width,
width,
AI,
AJ, Ax, &Symbolic,
2981 umfpack_dl_report_status(
Control, status);
2983 " umfpack_dl_symbolic() failed!");
2986 status = umfpack_dl_numeric(
AI,
AJ, Ax, Symbolic, &
Numeric,
2991 umfpack_dl_report_status(
Control, status);
2993 " umfpack_dl_numeric() failed!");
2995 umfpack_dl_free_symbolic(&Symbolic);
3002 mfem_error(
"UMFPackSolver::Mult : matrix is not set!"
3003 " Call SetOperator first!");
3011 umfpack_di_report_info(Control,
Info);
3014 umfpack_di_report_status(Control, status);
3015 mfem_error(
"UMFPackSolver::Mult : umfpack_di_solve() failed!");
3020 SuiteSparse_long status =
3023 umfpack_dl_report_info(Control,
Info);
3026 umfpack_dl_report_status(Control, status);
3027 mfem_error(
"UMFPackSolver::Mult : umfpack_dl_solve() failed!");
3035 mfem_error(
"UMFPackSolver::MultTranspose : matrix is not set!"
3036 " Call SetOperator first!");
3044 umfpack_di_report_info(Control,
Info);
3047 umfpack_di_report_status(Control, status);
3049 " umfpack_di_solve() failed!");
3054 SuiteSparse_long status =
3057 umfpack_dl_report_info(Control,
Info);
3060 umfpack_dl_report_status(Control, status);
3062 " umfpack_dl_solve() failed!");
3075 umfpack_di_free_numeric(&
Numeric);
3079 umfpack_dl_free_numeric(&
Numeric);
3094 "Had Numeric pointer in KLU, but not Symbolic");
3102 MFEM_VERIFY(
mat != NULL,
"not a SparseMatrix");
3110 MFEM_VERIFY(
width ==
height,
"not a square matrix");
3122 MFEM_VERIFY(
mat != NULL,
3123 "KLUSolver::Mult : matrix is not set! Call SetOperator first!");
3136 MFEM_VERIFY(
mat != NULL,
3137 "KLUSolver::Mult : matrix is not set! Call SetOperator first!");
3156 #endif // MFEM_USE_SUITESPARSE
3164 for (
int i = 0; i < block_dof.
NumRows(); ++i)
3169 block_solvers[i].SetOperator(sub_A);
3178 for (
int i = 0; i < block_dof.
NumRows(); ++i)
3183 block_solvers[i].Mult(sub_rhs, sub_sol);
3197 add(-1.0, z, 1.0, x, z);
3214 add(-1.0, z, 1.0, x, z);
3225 bool op_is_symmetric,
3227 :
Solver(op.NumRows()), aux_map_(aux_map, own_aux_map)
3229 aux_system_.
Reset(
RAP(&op, aux_map));
3232 aux_smoother_.
As<
HypreSmoother>()->SetOperatorSymmetry(op_is_symmetric);
3235 void AuxSpaceSmoother::Mult(
const Vector &x,
Vector &y,
bool transpose)
const
3240 Vector aux_sol(aux_rhs.Size());
3247 aux_smoother_->
Mult(aux_rhs, aux_sol);
3251 aux_map_->
Mult(aux_sol, y);
3253 #endif // MFEM_USE_MPI
const Array< int > * ess_dofs_list
Not owned.
void ApplyPlaneRotation(double &dx, double &dy, double &cs, double &sn)
PowerMethod helper class to estimate the largest eigenvalue of an operator using the iterative power ...
int Size() const
Return the logical size of the array.
int RowSize(const int i) const
Returns the number of elements in row i.
Conjugate gradient method.
OpType * As() const
Return the Operator pointer statically cast to a specified OpType. Similar to the method Get()...
virtual void MultTranspose(const Vector &b, Vector &x) const
Action of the transpose operator: y=A^t(x). The default behavior in class Operator is to generate an ...
double Info[UMFPACK_INFO]
void Mult(const Vector &b, Vector &x) const
Solve the system LUx = b, where L and U are the block ILU factors.
Chebyshev accelerated smoothing with given vector, no matrix necessary.
int GetNumIterations() const
void SetCol(int c, const double *col)
MPI_Comm GetComm() const
Return the associated MPI communicator, or MPI_COMM_NULL if no communicator is set.
HypreParMatrix * RAP(const HypreParMatrix *A, const HypreParMatrix *P)
Returns the matrix P^t * A * P.
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
virtual void Mult(const Vector &x, Vector &y) const
Operator application: y=A(x).
void SetSize(int s)
Resize the vector to size s.
void Monitor(int it, double norm, const Vector &r, const Vector &x, bool final=false) const
virtual void ProcessNewState(const Vector &x) const
This method can be overloaded in derived classes to perform computations that need knowledge of the n...
void MinimumDiscardedFillOrdering(SparseMatrix &C, Array< int > &p)
int * GetRowColumns(const int row)
Return a pointer to the column indices in a row.
virtual Operator & GetGradient(const Vector &x) const
Evaluate the gradient operator at the point x. The default behavior in class Operator is to generate ...
const T * HostRead() const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), false).
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
double Norml2() const
Returns the l2 norm of the vector.
OperatorJacobiSmoother(const double damping=1.0)
Default constructor: the diagonal will be computed by subsequent calls to SetOperator() using the Ope...
int * GetJ()
Return the array J.
class IterativeSolver * iter_solver
The last IterativeSolver to which this monitor was attached.
void GetSubVector(const Array< int > &dofs, Vector &elemvect) const
Extract entries listed in dofs to the output Vector elemvect.
void Mult(const Vector &x, Vector &y) const
Operator application: y=A(x).
Data type dense matrix using column-major storage.
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
int Size() const
Returns the size of the vector.
int * GetI()
Return the array I.
virtual void Mult(const Vector &x, Vector &y) const =0
Operator application: y=A(x).
virtual void MultTranspose(const Vector &b, Vector &x) const
Action of the transpose operator: y=A^t(x). The default behavior in class Operator is to generate an ...
void SetOperator(const Operator &op)
bool iterative_mode
If true, use the second argument of Mult() as an initial guess.
const Operator * GetC() const
Reordering
The reordering method used by the BlockILU factorization.
double * GetData() const
Return a pointer to the beginning of the Vector data.
void SortColumnIndices()
Sort the column indices corresponding to each row.
virtual void UseDevice(bool use_dev) const
Enable execution of Vector operations using the mfem::Device.
void GetSubMatrix(const Array< int > &rows, const Array< int > &cols, DenseMatrix &subm) const
void add(const Vector &v1, const Vector &v2, Vector &v)
double Norm(const Vector &x) const
virtual void MultTranspose(const Vector &x, Vector &y) const
Action of the transpose operator: y=A^t(x). The default behavior in class Operator is to generate an ...
double GetFinalNorm() const
double * GetData()
Return the element data, i.e. the array A.
int BiCGSTAB(const Operator &A, Vector &x, const Vector &b, Solver &M, int &max_iter, double &tol, double atol, int printit)
BiCGSTAB method. (tolerances are squared)
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
bool IsFinite(const double &val)
void Add(const DenseMatrix &A, const DenseMatrix &B, double alpha, DenseMatrix &C)
C = A + alpha*B.
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
General product operator: x -> (A*B)(x) = A(B(x)).
virtual void SetPreconditioner(Solver &pr)
This should be called before SetOperator.
void SetPrintLevel(int print_lvl)
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
double solve(double l, const Vector &xt, Vector &x, int &nclip) const
Solve QP at fixed lambda.
int GetNumConstraints() const
virtual MemoryClass GetMemoryClass() const
Return the MemoryClass preferred by the Operator.
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
void MINRES(const Operator &A, const Vector &b, Vector &x, int print_it, int max_it, double rtol, double atol)
MINRES method without preconditioner. (tolerances are squared)
virtual double * Write(bool on_dev=true)
Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), on_dev).
void Add(const double c, const DenseMatrix &A)
Adds the matrix A multiplied by the number c to the matrix.
Jacobi smoothing for a given bilinear form (no matrix necessary).
void mfem_error(const char *msg)
Function called when an error is encountered. Used by the macros MFEM_ABORT, MFEM_ASSERT, MFEM_VERIFY.
const double * HostReadData() const
void SetMaxIter(int max_it)
const int * HostReadJ() const
OperatorChebyshevSmoother(const Operator &oper_, const Vector &d, const Array< int > &ess_tdof_list, int order, double max_eig_estimate)
void SetLinearConstraint(const Vector &w_, double a_)
DirectSubBlockSolver(const SparseMatrix &A, const SparseMatrix &block_dof)
void SetKDim(int dim)
Set the number of iteration to perform between restarts, default is 50.
void CG(const Operator &A, const Vector &b, Vector &x, int print_iter, int max_num_iter, double RTOLERANCE, double ATOLERANCE)
Conjugate gradient method. (tolerances are squared)
const T * Read(bool on_dev=true) const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), on_dev).
void print_iteration(int it, double r, double l) const
void Setup(const Vector &diag)
Parallel smoothers in hypre.
void PCG(const Operator &A, Solver &B, const Vector &b, Vector &x, int print_iter, int max_num_iter, double RTOLERANCE, double ATOLERANCE)
Preconditioned conjugate gradient method. (tolerances are squared)
virtual int GetTrueVSize() const
Return the number of vector true (conforming) dofs.
void SetSize(int i, int j, int k, MemoryType mt_=MemoryType::PRESERVE)
void GetDiag(Vector &diag) const
Get the local diagonal of the matrix.
void Solve(int m, int n, double *X) const
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
double Dot(const Vector &x, const Vector &y) const
void AddElementVector(const Array< int > &dofs, const Vector &elemvect)
Add elements of the elemvect Vector to the entries listed in dofs. Negative dof values cause the -dof...
void GetColumn(int c, Vector &col) const
virtual const double * HostRead() const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), false).
BlockILU(int block_size_, Reordering reordering_=Reordering::MINIMUM_DISCARDED_FILL, int k_fill_=0)
virtual void Mult(const Vector &b, Vector &x) const
Solve the nonlinear system with right-hand side b.
bool Finalized() const
Returns whether or not CSR format has been finalized.
void AdaptiveLinRtolPostSolve(const Vector &x, const Vector &b, const int it, const double fnorm) const
Method for the adaptive linear solver rtol invoked after the linear solve.
Stationary linear iteration: x <- x + B (b - A x)
void SetInequalityConstraint(const Vector &dl, const Vector &dh)
void SetEqualityConstraint(const Vector &c)
void Swap(Array< T > &, Array< T > &)
void SetAbsTol(double atol)
virtual void MultTranspose(const Vector &x, Vector &y) const
Action of the transpose operator: y=A^t(x). The default behavior in class Operator is to generate an ...
double p(const Vector &x, double t)
void SetRelTol(double rtol)
double Control[UMFPACK_CONTROL]
Abstract base class for iterative solver.
virtual void Mult(const Vector &b, Vector &x) const
Solve the nonlinear system with right-hand side b.
OutStream err(std::cerr)
Global stream used by the library for standard error output. Initially it uses the same std::streambu...
virtual void Mult(const Vector &x, Vector &y) const
Matrix vector multiplication.
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
int NumRows() const
Get the number of rows (size of output) of the Operator. Synonym with Height().
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
void subtract(const Vector &x, const Vector &y, Vector &z)
MemoryType
Memory types supported by MFEM.
void SetAdaptiveLinRtol(const int type=2, const double rtol0=0.5, const double rtol_max=0.9, const double alpha=0.5 *(1.0+sqrt(5.0)), const double gamma=1.0)
Enable adaptive linear solver relative tolerance algorithm.
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
int NumCols() const
Get the number of columns (size of input) of the Operator. Synonym with Width().
void Update(Vector &x, int k, DenseMatrix &h, Vector &s, Array< Vector * > &v)
void SetDataAndSize(double *d, int s)
Set the Vector data and size.
Vector & Set(const double a, const Vector &x)
(*this) = a * x
int height
Dimension of the output / number of rows in the matrix.
virtual void SetOptimizationProblem(const OptimizationProblem &prob)
double InnerProduct(HypreParVector *x, HypreParVector *y)
virtual double * ReadWrite(bool on_dev=true)
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), on_dev).
Vector & Add(const double a, const Vector &Va)
(*this) += a * Va
void GetDiag(Vector &d) const
Returns the Diagonal of A.
virtual double ComputeScalingFactor(const Vector &x, const Vector &b) const
This method can be overloaded in derived classes to implement line search algorithms.
OptimizationProblem(int insize, const Operator *C_, const Operator *D_)
In parallel, insize is the number of the local true dofs.
void SetSolutionBounds(const Vector &xl, const Vector &xh)
virtual void AssembleDiagonal(Vector &diag) const
Computes the diagonal entries into diag. Typically, this operation only makes sense for linear Operat...
AuxSpaceSmoother(const HypreParMatrix &op, HypreParMatrix *aux_map, bool op_is_symmetric=true, bool own_aux_map=false)
void Mult(const Vector &x, Vector &y) const
Operator application: y=A(x).
void SetOperator(const Operator &op)
Recompute the diagonal using the method AssembleDiagonal of the given new Operator, op.
void GeneratePlaneRotation(double &dx, double &dy, double &cs, double &sn)
MemoryType GetMemoryType(MemoryClass mc)
Return a suitable MemoryType for a given MemoryClass.
void AdaptiveLinRtolPreSolve(const Vector &x, const int it, const double fnorm) const
Method for the adaptive linear solver rtol invoked before the linear solve.
void MultTranspose(const Vector &x, Vector &y) const
Multiply a vector with the transposed matrix. y = At * x.
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
virtual void Mult(const Vector &xt, Vector &x) const
virtual void SetOperator(const Operator &op)=0
Set/update the solver for the given operator.
void MakeRef(T *, int)
Make this Array a reference to a pointer.
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
void AddMult_a(double a, const Vector &x, Vector &y) const
y += a * A.x
const int * HostReadI() const
void MonitorResidual(int it, double norm, const Vector &r, bool final) override
Monitor the residual vector r.
virtual void MonitorSolution(int it, double norm, const Vector &x, bool final)
Monitor the solution vector x.
virtual void SetPreconditioner(Solver &pr)
This should be called before SetOperator.
int aGMRES(const Operator &A, Vector &x, const Vector &b, const Operator &M, int &max_iter, int m_max, int m_min, int m_step, double cf, double &tol, double &atol, int printit)
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
const OptimizationProblem * problem
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
double EstimateLargestEigenvalue(Operator &opr, Vector &v0, int numSteps=10, double tolerance=1e-8, int seed=12345)
Returns an estimate of the largest eigenvalue of the operator opr using the iterative power method...
Wrapper for hypre's ParCSR matrix class.
void SetBounds(const Vector &lo_, const Vector &hi_)
void AddMult_a(double alpha, const DenseMatrix &b, const DenseMatrix &c, DenseMatrix &a)
Matrix matrix multiplication. A += alpha * B * C.
IterativeSolverMonitor * monitor
virtual void Mult(const Vector &x, Vector &y) const
Operator application: y=A(x).
virtual const double * Read(bool on_dev=true) const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), on_dev).
virtual void MonitorResidual(int it, double norm, const Vector &r, bool final)
Monitor the residual vector r.
virtual double * HostReadWrite()
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), false).
int width
Dimension of the input / number of columns in the matrix.
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
const Operator * C
Not owned, some can remain unused (NULL).
void Reset(OpType *A, bool own_A=true)
Reset the OperatorHandle to the given OpType pointer, A.
void SLI(const Operator &A, const Vector &b, Vector &x, int print_iter, int max_num_iter, double RTOLERANCE, double ATOLERANCE)
Stationary linear iteration. (tolerances are squared)
int GMRES(const Operator &A, Vector &x, const Vector &b, Solver &M, int &max_iter, int m, double &tol, double atol, int printit)
GMRES method. (tolerances are squared)
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
virtual void SetOperator(const Operator &op)
Factorize the given Operator op which must be a SparseMatrix.