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++)
567 double beta =
Norm(r);
580 cout <<
" Pass : " << setw(2) << 1
581 <<
" Iteration : " << setw(3) << 0
582 <<
" ||B r|| = " << beta <<
'\n';
589 if (v[0] == NULL) { v[0] =
new Vector(n); }
590 v[0]->Set(1.0/beta, r);
591 s = 0.0; s(0) = beta;
593 for (i = 0; i <
m && j <=
max_iter; i++, j++)
605 for (k = 0; k <= i; k++)
607 H(k,i) =
Dot(w, *v[k]);
608 w.
Add(-H(k,i), *v[k]);
612 if (v[i+1] == NULL) { v[i+1] =
new Vector(n); }
613 v[i+1]->Set(1.0/H(i+1,i), w);
615 for (k = 0; k < i; k++)
624 resid = fabs(s(i+1));
626 cout <<
" Pass : " << setw(2) << (j-1)/
m+1
627 <<
" Iteration : " << setw(3) << j
628 <<
" ||B r|| = " << resid <<
'\n';
635 for (i = 0; i <=
m; i++)
646 cout <<
"Restarting..." <<
'\n';
666 for (i = 0; i <=
m; i++)
677 for (i = 0; i <=
m; i++)
704 double beta =
Norm(r);
717 cout <<
" Pass : " << setw(2) << 1
718 <<
" Iteration : " << setw(3) << 0
719 <<
" || r || = " << beta << endl;
723 for (i= 0; i<=
m; i++)
732 if (v[0] == NULL) { v[0] =
new Vector(b.
Size()); }
734 v[0] ->
Add (1.0/beta, r);
735 s = 0.0; s(0) = beta;
740 if (z[i] == NULL) { z[i] =
new Vector(b.
Size()); }
746 for (k = 0; k <= i; k++)
748 H(k,i) =
Dot( r, *v[k]);
749 r.Add(-H(k,i), (*v[k]));
753 if (v[i+1] == NULL) { v[i+1] =
new Vector(b.
Size()); }
755 v[i+1] ->
Add (1.0/H(i+1,i), r);
757 for (k = 0; k < i; k++)
766 double resid = fabs(s(i+1));
768 cout <<
" Pass : " << setw(2) << j
769 <<
" Iteration : " << setw(3) << i+1
770 <<
" || r || = " << resid << endl;
778 for (i= 0; i<=
m; i++)
780 if (v[i]) {
delete v[i]; }
781 if (z[i]) {
delete z[i]; }
789 cout <<
"Restarting..." << endl;
802 for (i= 0; i<=
m; i++)
804 if (v[i]) {
delete v[i]; }
805 if (z[i]) {
delete z[i]; }
813 for (i = 0; i <=
m; i++)
815 if (v[i]) {
delete v[i]; }
816 if (z[i]) {
delete z[i]; }
825 int &max_iter,
int m,
double &tol,
double atol,
int printit)
842 int print_iter,
int max_num_iter,
int m,
double rtol,
double atol)
844 GMRES(A, x, b, B, max_num_iter, m, rtol, atol, print_iter);
866 double resid, tol_goal;
867 double rho_1, rho_2=1.0,
alpha=1.0, beta, omega=1.0;
883 cout <<
" Iteration : " << setw(3) << 0
884 <<
" ||r|| = " << resid <<
'\n';
888 if (resid <= tol_goal)
902 cout <<
" Iteration : " << setw(3) << i
903 <<
" ||r|| = " << resid <<
'\n';
915 beta = (rho_1/rho_2) * (
alpha/omega);
931 if (resid < tol_goal)
935 cout <<
" Iteration : " << setw(3) << i
936 <<
" ||s|| = " << resid <<
'\n';
943 cout <<
" Iteration : " << setw(3) << i
944 <<
" ||s|| = " << resid;
963 cout <<
" ||r|| = " << resid <<
'\n';
965 if (resid < tol_goal)
987 int &max_iter,
double &tol,
double atol,
int printit)
1003 int print_iter,
int max_num_iter,
double rtol,
double atol)
1005 BiCGSTAB(A, x, b, B, max_num_iter, rtol, atol, print_iter);
1031 double beta, eta, gamma0, gamma1, sigma0, sigma1;
1032 double alpha, delta, rho1, rho2, rho3, norm_goal;
1052 eta = beta = sqrt(
Dot(*z,
v1));
1053 gamma0 = gamma1 = 1.;
1054 sigma0 = sigma1 = 0.;
1059 cout <<
"MINRES: iteration " << setw(3) << 0 <<
": ||r||_B = "
1062 if (eta <= norm_goal)
1083 delta = gamma1*alpha - gamma0*sigma1*beta;
1085 rho2 = sigma1*alpha + gamma0*gamma1*beta;
1095 rho1 = hypot(delta, beta);
1099 w0.
Set(1./rho1, *z);
1103 add(1./rho1, *z, -rho2/rho1,
w1,
w0);
1107 add(-rho3/rho1,
w0, -rho2/rho1,
w1,
w0);
1108 w0.
Add(1./rho1, *z);
1112 gamma1 = delta/rho1;
1114 x.
Add(gamma1*eta,
w0);
1122 cout <<
"MINRES: iteration " << setw(3) << it <<
": ||r||_B = "
1123 << fabs(eta) <<
'\n';
1125 if (fabs(eta) <= norm_goal)
1146 cout <<
"MINRES: number of iterations: " << it <<
'\n';
1149 cout <<
"MINRES: iteration " << setw(3) << it <<
": ||r||_B = "
1150 << fabs(eta) <<
'\n';
1160 eta = sqrt(
Dot(*z,
v1));
1161 cout <<
"MINRES: iteration " << setw(3) << it <<
": ||r||_B = "
1162 << eta <<
" (re-computed)" <<
'\n';
1167 cerr <<
"MINRES: No convergence!" <<
'\n';
1172 int max_it,
double rtol,
double atol)
1184 int print_it,
int max_it,
double rtol,
double atol)
1202 MFEM_ASSERT(
height ==
width,
"square Operator is required.");
1210 MFEM_ASSERT(
oper != NULL,
"the Operator is not set (use SetOperator).");
1211 MFEM_ASSERT(
prec != NULL,
"the Solver is not set (use SetSolver).");
1214 double norm, norm_goal;
1234 for (it = 0;
true; it++)
1237 cout <<
"Newton iteration " << setw(2) << it
1238 <<
" : ||r|| = " << norm <<
'\n';
1240 if (norm <= norm_goal)
1273 int m_max,
int m_min,
int m_step,
double cf,
1274 double &tol,
double &atol,
int printit)
1281 Vector s(m+1), cs(m+1), sn(m+1);
1288 double normb = w.Norml2();
1298 double beta = r.
Norml2();
1300 resid = beta / normb;
1302 if (resid * resid <= tol)
1304 tol = resid * resid;
1310 cout <<
" Pass : " << setw(2) << 1
1311 <<
" Iteration : " << setw(3) << 0
1312 <<
" (r, r) = " << beta*beta <<
'\n';
1314 tol *= (normb*normb);
1315 tol = (atol > tol) ? atol : tol;
1319 for (i= 0; i<=m; i++)
1326 while (j <= max_iter)
1329 v[0] ->
Add (1.0/beta, r);
1330 s = 0.0; s(0) = beta;
1334 for (i = 0; i < m && j <= max_iter; i++)
1339 for (k = 0; k <= i; k++)
1341 H(k,i) = w * (*v[k]);
1342 w.
Add(-H(k,i), (*v[k]));
1345 H(i+1,i) = w.Norml2();
1347 v[i+1] ->
Add (1.0/H(i+1,i), w);
1349 for (k = 0; k < i; k++)
1358 resid = fabs(s(i+1));
1360 cout <<
" Pass : " << setw(2) << j
1361 <<
" Iteration : " << setw(3) << i+1
1362 <<
" (r, r) = " << resid*resid <<
'\n';
1364 if ( resid*resid < tol)
1367 tol = resid * resid;
1369 for (i= 0; i<=m; i++)
1379 cout <<
"Restarting..." <<
'\n';
1388 if ( resid*resid < tol)
1390 tol = resid * resid;
1392 for (i= 0; i<=m; i++)
1401 if (m - m_step >= m_min)
1414 tol = resid * resid;
1415 for (i= 0; i<=m; i++)
1437 mfem_error(
"SLBQPOptimizer::SetPreconditioner() : "
1438 "not meaningful for this solver");
1443 mfem_error(
"SLBQPOptimizer::SetOperator() : "
1444 "not meaningful for this solver");
1450 cout <<
"SLBQP iteration " << it <<
": residual = " << r
1451 <<
", lambda = " << l <<
'\n';
1473 const double smin = 0.1;
1480 cout <<
"SLBQP bracketing phase" <<
'\n';
1484 r =
solve(l,xt,x,nclip);
1498 llow = l; rlow = r; l = l + dl;
1501 r =
solve(l,xt,x,nclip);
1504 while ((r < 0) && (nclip <
max_iter))
1508 if (s < smin) { s = smin; }
1513 r =
solve(l,xt,x,nclip);
1521 lupp = l; rupp = r; l = l - dl;
1524 r =
solve(l,xt,x,nclip);
1527 while ((r > 0) && (nclip <
max_iter))
1531 if (s < smin) { s = smin; }
1536 r =
solve(l,xt,x,nclip);
1549 cout <<
"SLBQP secant phase" <<
'\n';
1552 s = 1.0 - rlow/rupp; dl = dl/s; l = lupp - dl;
1555 r =
solve(l,xt,x,nclip);
1558 while ( (fabs(r) > tol) && (nclip <
max_iter) )
1564 lupp = l; rupp = r; s = 1.0 - rlow/rupp;
1565 dl = (lupp - llow)/s; l = lupp - dl;
1570 if (s < smin) { s = smin; }
1572 lnew = 0.75*llow + 0.25*l;
1573 if (lnew < l-dl) { lnew = l-dl; }
1574 lupp = l; rupp = r; l = lnew;
1575 s = (lupp - llow)/(lupp - l);
1583 llow = l; rlow = r; s = 1.0 - rlow/rupp;
1584 dl = (lupp - llow)/s; l = lupp - dl;
1589 if (s < smin) { s = smin; }
1591 lnew = 0.75*lupp + 0.25*l;
1592 if (lnew < l+dl) { lnew = l+dl; }
1593 llow = l; rlow = r; l = lnew;
1594 s = (lupp - llow)/(lupp - l);
1599 r =
solve(l,xt,x,nclip);
1608 cerr <<
"SLBQP not converged!" <<
'\n';
1618 cout <<
"SLBQP iterations = " << nclip <<
'\n';
1619 cout <<
"SLBQP lambda = " << l <<
'\n';
1620 cout <<
"SLBQP residual = " << r <<
'\n';
1624 #ifdef MFEM_USE_SUITESPARSE
1651 umfpack_di_free_numeric(&
Numeric);
1655 umfpack_dl_free_numeric(&
Numeric);
1662 MFEM_ABORT(
"not a SparseMatrix");
1672 MFEM_VERIFY(
width ==
height,
"not a square matrix");
1680 int status = umfpack_di_symbolic(
width,
width, Ap, Ai, Ax, &Symbolic,
1685 umfpack_di_report_status(
Control, status);
1687 " umfpack_di_symbolic() failed!");
1690 status = umfpack_di_numeric(Ap, Ai, Ax, Symbolic, &
Numeric,
1695 umfpack_di_report_status(
Control, status);
1697 " umfpack_di_numeric() failed!");
1699 umfpack_di_free_symbolic(&Symbolic);
1703 SuiteSparse_long status;
1707 AI =
new SuiteSparse_long[
width + 1];
1708 AJ =
new SuiteSparse_long[Ap[
width]];
1709 for (
int i = 0; i <=
width; i++)
1711 AI[i] = (SuiteSparse_long)(Ap[i]);
1713 for (
int i = 0; i < Ap[
width]; i++)
1715 AJ[i] = (SuiteSparse_long)(Ai[i]);
1718 status = umfpack_dl_symbolic(
width,
width,
AI,
AJ, Ax, &Symbolic,
1723 umfpack_dl_report_status(
Control, status);
1725 " umfpack_dl_symbolic() failed!");
1728 status = umfpack_dl_numeric(
AI,
AJ, Ax, Symbolic, &
Numeric,
1733 umfpack_dl_report_status(
Control, status);
1735 " umfpack_dl_numeric() failed!");
1737 umfpack_dl_free_symbolic(&Symbolic);
1744 mfem_error(
"UMFPackSolver::Mult : matrix is not set!"
1745 " Call SetOperator first!");
1752 umfpack_di_report_info(Control,
Info);
1755 umfpack_di_report_status(Control, status);
1756 mfem_error(
"UMFPackSolver::Mult : umfpack_di_solve() failed!");
1761 SuiteSparse_long status =
1764 umfpack_dl_report_info(Control,
Info);
1767 umfpack_dl_report_status(Control, status);
1768 mfem_error(
"UMFPackSolver::Mult : umfpack_dl_solve() failed!");
1776 mfem_error(
"UMFPackSolver::MultTranspose : matrix is not set!"
1777 " Call SetOperator first!");
1784 umfpack_di_report_info(Control,
Info);
1787 umfpack_di_report_status(Control, status);
1789 " umfpack_di_solve() failed!");
1794 SuiteSparse_long status =
1797 umfpack_dl_report_info(Control,
Info);
1800 umfpack_dl_report_status(Control, status);
1802 " umfpack_dl_solve() failed!");
1815 umfpack_di_free_numeric(&
Numeric);
1819 umfpack_dl_free_numeric(&
Numeric);
1834 "Had Numeric pointer in KLU, but not Symbolic");
1842 MFEM_VERIFY(
mat != NULL,
"not a SparseMatrix");
1850 MFEM_VERIFY(
width ==
height,
"not a square matrix");
1862 MFEM_VERIFY(
mat != NULL,
1863 "KLUSolver::Mult : matrix is not set! Call SetOperator first!");
1876 MFEM_VERIFY(
mat != NULL,
1877 "KLUSolver::Mult : matrix is not set! Call SetOperator first!");
1896 #endif // MFEM_USE_SUITESPARSE
void ApplyPlaneRotation(double &dx, double &dy, double &cs, double &sn)
Conjugate gradient method.
virtual void MultTranspose(const Vector &b, Vector &x) const
Action of the transpose operator.
double Info[UMFPACK_INFO]
int GetNumIterations() const
void SetSize(int s)
Resize the vector if the new size is different.
virtual Operator & GetGradient(const Vector &x) const
Evaluate the gradient operator at the point x.
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.
virtual void MultTranspose(const Vector &b, Vector &x) const
Action of the transpose operator.
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.
virtual void Mult(const Vector &x, Vector &y) const
Operator application.
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.
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.
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.
virtual void Mult(const Vector &x, Vector &y) const
Operator application.
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.
virtual void Mult(const Vector &b, Vector &x) const
Operator application.
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.
void subtract(const Vector &x, const Vector &y, Vector &z)
void mfem_error(const char *msg)
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)
Vector & Set(const double a, const Vector &x)
(*this) = a * x
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.
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.
virtual void Mult(const Vector &b, Vector &x) const
Operator application.
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)
Set/update the solver for the given operator.