55 if (dot_prod_type == 0)
61 double local_dot = (x * y);
64 MPI_Allreduce(&local_dot, &global_dot, 1, MPI_DOUBLE, MPI_SUM, comm);
76 if (dot_prod_type == 0)
83 MPI_Comm_rank(comm, &rank);
155 double r0, nom, nom0, nomold = 1, cf;
171 nom0 = nom =
Dot(
z,
r);
175 nom0 = nom =
Dot(
r,
r);
179 cout <<
" Iteration : " << setw(3) << 0 <<
" (B r, r) = "
218 cf = sqrt(nom/nomold);
220 cout <<
" Iteration : " << setw(3) << i <<
" (B r, r) = "
221 << nom <<
"\tConv. rate: " << cf <<
'\n';
227 cout <<
"Number of SLI iterations: " << i <<
'\n'
228 <<
"Conv. rate: " << cf <<
'\n';
230 cout <<
"(B r_0, r_0) = " << nom0 <<
'\n'
231 <<
"(B r_N, r_N) = " << nom <<
'\n'
232 <<
"Number of SLI iterations: " << i <<
'\n';
246 cerr <<
"SLI: No convergence!" <<
'\n';
247 cout <<
"(B r_0, r_0) = " << nom0 <<
'\n'
248 <<
"(B r_N, r_N) = " << nom <<
'\n'
249 <<
"Number of SLI iterations: " <<
final_iter <<
'\n';
253 cout <<
"Average reduction factor = "
260 int print_iter,
int max_num_iter,
261 double RTOLERANCE,
double ATOLERANCE)
273 int print_iter,
int max_num_iter,
274 double RTOLERANCE,
double ATOLERANCE)
297 double r0, den, nom, nom0, betanom,
alpha, beta;
319 nom0 = nom =
Dot(
d,
r);
320 MFEM_ASSERT(
IsFinite(nom),
"nom = " << nom);
324 cout <<
" Iteration : " << setw(3) << 0 <<
" (B r, r) = "
339 MFEM_ASSERT(
IsFinite(den),
"den = " << den);
343 cout <<
"Negative denominator in step 0 of PCG: " << den <<
'\n';
372 MFEM_ASSERT(
IsFinite(betanom),
"betanom = " << betanom);
376 cout <<
" Iteration : " << setw(3) << i <<
" (B r, r) = "
384 cout <<
"Number of PCG iterations: " << i <<
'\n';
388 cout <<
" Iteration : " << setw(3) << i <<
" (B r, r) = "
412 MFEM_ASSERT(
IsFinite(den),
"den = " << den);
416 cout <<
"PCG: The operator is not positive definite. (Ad, d) = "
427 cout <<
" Iteration : " << setw(3) << 0 <<
" (B r, r) = "
430 cout <<
" Iteration : " << setw(3) <<
final_iter <<
" (B r, r) = "
433 cout <<
"PCG: No convergence!" <<
'\n';
437 cout <<
"Average reduction factor = "
438 << pow (betanom/nom0, 0.5/
final_iter) <<
'\n';
444 int print_iter,
int max_num_iter,
445 double RTOLERANCE,
double ATOLERANCE)
457 int print_iter,
int max_num_iter,
458 double RTOLERANCE,
double ATOLERANCE)
472 double &cs,
double &sn)
479 else if (fabs(dy) > fabs(dx))
481 double temp = dx / dy;
482 sn = 1.0 / sqrt( 1.0 + temp*temp );
487 double temp = dy / dx;
488 cs = 1.0 / sqrt( 1.0 + temp*temp );
495 double temp = cs * dx + sn * dy;
496 dy = -sn * dx + cs * dy;
506 for (
int i = k; i >= 0; i--)
509 for (
int j = i - 1; j >= 0; j--)
511 y(j) -= h(j,i) * y(i);
515 for (
int j = 0; j <= k; j++)
568 double beta =
Norm(r);
569 MFEM_ASSERT(
IsFinite(beta),
"beta = " << beta);
583 cout <<
" Pass : " << setw(2) << 1
584 <<
" Iteration : " << setw(3) << 0
585 <<
" ||B r|| = " << beta << (
print_level == 3 ?
" ...\n" :
"\n");
592 if (v[0] == NULL) { v[0] =
new Vector(n); }
593 v[0]->Set(1.0/beta, r);
594 s = 0.0; s(0) = beta;
596 for (i = 0; i <
m && j <=
max_iter; i++, j++)
608 for (k = 0; k <= i; k++)
610 H(k,i) =
Dot(w, *v[k]);
611 w.
Add(-H(k,i), *v[k]);
615 MFEM_ASSERT(
IsFinite(H(i+1,i)),
"Norm(w) = " << H(i+1,i));
616 if (v[i+1] == NULL) { v[i+1] =
new Vector(n); }
617 v[i+1]->Set(1.0/H(i+1,i), w);
619 for (k = 0; k < i; k++)
628 resid = fabs(s(i+1));
629 MFEM_ASSERT(
IsFinite(resid),
"resid = " << resid);
642 cout <<
" Pass : " << setw(2) << (j-1)/
m+1
643 <<
" Iteration : " << setw(3) << j
644 <<
" ||B r|| = " << resid <<
'\n';
650 cout <<
"Restarting..." <<
'\n';
666 MFEM_ASSERT(
IsFinite(beta),
"beta = " << beta);
683 cout <<
" Pass : " << setw(2) << (
final_iter-1)/
m+1
689 cout <<
"GMRES: Number of iterations: " <<
final_iter <<
'\n';
693 cout <<
"GMRES: No convergence!\n";
695 for (i = 0; i < v.
Size(); i++)
720 double beta =
Norm(r);
721 MFEM_ASSERT(
IsFinite(beta),
"beta = " << beta);
734 cout <<
" Pass : " << setw(2) << 1
735 <<
" Iteration : " << setw(3) << 0
736 <<
" || r || = " << beta << endl;
740 for (i= 0; i<=
m; i++)
749 if (v[0] == NULL) { v[0] =
new Vector(b.
Size()); }
751 v[0] ->
Add (1.0/beta, r);
752 s = 0.0; s(0) = beta;
757 if (z[i] == NULL) { z[i] =
new Vector(b.
Size()); }
763 for (k = 0; k <= i; k++)
765 H(k,i) =
Dot( r, *v[k]);
766 r.Add(-H(k,i), (*v[k]));
770 if (v[i+1] == NULL) { v[i+1] =
new Vector(b.
Size()); }
772 v[i+1] ->
Add (1.0/H(i+1,i), r);
774 for (k = 0; k < i; k++)
783 double resid = fabs(s(i+1));
784 MFEM_ASSERT(
IsFinite(resid),
"resid = " << resid);
786 cout <<
" Pass : " << setw(2) << j
787 <<
" Iteration : " << setw(3) << i+1
788 <<
" || r || = " << resid << endl;
796 for (i= 0; i<=
m; i++)
798 if (v[i]) {
delete v[i]; }
799 if (z[i]) {
delete z[i]; }
807 cout <<
"Restarting..." << endl;
815 MFEM_ASSERT(
IsFinite(beta),
"beta = " << beta);
821 for (i= 0; i<=
m; i++)
823 if (v[i]) {
delete v[i]; }
824 if (z[i]) {
delete z[i]; }
832 for (i = 0; i <=
m; i++)
834 if (v[i]) {
delete v[i]; }
835 if (z[i]) {
delete z[i]; }
844 int &max_iter,
int m,
double &tol,
double atol,
int printit)
861 int print_iter,
int max_num_iter,
int m,
double rtol,
double atol)
863 GMRES(A, x, b, B, max_num_iter, m, rtol, atol, print_iter);
885 double resid, tol_goal;
886 double rho_1, rho_2=1.0,
alpha=1.0, beta, omega=1.0;
901 MFEM_ASSERT(
IsFinite(resid),
"resid = " << resid);
903 cout <<
" Iteration : " << setw(3) << 0
904 <<
" ||r|| = " << resid <<
'\n';
908 if (resid <= tol_goal)
922 cout <<
" Iteration : " << setw(3) << i
923 <<
" ||r|| = " << resid <<
'\n';
935 beta = (rho_1/rho_2) * (
alpha/omega);
951 MFEM_ASSERT(
IsFinite(resid),
"resid = " << resid);
952 if (resid < tol_goal)
956 cout <<
" Iteration : " << setw(3) << i
957 <<
" ||s|| = " << resid <<
'\n';
964 cout <<
" Iteration : " << setw(3) << i
965 <<
" ||s|| = " << resid;
982 MFEM_ASSERT(
IsFinite(resid),
"resid = " << resid);
985 cout <<
" ||r|| = " << resid <<
'\n';
987 if (resid < tol_goal)
1009 int &max_iter,
double &tol,
double atol,
int printit)
1018 bicgstab.
Mult(b, x);
1025 int print_iter,
int max_num_iter,
double rtol,
double atol)
1027 BiCGSTAB(A, x, b, B, max_num_iter, rtol, atol, print_iter);
1053 double beta, eta, gamma0, gamma1, sigma0, sigma1;
1054 double alpha, delta, rho1, rho2, rho3, norm_goal;
1074 eta = beta = sqrt(
Dot(*z,
v1));
1075 MFEM_ASSERT(
IsFinite(eta),
"eta = " << eta);
1076 gamma0 = gamma1 = 1.;
1077 sigma0 = sigma1 = 0.;
1081 if (eta <= norm_goal)
1089 cout <<
"MINRES: iteration " << setw(3) << 0 <<
": ||r||_B = "
1102 MFEM_ASSERT(
IsFinite(alpha),
"alpha = " << alpha);
1109 delta = gamma1*alpha - gamma0*sigma1*beta;
1111 rho2 = sigma1*alpha + gamma0*gamma1*beta;
1121 MFEM_ASSERT(
IsFinite(beta),
"beta = " << beta);
1122 rho1 = hypot(delta, beta);
1126 w0.
Set(1./rho1, *z);
1130 add(1./rho1, *z, -rho2/rho1,
w1,
w0);
1134 add(-rho3/rho1,
w0, -rho2/rho1,
w1,
w0);
1135 w0.
Add(1./rho1, *z);
1139 gamma1 = delta/rho1;
1141 x.
Add(gamma1*eta,
w0);
1147 MFEM_ASSERT(
IsFinite(eta),
"eta = " << eta);
1149 if (fabs(eta) <= norm_goal)
1156 cout <<
"MINRES: iteration " << setw(3) << it <<
": ||r||_B = "
1157 << fabs(eta) <<
'\n';
1176 cout <<
"MINRES: iteration " << setw(3) <<
final_iter <<
": ||r||_B = "
1181 cout <<
"MINRES: number of iterations: " <<
final_iter <<
'\n';
1192 eta = sqrt(
Dot(*z,
v1));
1193 cout <<
"MINRES: iteration " << setw(3) << it <<
": ||r||_B = "
1194 << eta <<
" (re-computed)" <<
'\n';
1199 cout <<
"MINRES: No convergence!\n";
1204 int max_it,
double rtol,
double atol)
1216 int print_it,
int max_it,
double rtol,
double atol)
1234 MFEM_ASSERT(
height ==
width,
"square Operator is required.");
1242 MFEM_ASSERT(
oper != NULL,
"the Operator is not set (use SetOperator).");
1243 MFEM_ASSERT(
prec != NULL,
"the Solver is not set (use SetSolver).");
1246 double norm, norm_goal;
1266 for (it = 0;
true; it++)
1268 MFEM_ASSERT(
IsFinite(norm),
"norm = " << norm);
1270 cout <<
"Newton iteration " << setw(2) << it
1271 <<
" : ||r|| = " << norm <<
'\n';
1273 if (norm <= norm_goal)
1306 int m_max,
int m_min,
int m_step,
double cf,
1307 double &tol,
double &atol,
int printit)
1314 Vector s(m+1), cs(m+1), sn(m+1);
1321 double normb = w.Norml2();
1331 double beta = r.
Norml2();
1333 resid = beta / normb;
1335 if (resid * resid <= tol)
1337 tol = resid * resid;
1343 cout <<
" Pass : " << setw(2) << 1
1344 <<
" Iteration : " << setw(3) << 0
1345 <<
" (r, r) = " << beta*beta <<
'\n';
1347 tol *= (normb*normb);
1348 tol = (atol > tol) ? atol : tol;
1352 for (i= 0; i<=m; i++)
1359 while (j <= max_iter)
1362 v[0] ->
Add (1.0/beta, r);
1363 s = 0.0; s(0) = beta;
1367 for (i = 0; i < m && j <= max_iter; i++)
1372 for (k = 0; k <= i; k++)
1374 H(k,i) = w * (*v[k]);
1375 w.
Add(-H(k,i), (*v[k]));
1378 H(i+1,i) = w.Norml2();
1380 v[i+1] ->
Add (1.0/H(i+1,i), w);
1382 for (k = 0; k < i; k++)
1391 resid = fabs(s(i+1));
1393 cout <<
" Pass : " << setw(2) << j
1394 <<
" Iteration : " << setw(3) << i+1
1395 <<
" (r, r) = " << resid*resid <<
'\n';
1397 if ( resid*resid < tol)
1400 tol = resid * resid;
1402 for (i= 0; i<=m; i++)
1412 cout <<
"Restarting..." <<
'\n';
1421 if ( resid*resid < tol)
1423 tol = resid * resid;
1425 for (i= 0; i<=m; i++)
1434 if (m - m_step >= m_min)
1447 tol = resid * resid;
1448 for (i= 0; i<=m; i++)
1470 mfem_error(
"SLBQPOptimizer::SetPreconditioner() : "
1471 "not meaningful for this solver");
1476 mfem_error(
"SLBQPOptimizer::SetOperator() : "
1477 "not meaningful for this solver");
1483 cout <<
"SLBQP iteration " << it <<
": residual = " << r
1484 <<
", lambda = " << l <<
'\n';
1506 const double smin = 0.1;
1513 cout <<
"SLBQP bracketing phase" <<
'\n';
1517 r =
solve(l,xt,x,nclip);
1531 llow = l; rlow = r; l = l + dl;
1534 r =
solve(l,xt,x,nclip);
1537 while ((r < 0) && (nclip <
max_iter))
1541 if (s < smin) { s = smin; }
1546 r =
solve(l,xt,x,nclip);
1554 lupp = l; rupp = r; l = l - dl;
1557 r =
solve(l,xt,x,nclip);
1560 while ((r > 0) && (nclip <
max_iter))
1564 if (s < smin) { s = smin; }
1569 r =
solve(l,xt,x,nclip);
1582 cout <<
"SLBQP secant phase" <<
'\n';
1585 s = 1.0 - rlow/rupp; dl = dl/s; l = lupp - dl;
1588 r =
solve(l,xt,x,nclip);
1591 while ( (fabs(r) > tol) && (nclip <
max_iter) )
1597 lupp = l; rupp = r; s = 1.0 - rlow/rupp;
1598 dl = (lupp - llow)/s; l = lupp - dl;
1603 if (s < smin) { s = smin; }
1605 lnew = 0.75*llow + 0.25*l;
1606 if (lnew < l-dl) { lnew = l-dl; }
1607 lupp = l; rupp = r; l = lnew;
1608 s = (lupp - llow)/(lupp - l);
1616 llow = l; rlow = r; s = 1.0 - rlow/rupp;
1617 dl = (lupp - llow)/s; l = lupp - dl;
1622 if (s < smin) { s = smin; }
1624 lnew = 0.75*lupp + 0.25*l;
1625 if (lnew < l+dl) { lnew = l+dl; }
1626 llow = l; rlow = r; l = lnew;
1627 s = (lupp - llow)/(lupp - l);
1632 r =
solve(l,xt,x,nclip);
1641 cerr <<
"SLBQP not converged!" <<
'\n';
1651 cout <<
"SLBQP iterations = " << nclip <<
'\n';
1652 cout <<
"SLBQP lambda = " << l <<
'\n';
1653 cout <<
"SLBQP residual = " << r <<
'\n';
1657 #ifdef MFEM_USE_SUITESPARSE
1684 umfpack_di_free_numeric(&
Numeric);
1688 umfpack_dl_free_numeric(&
Numeric);
1695 MFEM_ABORT(
"not a SparseMatrix");
1705 MFEM_VERIFY(
width ==
height,
"not a square matrix");
1713 int status = umfpack_di_symbolic(
width,
width, Ap, Ai, Ax, &Symbolic,
1718 umfpack_di_report_status(
Control, status);
1720 " umfpack_di_symbolic() failed!");
1723 status = umfpack_di_numeric(Ap, Ai, Ax, Symbolic, &
Numeric,
1728 umfpack_di_report_status(
Control, status);
1730 " umfpack_di_numeric() failed!");
1732 umfpack_di_free_symbolic(&Symbolic);
1736 SuiteSparse_long status;
1740 AI =
new SuiteSparse_long[
width + 1];
1741 AJ =
new SuiteSparse_long[Ap[
width]];
1742 for (
int i = 0; i <=
width; i++)
1744 AI[i] = (SuiteSparse_long)(Ap[i]);
1746 for (
int i = 0; i < Ap[
width]; i++)
1748 AJ[i] = (SuiteSparse_long)(Ai[i]);
1751 status = umfpack_dl_symbolic(
width,
width,
AI,
AJ, Ax, &Symbolic,
1756 umfpack_dl_report_status(
Control, status);
1758 " umfpack_dl_symbolic() failed!");
1761 status = umfpack_dl_numeric(
AI,
AJ, Ax, Symbolic, &
Numeric,
1766 umfpack_dl_report_status(
Control, status);
1768 " umfpack_dl_numeric() failed!");
1770 umfpack_dl_free_symbolic(&Symbolic);
1777 mfem_error(
"UMFPackSolver::Mult : matrix is not set!"
1778 " Call SetOperator first!");
1785 umfpack_di_report_info(Control,
Info);
1788 umfpack_di_report_status(Control, status);
1789 mfem_error(
"UMFPackSolver::Mult : umfpack_di_solve() failed!");
1794 SuiteSparse_long status =
1797 umfpack_dl_report_info(Control,
Info);
1800 umfpack_dl_report_status(Control, status);
1801 mfem_error(
"UMFPackSolver::Mult : umfpack_dl_solve() failed!");
1809 mfem_error(
"UMFPackSolver::MultTranspose : matrix is not set!"
1810 " Call SetOperator first!");
1817 umfpack_di_report_info(Control,
Info);
1820 umfpack_di_report_status(Control, status);
1822 " umfpack_di_solve() failed!");
1827 SuiteSparse_long status =
1830 umfpack_dl_report_info(Control,
Info);
1833 umfpack_dl_report_status(Control, status);
1835 " umfpack_dl_solve() failed!");
1848 umfpack_di_free_numeric(&
Numeric);
1852 umfpack_dl_free_numeric(&
Numeric);
1867 "Had Numeric pointer in KLU, but not Symbolic");
1875 MFEM_VERIFY(
mat != NULL,
"not a SparseMatrix");
1883 MFEM_VERIFY(
width ==
height,
"not a square matrix");
1895 MFEM_VERIFY(
mat != NULL,
1896 "KLUSolver::Mult : matrix is not set! Call SetOperator first!");
1909 MFEM_VERIFY(
mat != NULL,
1910 "KLUSolver::Mult : matrix is not set! Call SetOperator first!");
1929 #endif // MFEM_USE_SUITESPARSE
void ApplyPlaneRotation(double &dx, double &dy, double &cs, double &sn)
int Size() const
Logical size of the array.
Conjugate gradient method.
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]
int GetNumIterations() const
void SetSize(int s)
Resize the vector to size s.
virtual Operator & GetGradient(const Vector &x) const
Evaluate the gradient operator at the point x. The default behavior in class Operator is to generate ...
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.
Data type dense matrix using column-major storage.
int Size() const
Returns the size of the vector.
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 ...
bool iterative_mode
If true, use the second argument of Mult() as an initial guess.
virtual void Mult(const Vector &x, Vector &y) const
Operator application: y=A(x).
virtual void Mult(const Vector &x, Vector &y) const
Operator application: y=A(x).
void SortColumnIndices()
Sort the column indices corresponding to each row.
void add(const Vector &v1, const Vector &v2, Vector &v)
double Norm(const Vector &x) const
double GetFinalNorm() const
virtual void Mult(const Vector &x, Vector &y) const
Operator application: y=A(x).
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)
bool IsFinite(const double &val)
virtual void Mult(const Vector &x, Vector &y) const
Operator application: y=A(x).
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 &x, Vector &y) const
Operator application: y=A(x).
void SetLinearConstraint(const Vector &_w, double _a)
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 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)
void Add(const double c, const DenseMatrix &A)
Adds the matrix A multiplied by the number c to the matrix.
void SetMaxIter(int max_it)
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)
void print_iteration(int it, double r, double l) const
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 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
double * GetData() const
Return element data, i.e. array A.
virtual void Mult(const Vector &b, Vector &x) const
Solve the nonlinear system with right-hand side b.
int * GetI() const
Return the array I.
Stationary linear iteration: x <- x + B (b - A x)
void Swap(Array< T > &, Array< T > &)
void SetAbsTol(double atol)
void SetRelTol(double rtol)
double Control[UMFPACK_CONTROL]
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
void subtract(const Vector &x, const Vector &y, Vector &z)
void mfem_error(const char *msg)
void SetSize(int nsize)
Change logical size of the array, keep existing entries.
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
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.
void SetBounds(const Vector &_lo, const Vector &_hi)
Vector & Add(const double a, const Vector &Va)
(*this) += a * Va
void GeneratePlaneRotation(double &dx, double &dy, double &cs, double &sn)
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
Operator application: y=A(x).
virtual void SetOperator(const Operator &op)=0
Set/update the solver for the given operator.
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
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)
virtual void SetPreconditioner(Solver &pr)
These are not currently meaningful for this solver and will error out.
int * GetJ() const
Return the array J.
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.
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.