13 #include "../general/annotation.hpp" 14 #include "../general/forall.hpp" 15 #include "../general/globals.hpp" 16 #include "../fem/bilinearform.hpp" 53 #endif // MFEM_USE_MPI 60 if (dot_prod_type == 0)
74 int print_level_ = print_lvl;
77 if (dot_prod_type != 0)
80 MPI_Comm_rank(comm, &rank);
99 if (dot_prod_type != 0)
102 MPI_Comm_rank(comm, &rank);
105 derived_print_level = -1;
119 if (comm != MPI_COMM_NULL)
121 MPI_Comm_rank(comm, &rank);
125 switch (print_level_)
142 MFEM_WARNING(
"Unknown print level " << print_level_ <<
143 ". Defaulting to level 0.");
159 else if (print_options_.
summary)
191 const Vector& x,
bool final)
const 202 ess_tdof_list(nullptr),
211 Solver(
a.FESpace()->GetTrueVSize()),
214 ess_tdof_list(&ess_tdofs),
219 a.AssembleDiagonal(diag);
233 ess_tdof_list(&ess_tdofs),
266 MFEM_ASSERT(
height ==
width,
"not a square matrix!");
268 ess_tdof_list =
nullptr;
280 const double delta = damping;
281 auto D = diag.
Read();
282 auto DI = dinv.
Write();
283 const bool use_abs_diag_ = use_abs_diag;
288 MFEM_ABORT_KERNEL(
"Zero diagonal entry in OperatorJacobiSmoother");
290 if (!use_abs_diag_) { DI[i] =
delta / D[i]; }
291 else { DI[i] =
delta / std::abs(D[i]); }
293 if (ess_tdof_list && ess_tdof_list->
Size() > 0)
295 auto I = ess_tdof_list->
Read();
296 MFEM_FORALL(i, ess_tdof_list->
Size(), DI[I[i]] =
delta; );
304 MFEM_ASSERT(x.
Size() ==
Width(),
"invalid input vector");
305 MFEM_ASSERT(y.
Size() ==
Height(),
"invalid output vector");
309 MFEM_VERIFY(oper,
"iterative_mode == true requires the forward operator");
310 oper->
Mult(y, residual);
319 auto DI = dinv.
Read();
320 auto R = residual.
Read();
324 Y[i] += DI[i] * R[i];
331 int order_,
double max_eig_estimate_)
335 max_eig_estimate(max_eig_estimate_),
340 ess_tdof_list(ess_tdofs),
342 oper(&oper_) {
Setup(); }
348 int order_, MPI_Comm comm,
int power_iterations,
double power_tolerance)
353 int order_,
int power_iterations,
double power_tolerance)
361 ess_tdof_list(ess_tdofs),
375 power_iterations, power_tolerance);
383 int order_,
double max_eig_estimate_)
390 int order_, MPI_Comm comm,
int power_iterations,
double power_tolerance)
392 power_iterations, power_tolerance) { }
397 int order_,
int power_iterations,
double power_tolerance)
406 auto D = diag.
Read();
407 auto X = dinv.
Write();
408 MFEM_FORALL(i, N, X[i] = 1.0 / D[i]; );
409 auto I = ess_tdof_list.
Read();
410 MFEM_FORALL(i, ess_tdof_list.
Size(), X[I[i]] = 1.0; );
415 double upper_bound = 1.2 * max_eig_estimate;
416 double lower_bound = 0.3 * max_eig_estimate;
417 double theta = 0.5 * (upper_bound + lower_bound);
418 double delta = 0.5 * (upper_bound - lower_bound);
424 coeffs[0] = 1.0 / theta;
429 double tmp_0 = 1.0/(pow(
delta, 2) - 2*pow(theta, 2));
430 coeffs[0] = -4*theta*tmp_0;
436 double tmp_0 = 3*pow(
delta, 2);
437 double tmp_1 = pow(theta, 2);
438 double tmp_2 = 1.0/(-4*pow(theta, 3) + theta*tmp_0);
439 coeffs[0] = tmp_2*(tmp_0 - 12*tmp_1);
440 coeffs[1] = 12/(tmp_0 - 4*tmp_1);
441 coeffs[2] = -4*tmp_2;
446 double tmp_0 = pow(
delta, 2);
447 double tmp_1 = pow(theta, 2);
448 double tmp_2 = 8*tmp_0;
449 double tmp_3 = 1.0/(pow(
delta, 4) + 8*pow(theta, 4) - tmp_1*tmp_2);
450 coeffs[0] = tmp_3*(32*pow(theta, 3) - 16*theta*tmp_0);
451 coeffs[1] = tmp_3*(-48*tmp_1 + tmp_2);
452 coeffs[2] = 32*theta*tmp_3;
453 coeffs[3] = -8*tmp_3;
458 double tmp_0 = 5*pow(
delta, 4);
459 double tmp_1 = pow(theta, 4);
460 double tmp_2 = pow(theta, 2);
461 double tmp_3 = pow(
delta, 2);
462 double tmp_4 = 60*tmp_3;
463 double tmp_5 = 20*tmp_3;
464 double tmp_6 = 1.0/(16*pow(theta, 5) - pow(theta, 3)*tmp_5 + theta*tmp_0);
465 double tmp_7 = 160*tmp_2;
466 double tmp_8 = 1.0/(tmp_0 + 16*tmp_1 - tmp_2*tmp_5);
467 coeffs[0] = tmp_6*(tmp_0 + 80*tmp_1 - tmp_2*tmp_4);
468 coeffs[1] = tmp_8*(tmp_4 - tmp_7);
469 coeffs[2] = tmp_6*(-tmp_5 + tmp_7);
470 coeffs[3] = -80*tmp_8;
471 coeffs[4] = 16*tmp_6;
475 MFEM_ABORT(
"Chebyshev smoother not implemented for order = " << order);
483 MFEM_ABORT(
"Chebyshev smoother not implemented for iterative mode");
488 MFEM_ABORT(
"Chebyshev smoother requires operator");
497 for (
int k = 0; k < order; ++k)
502 oper->
Mult(residual, helperVector);
503 residual = helperVector;
508 auto Dinv = dinv.
Read();
510 MFEM_FORALL(i, n, R[i] *= Dinv[i]; );
514 auto C = coeffs.
Read();
515 MFEM_FORALL(i, n, Y[i] += C[k] * R[i]; );
564 double r0, nom, nom0, nomold = 1, cf;
580 nom0 = nom = sqrt(
Dot(
z,
z));
584 nom0 = nom = sqrt(
Dot(
r,
r));
590 mfem::out <<
" Iteration : " << setw(3) << right << 0 <<
" ||Br|| = " 623 nom = sqrt(
Dot(
z,
z));
627 nom = sqrt(
Dot(
r,
r));
648 mfem::out <<
" Iteration : " << setw(3) << right << (i-1)
649 <<
" ||Br|| = " << setw(11) << left << nom
650 <<
"\tConv. rate: " << cf <<
'\n';
658 const auto rf = pow (nom/nom0, 1.0/
final_iter);
660 <<
"Conv. rate: " << cf <<
'\n' 661 <<
"Average reduction factor: "<< rf <<
'\n';
665 mfem::out <<
"SLI: No convergence!" <<
'\n';
672 int print_iter,
int max_num_iter,
673 double RTOLERANCE,
double ATOLERANCE)
687 int print_iter,
int max_num_iter,
688 double RTOLERANCE,
double ATOLERANCE)
715 double r0, den, nom, nom0, betanom,
alpha, beta;
738 nom0 = nom =
Dot(
d,
r);
740 MFEM_ASSERT(
IsFinite(nom),
"nom = " << nom);
743 mfem::out <<
" Iteration : " << setw(3) << 0 <<
" (B r, r) = " 752 mfem::out <<
"PCG: The preconditioner is not positive definite. (Br, r) = " 772 MFEM_ASSERT(
IsFinite(den),
"den = " << den);
777 mfem::out <<
"PCG: The operator is not positive definite. (Ad, d) = " 807 MFEM_ASSERT(
IsFinite(betanom),
"betanom = " << betanom);
812 mfem::out <<
"PCG: The preconditioner is not positive definite. (Br, r) = " 822 mfem::out <<
" Iteration : " << setw(3) << i <<
" (B r, r) = " 823 << betanom << std::endl;
851 MFEM_ASSERT(
IsFinite(den),
"den = " << den);
856 mfem::out <<
"PCG: The operator is not positive definite. (Ad, d) = " 879 const auto arf = pow (betanom/nom0, 0.5/
final_iter);
880 mfem::out <<
"Average reduction factor = " << arf <<
'\n';
884 mfem::out <<
"PCG: No convergence!" <<
'\n';
893 int print_iter,
int max_num_iter,
894 double RTOLERANCE,
double ATOLERANCE)
908 int print_iter,
int max_num_iter,
909 double RTOLERANCE,
double ATOLERANCE)
925 double &cs,
double &sn)
932 else if (fabs(dy) > fabs(dx))
934 double temp = dx / dy;
935 sn = 1.0 / sqrt( 1.0 + temp*temp );
940 double temp = dy / dx;
941 cs = 1.0 / sqrt( 1.0 + temp*temp );
948 double temp = cs * dx + sn * dy;
949 dy = -sn * dx + cs * dy;
959 for (
int i = k; i >= 0; i--)
962 for (
int j = i - 1; j >= 0; j--)
964 y(j) -= h(j,i) * y(i);
968 for (
int j = 0; j <= k; j++)
1022 MFEM_ASSERT(
IsFinite(beta),
"beta = " << beta);
1037 <<
" Iteration : " << setw(3) << 0
1038 <<
" ||B r|| = " << beta
1048 if (v[0] == NULL) { v[0] =
new Vector(n); }
1049 v[0]->Set(1.0/beta, r);
1050 s = 0.0;
s(0) = beta;
1052 for (i = 0; i <
m && j <=
max_iter; i++, j++)
1064 for (k = 0; k <= i; k++)
1066 H(k,i) =
Dot(w, *v[k]);
1067 w.
Add(-H(k,i), *v[k]);
1071 MFEM_ASSERT(
IsFinite(H(i+1,i)),
"Norm(w) = " << H(i+1,i));
1072 if (v[i+1] == NULL) { v[i+1] =
new Vector(n); }
1073 v[i+1]->Set(1.0/H(i+1,i), w);
1075 for (k = 0; k < i; k++)
1084 resid = fabs(
s(i+1));
1085 MFEM_ASSERT(
IsFinite(resid),
"resid = " << resid);
1098 mfem::out <<
" Pass : " << setw(2) << (j-1)/
m+1
1099 <<
" Iteration : " << setw(3) << j
1100 <<
" ||B r|| = " << resid <<
'\n';
1124 MFEM_ASSERT(
IsFinite(beta),
"beta = " << beta);
1141 mfem::out <<
" Pass : " << setw(2) << (j-1)/
m+1
1143 <<
" ||B r|| = " << resid <<
'\n';
1151 mfem::out <<
"GMRES: No convergence!\n";
1156 for (i = 0; i < v.
Size(); i++)
1185 MFEM_ASSERT(
IsFinite(beta),
"beta = " << beta);
1200 <<
" Iteration : " << setw(3) << 0
1201 <<
" || r || = " << beta
1209 for (i= 0; i<=
m; i++)
1218 if (v[0] == NULL) { v[0] =
new Vector(
b.Size()); }
1220 v[0] ->
Add (1.0/beta, r);
1221 s = 0.0;
s(0) = beta;
1223 for (i = 0; i <
m && j <=
max_iter; i++, j++)
1226 if (z[i] == NULL) { z[i] =
new Vector(
b.Size()); }
1239 for (k = 0; k <= i; k++)
1241 H(k,i) =
Dot( r, *v[k]);
1242 r.Add(-H(k,i), (*v[k]));
1246 if (v[i+1] == NULL) { v[i+1] =
new Vector(
b.Size()); }
1248 v[i+1] ->
Add (1.0/H(i+1,i), r);
1250 for (k = 0; k < i; k++)
1259 resid = fabs(
s(i+1));
1260 MFEM_ASSERT(
IsFinite(resid),
"resid = " << resid);
1264 mfem::out <<
" Pass : " << setw(2) << (j-1)/
m+1
1265 <<
" Iteration : " << setw(3) << j
1266 <<
" || r || = " << resid << endl;
1282 for (i= 0; i<=
m; i++)
1284 if (v[i]) {
delete v[i]; }
1285 if (z[i]) {
delete z[i]; }
1301 MFEM_ASSERT(
IsFinite(beta),
"beta = " << beta);
1313 for (i = 0; i <=
m; i++)
1315 if (v[i]) {
delete v[i]; }
1316 if (z[i]) {
delete z[i]; }
1323 mfem::out <<
" Pass : " << setw(2) << (j-1)/
m+1
1324 <<
" Iteration : " << setw(3) << j-1
1325 <<
" || r || = " << resid << endl;
1329 mfem::out <<
"FGMRES: Number of iterations: " << j-1 <<
'\n';
1333 mfem::out <<
"FGMRES: No convergence!\n";
1339 int &max_iter,
int m,
double &tol,
double atol,
int printit)
1358 int print_iter,
int max_num_iter,
int m,
double rtol,
double atol)
1360 GMRES(A, x,
b, B, max_num_iter, m, rtol, atol, print_iter);
1382 double resid, tol_goal;
1383 double rho_1, rho_2=1.0,
alpha=1.0, beta,
omega=1.0;
1398 MFEM_ASSERT(
IsFinite(resid),
"resid = " << resid);
1401 mfem::out <<
" Iteration : " << setw(3) << 0
1409 if (resid <= tol_goal)
1424 mfem::out <<
" Iteration : " << setw(3) << i
1425 <<
" ||r|| = " << resid <<
'\n';
1439 mfem::out <<
"BiCGStab: No convergence!\n";
1465 MFEM_ASSERT(
IsFinite(resid),
"resid = " << resid);
1466 if (resid < tol_goal)
1471 mfem::out <<
" Iteration : " << setw(3) << i
1472 <<
" ||s|| = " << resid <<
'\n';
1485 mfem::out <<
" Iteration : " << setw(3) << i
1486 <<
" ||s|| = " << resid;
1505 MFEM_ASSERT(
IsFinite(resid),
"resid = " << resid);
1508 mfem::out <<
" ||r|| = " << resid <<
'\n';
1511 if (resid < tol_goal)
1518 mfem::out <<
" Iteration : " << setw(3) << i
1519 <<
" ||r|| = " << resid <<
'\n';
1534 mfem::out <<
" Iteration : " << setw(3) << i
1535 <<
" ||r|| = " << resid <<
'\n';
1543 mfem::out <<
"BiCGStab: No convergence!\n";
1556 <<
" ||r|| = " << resid <<
'\n';
1564 mfem::out <<
"BiCGStab: No convergence!\n";
1569 int &max_iter,
double &tol,
double atol,
int printit)
1578 bicgstab.
Mult(
b, x);
1585 int print_iter,
int max_num_iter,
double rtol,
double atol)
1587 BiCGSTAB(A, x,
b, B, max_num_iter, rtol, atol, print_iter);
1623 double beta, eta, gamma0, gamma1, sigma0, sigma1;
1624 double alpha,
delta, rho1, rho2, rho3, norm_goal;
1645 MFEM_ASSERT(
IsFinite(eta),
"eta = " << eta);
1646 gamma0 = gamma1 = 1.;
1647 sigma0 = sigma1 = 0.;
1651 if (eta <= norm_goal)
1659 mfem::out <<
"MINRES: iteration " << setw(3) << 0 <<
": ||r||_B = " 1682 rho2 = sigma1*
alpha + gamma0*gamma1*beta;
1692 MFEM_ASSERT(
IsFinite(beta),
"beta = " << beta);
1693 rho1 = hypot(
delta, beta);
1697 w0.
Set(1./rho1, *z);
1701 add(1./rho1, *z, -rho2/rho1,
w1,
w0);
1705 add(-rho3/rho1,
w0, -rho2/rho1,
w1,
w0);
1706 w0.
Add(1./rho1, *z);
1710 gamma1 =
delta/rho1;
1712 x.
Add(gamma1*eta,
w0);
1718 MFEM_ASSERT(
IsFinite(eta),
"eta = " << eta);
1720 if (fabs(eta) <= norm_goal)
1727 mfem::out <<
"MINRES: iteration " << setw(3) << it <<
": ||r||_B = " 1728 << fabs(eta) <<
'\n';
1730 Monitor(it, fabs(eta), *z, x);
1748 mfem::out <<
"MINRES: iteration " << setw(3) << it <<
": ||r||_B = " 1749 << fabs(eta) <<
'\n';
1774 mfem::out <<
"MINRES: No convergence!\n";
1779 int max_it,
double rtol,
double atol)
1793 int print_it,
int max_it,
double rtol,
double atol)
1811 MFEM_ASSERT(
height ==
width,
"square Operator is required.");
1819 MFEM_ASSERT(
oper != NULL,
"the Operator is not set (use SetOperator).");
1820 MFEM_ASSERT(
prec != NULL,
"the Solver is not set (use SetSolver).");
1823 double norm0, norm, norm_goal;
1824 const bool have_b = (
b.Size() ==
Height());
1842 mfem::out <<
"Newton iteration " << setw(2) << 0
1843 <<
" : ||r|| = " << norm <<
"...\n";
1850 for (it = 0;
true; it++)
1852 MFEM_ASSERT(
IsFinite(norm),
"norm = " << norm);
1855 mfem::out <<
"Newton iteration " << setw(2) << it
1856 <<
" : ||r|| = " << norm;
1859 mfem::out <<
", ||r||/||r_0|| = " << norm/norm0;
1865 if (norm <= norm_goal)
1898 add(x, -c_scale,
c, x);
1921 mfem::out <<
"Newton: No convergence!\n";
1927 const double rtol_max,
1928 const double alpha_,
1929 const double gamma_)
1934 this->
alpha = alpha_;
1935 this->
gamma = gamma_;
1940 const double fnorm)
const 1948 double sg_threshold = 0.1;
1968 MFEM_ABORT(
"Unknown adaptive linear solver rtol version");
1973 if (sg_eta > sg_threshold) { eta = std::max(eta, sg_eta); }
1977 iterative_solver->SetRelTol(eta);
1981 mfem::out <<
"Eisenstat-Walker rtol = " << eta <<
"\n";
1988 const double fnorm)
const 2007 MFEM_VERIFY(
oper != NULL,
"the Operator is not set (use SetOperator).");
2018 int last_saved_id = -1;
2021 double norm0, norm, norm_goal;
2022 const bool have_b = (
b.Size() ==
Height());
2033 if (have_b) {
r -=
b; }
2040 mfem::out <<
"LBFGS iteration " << setw(2) << 0
2041 <<
" : ||r|| = " << norm <<
"...\n";
2044 for (it = 0;
true; it++)
2046 MFEM_ASSERT(
IsFinite(norm),
"norm = " << norm);
2050 <<
" : ||r|| = " << norm;
2053 mfem::out <<
", ||r||/||r_0|| = " << norm/norm0;
2058 if (norm <= norm_goal)
2077 add(x, -c_scale,
c, x);
2089 sk =
c; sk *= -c_scale;
2093 last_saved_id = (last_saved_id ==
m-1) ? 0 : last_saved_id+1;
2098 for (
int i = last_saved_id; i > -1; i--)
2106 for (
int i =
m-1; i > last_saved_id; i--)
2117 for (
int i = last_saved_id+1; i <
m ; i++)
2123 for (
int i = 0; i < last_saved_id+1 ; i++)
2143 mfem::out <<
"LBFGS: No convergence!\n";
2149 int m_max,
int m_min,
int m_step,
double cf,
2150 double &tol,
double &atol,
int printit)
2157 Vector s(m+1), cs(m+1), sn(m+1);
2164 double normb = w.Norml2();
2174 double beta = r.
Norml2();
2176 resid = beta / normb;
2178 if (resid * resid <= tol)
2180 tol = resid * resid;
2188 <<
" Iteration : " << setw(3) << 0
2189 <<
" (r, r) = " << beta*beta <<
'\n';
2192 tol *= (normb*normb);
2193 tol = (atol > tol) ? atol : tol;
2197 for (i= 0; i<=m; i++)
2204 while (j <= max_iter)
2207 v[0] ->
Add (1.0/beta, r);
2208 s = 0.0;
s(0) = beta;
2212 for (i = 0; i < m && j <= max_iter; i++)
2217 for (k = 0; k <= i; k++)
2219 H(k,i) = w * (*v[k]);
2220 w.
Add(-H(k,i), (*v[k]));
2223 H(i+1,i) = w.Norml2();
2225 v[i+1] ->
Add (1.0/H(i+1,i), w);
2227 for (k = 0; k < i; k++)
2236 resid = fabs(
s(i+1));
2240 <<
" Iteration : " << setw(3) << i+1
2241 <<
" (r, r) = " << resid*resid <<
'\n';
2244 if ( resid*resid < tol)
2247 tol = resid * resid;
2249 for (i= 0; i<=m; i++)
2268 if ( resid*resid < tol)
2270 tol = resid * resid;
2272 for (i= 0; i<=m; i++)
2281 if (m - m_step >= m_min)
2294 tol = resid * resid;
2295 for (i= 0; i<=m; i++)
2305 : C(C_), D(D_), c_e(NULL), d_lo(NULL), d_hi(NULL), x_lo(NULL), x_hi(NULL),
2314 MFEM_ASSERT(
C,
"The C operator is unspecified -- can't set constraints.");
2315 MFEM_ASSERT(c.
Size() ==
C->
Height(),
"Wrong size of the constraint.");
2323 MFEM_ASSERT(
D,
"The D operator is unspecified -- can't set constraints.");
2325 "Wrong size of the constraint.");
2333 "Wrong size of the constraint.");
2350 MFEM_WARNING(
"Objective functional is ignored as SLBQP always minimizes" 2351 "the l2 norm of (x - x_target).");
2353 MFEM_ASSERT(
prob.GetC(),
"Linear constraint is not set.");
2354 MFEM_ASSERT(
prob.GetC()->Height() == 1,
"Solver expects scalar constraint.");
2375 mfem::out <<
"SLBQP iteration " << it <<
": residual = " << r
2376 <<
", lambda = " << l <<
'\n';
2399 const double smin = 0.1;
2406 mfem::out <<
"SLBQP bracketing phase" <<
'\n';
2424 llow = l; rlow = r; l = l + dl;
2427 r =
solve(l,xt,x,nclip);
2430 while ((r < 0) && (nclip <
max_iter))
2434 if (
s < smin) {
s = smin; }
2439 r =
solve(l,xt,x,nclip);
2447 lupp = l; rupp = r; l = l - dl;
2450 r =
solve(l,xt,x,nclip);
2453 while ((r > 0) && (nclip <
max_iter))
2457 if (
s < smin) {
s = smin; }
2462 r =
solve(l,xt,x,nclip);
2475 mfem::out <<
"SLBQP secant phase" <<
'\n';
2478 s = 1.0 - rlow/rupp; dl = dl/
s; l = lupp - dl;
2481 r =
solve(l,xt,x,nclip);
2484 while ( (fabs(r) > tol) && (nclip <
max_iter) )
2490 lupp = l; rupp = r;
s = 1.0 - rlow/rupp;
2491 dl = (lupp - llow)/
s; l = lupp - dl;
2496 if (
s < smin) {
s = smin; }
2498 lnew = 0.75*llow + 0.25*l;
2499 if (lnew < l-dl) { lnew = l-dl; }
2500 lupp = l; rupp = r; l = lnew;
2501 s = (lupp - llow)/(lupp - l);
2509 llow = l; rlow = r;
s = 1.0 - rlow/rupp;
2510 dl = (lupp - llow)/
s; l = lupp - dl;
2515 if (
s < smin) {
s = smin; }
2517 lnew = 0.75*lupp + 0.25*l;
2518 if (lnew < l+dl) { lnew = l+dl; }
2519 llow = l; rlow = r; l = lnew;
2520 s = (lupp - llow)/(lupp - l);
2525 r =
solve(l,xt,x,nclip);
2541 <<
" lambda = " << l <<
'\n' 2546 mfem::out <<
"SLBQP: No convergence!" <<
'\n';
2550 struct WeightMinHeap
2552 const std::vector<double> &w;
2553 std::vector<size_t> c;
2554 std::vector<int> loc;
2556 WeightMinHeap(
const std::vector<double> &w_) : w(w_)
2558 c.reserve(w.size());
2559 loc.resize(w.size());
2560 for (
size_t i=0; i<w.size(); ++i) { push(i); }
2563 size_t percolate_up(
size_t pos,
double val)
2565 for (; pos > 0 && w[c[(pos-1)/2]] > val; pos = (pos-1)/2)
2567 c[pos] = c[(pos-1)/2];
2568 loc[c[(pos-1)/2]] = pos;
2573 size_t percolate_down(
size_t pos,
double val)
2575 while (2*pos+1 < c.size())
2577 size_t left = 2*pos+1;
2578 size_t right = left+1;
2580 if (right < c.size() && w[c[right]] < w[c[left]]) { tgt = right; }
2581 else { tgt = left; }
2582 if (w[c[tgt]] < val)
2600 size_t pos = c.size()-1;
2601 pos = percolate_up(pos, val);
2609 size_t j = c.back();
2613 if (c.empty()) {
return i; }
2616 pos = percolate_down(pos, val);
2622 void update(
size_t i)
2624 size_t pos = loc[i];
2626 pos = percolate_up(pos, val);
2627 pos = percolate_down(pos, val);
2632 bool picked(
size_t i)
2647 for (
int i=0; i<n; ++i)
2649 for (
int j=I[i]; j<I[i+1]; ++j)
2651 V[j] = abs(V[j]/D[i]);
2655 std::vector<double> w(n, 0.0);
2656 for (
int k=0; k<n; ++k)
2659 for (
int ii=I[k]; ii<I[k+1]; ++ii)
2664 for (
int kk=I[i]; kk<I[i+1]; ++kk)
2672 for (
int jj=I[k]; jj<I[k+1]; ++jj)
2675 if (j == k) {
continue; }
2676 double C_kj = V[jj];
2677 bool ij_exists =
false;
2678 for (
int jj2=I[i]; jj2<I[i+1]; ++jj2)
2686 if (!ij_exists) { w[k] += pow(C_ik*C_kj,2); }
2692 WeightMinHeap w_heap(w);
2696 for (
int ii=0; ii<n; ++ii)
2698 int pi = w_heap.pop();
2701 for (
int kk=I[pi]; kk<I[pi+1]; ++kk)
2704 if (w_heap.picked(k)) {
continue; }
2708 for (
int ii2=I[k]; ii2<I[k+1]; ++ii2)
2711 if (w_heap.picked(i)) {
continue; }
2714 for (
int kk2=I[i]; kk2<I[i+1]; ++kk2)
2722 for (
int jj=I[k]; jj<I[k+1]; ++jj)
2725 if (j == k || w_heap.picked(j)) {
continue; }
2726 double C_kj = V[jj];
2727 bool ij_exists =
false;
2728 for (
int jj2=I[i]; jj2<I[i+1]; ++jj2)
2736 if (!ij_exists) { w[k] += pow(C_ik*C_kj,2); }
2749 block_size(block_size_),
2751 reordering(reordering_)
2758 :
BlockILU(block_size_, reordering_, k_fill_)
2780 MFEM_ABORT(
"BlockILU must be created with a SparseMatrix or HypreParMatrix");
2785 MFEM_ASSERT(A->
Finalized(),
"Matrix must be finalized.");
2786 CreateBlockPattern(*A);
2790 void BlockILU::CreateBlockPattern(
const SparseMatrix &A)
2792 MFEM_VERIFY(k_fill == 0,
"Only block ILU(0) is currently supported.");
2793 if (A.
Height() % block_size != 0)
2795 MFEM_ABORT(
"BlockILU: block size must evenly divide the matrix size");
2799 const int *I = A.
GetI();
2800 const int *J = A.
GetJ();
2801 const double *V = A.
GetData();
2803 int nblockrows = nrows / block_size;
2805 std::vector<std::set<int>> unique_block_cols(nblockrows);
2807 for (
int iblock = 0; iblock < nblockrows; ++iblock)
2809 for (
int bi = 0; bi < block_size; ++bi)
2811 int i = iblock * block_size + bi;
2812 for (
int k = I[i]; k < I[i + 1]; ++k)
2814 unique_block_cols[iblock].insert(J[k] / block_size);
2817 nnz += unique_block_cols[iblock].size();
2822 SparseMatrix C(nblockrows, nblockrows);
2823 for (
int iblock = 0; iblock < nblockrows; ++iblock)
2825 for (
int jblock : unique_block_cols[iblock])
2827 for (
int bi = 0; bi < block_size; ++bi)
2829 int i = iblock * block_size + bi;
2830 for (
int k = I[i]; k < I[i + 1]; ++k)
2833 if (j >= jblock * block_size && j < (jblock + 1) * block_size)
2835 C.Add(iblock, jblock, V[k]*V[k]);
2842 double *CV = C.GetData();
2843 for (
int i=0; i<C.NumNonZeroElems(); ++i)
2845 CV[i] = sqrt(CV[i]);
2854 MFEM_ABORT(
"BlockILU: unknown reordering")
2861 for (
int i=0; i<nblockrows; ++i)
2869 for (
int i=0; i<nblockrows; ++i)
2875 std::vector<std::vector<int>> unique_block_cols_perminv(nblockrows);
2876 for (
int i=0; i<nblockrows; ++i)
2878 std::vector<int> &cols = unique_block_cols_perminv[i];
2879 for (
int j : unique_block_cols[P[i]])
2881 cols.push_back(Pinv[j]);
2883 std::sort(cols.begin(), cols.end());
2890 AB.
SetSize(block_size, block_size, nnz);
2891 DB.
SetSize(block_size, block_size, nblockrows);
2894 ipiv.
SetSize(block_size*nblockrows);
2897 for (
int iblock = 0; iblock < nblockrows; ++iblock)
2899 int iblock_perm = P[iblock];
2900 for (
int jblock : unique_block_cols_perminv[iblock])
2902 int jblock_perm = P[jblock];
2903 if (iblock == jblock)
2905 ID[iblock] = counter;
2907 JB[counter] = jblock;
2908 for (
int bi = 0; bi < block_size; ++bi)
2910 int i = iblock_perm*block_size + bi;
2911 for (
int k = I[i]; k < I[i + 1]; ++k)
2914 if (j >= jblock_perm*block_size && j < (jblock_perm + 1)*block_size)
2916 int bj = j - jblock_perm*block_size;
2918 AB(bi, bj, counter) = val;
2920 if (iblock == jblock)
2922 DB(bi, bj, iblock) = val;
2929 IB[iblock + 1] = counter;
2933 void BlockILU::Factorize()
2935 int nblockrows =
Height()/block_size;
2938 for (
int i=0; i<nblockrows; ++i)
2940 LUFactors factorization(DB.
GetData(i), &ipiv[i*block_size]);
2941 factorization.Factor(block_size);
2947 DenseMatrix A_ik, A_ij, A_kj;
2949 for (
int i=1; i<nblockrows; ++i)
2952 for (
int kk=IB[i]; kk<IB[i+1]; ++kk)
2956 if (k == i) {
break; }
2959 MFEM_ABORT(
"Matrix must be sorted with nonzero diagonal");
2961 LUFactors A_kk_inv(DB.
GetData(k), &ipiv[k*block_size]);
2962 A_ik.UseExternalData(&AB(0,0,kk), block_size, block_size);
2964 A_kk_inv.RightSolve(block_size, block_size, A_ik.GetData());
2966 for (
int jj=kk+1; jj<IB[i+1]; ++jj)
2969 if (j <= k) {
continue; }
2970 A_ij.UseExternalData(&AB(0,0,jj), block_size, block_size);
2971 for (
int ll=IB[k]; ll<IB[k+1]; ++ll)
2976 A_kj.UseExternalData(&AB(0,0,ll), block_size, block_size);
2983 LUFactors factorization(DB.
GetData(i), &ipiv[i*block_size]);
2984 factorization.Factor(block_size);
2996 MFEM_ASSERT(
height > 0,
"BlockILU(0) preconditioner is not constructed");
2997 int nblockrows =
Height()/block_size;
3006 for (
int i=0; i<nblockrows; ++i)
3009 for (
int ib=0; ib<block_size; ++ib)
3011 yi[ib] =
b[ib + P[i]*block_size];
3013 for (
int k=IB[i]; k<ID[i]; ++k)
3023 for (
int i=nblockrows-1; i >= 0; --i)
3026 for (
int ib=0; ib<block_size; ++ib)
3028 xi[ib] = y[ib + i*block_size];
3030 for (
int k=ID[i]+1; k<IB[i+1]; ++k)
3038 LUFactors A_ii_inv(&DB(0,0,i), &ipiv[i*block_size]);
3046 int it,
double norm,
const Vector &r,
bool final)
3050 double bc_norm_squared = 0.0;
3056 bc_norm_squared += r_entry*r_entry;
3061 if (comm != MPI_COMM_NULL)
3063 double glob_bc_norm_squared = 0.0;
3064 MPI_Reduce(&bc_norm_squared, &glob_bc_norm_squared, 1, MPI_DOUBLE,
3066 bc_norm_squared = glob_bc_norm_squared;
3068 MPI_Comm_rank(comm, &rank);
3069 print = (rank == 0);
3072 if ((it == 0 ||
final || bc_norm_squared > 0.0) && print)
3074 mfem::out <<
" ResidualBCMonitor : b.c. residual norm = " 3075 << sqrt(bc_norm_squared) << endl;
3080 #ifdef MFEM_USE_SUITESPARSE 3105 umfpack_di_free_numeric(&
Numeric);
3109 umfpack_dl_free_numeric(&
Numeric);
3114 MFEM_VERIFY(
mat,
"not a SparseMatrix");
3123 MFEM_VERIFY(
width ==
height,
"not a square matrix");
3136 umfpack_di_report_status(
Control, status);
3138 " umfpack_di_symbolic() failed!");
3146 umfpack_di_report_status(
Control, status);
3148 " umfpack_di_numeric() failed!");
3150 umfpack_di_free_symbolic(&
Symbolic);
3154 SuiteSparse_long status;
3158 AI =
new SuiteSparse_long[
width + 1];
3159 AJ =
new SuiteSparse_long[Ap[
width]];
3160 for (
int i = 0; i <=
width; i++)
3162 AI[i] = (SuiteSparse_long)(Ap[i]);
3164 for (
int i = 0; i < Ap[
width]; i++)
3166 AJ[i] = (SuiteSparse_long)(Ai[i]);
3174 umfpack_dl_report_status(
Control, status);
3176 " umfpack_dl_symbolic() failed!");
3184 umfpack_dl_report_status(
Control, status);
3186 " umfpack_dl_numeric() failed!");
3188 umfpack_dl_free_symbolic(&
Symbolic);
3195 mfem_error(
"UMFPackSolver::Mult : matrix is not set!" 3196 " Call SetOperator first!");
3208 umfpack_di_report_status(
Control, status);
3209 mfem_error(
"UMFPackSolver::Mult : umfpack_di_solve() failed!");
3214 SuiteSparse_long status =
3221 umfpack_dl_report_status(
Control, status);
3222 mfem_error(
"UMFPackSolver::Mult : umfpack_dl_solve() failed!");
3230 mfem_error(
"UMFPackSolver::MultTranspose : matrix is not set!" 3231 " Call SetOperator first!");
3243 umfpack_di_report_status(
Control, status);
3245 " umfpack_di_solve() failed!");
3250 SuiteSparse_long status =
3257 umfpack_dl_report_status(
Control, status);
3259 " umfpack_dl_solve() failed!");
3272 umfpack_di_free_numeric(&
Numeric);
3276 umfpack_dl_free_numeric(&
Numeric);
3291 "Had Numeric pointer in KLU, but not Symbolic");
3299 MFEM_VERIFY(
mat != NULL,
"not a SparseMatrix");
3307 MFEM_VERIFY(
width ==
height,
"not a square matrix");
3319 MFEM_VERIFY(
mat != NULL,
3320 "KLUSolver::Mult : matrix is not set! Call SetOperator first!");
3333 MFEM_VERIFY(
mat != NULL,
3334 "KLUSolver::Mult : matrix is not set! Call SetOperator first!");
3353 #endif // MFEM_USE_SUITESPARSE 3361 for (
int i = 0; i < block_dof.
NumRows(); ++i)
3366 block_solvers[i].SetOperator(sub_A);
3375 for (
int i = 0; i < block_dof.
NumRows(); ++i)
3380 block_solvers[i].Mult(sub_rhs, sub_sol);
3394 add(-1.0, z, 1.0, x, z);
3411 add(-1.0, z, 1.0, x, z);
3420 :
Solver(0, false), global_size(-1)
3428 :
Solver(0, false), mycomm(mycomm_), global_size(-1), parallel(true) { }
3436 MFEM_VERIFY(
height ==
width,
"Solver must be a square Operator!");
3442 MFEM_VERIFY(solver,
"Solver hasn't been set, call SetSolver() first.");
3446 MFEM_VERIFY(
height ==
width,
"Solver must be a square Operator!");
3452 MFEM_VERIFY(solver,
"Solver hasn't been set, call SetSolver() first.");
3454 "solver was modified externally! call SetSolver() again!");
3455 MFEM_VERIFY(
height ==
b.Size(),
"incompatible input Vector size!");
3456 MFEM_VERIFY(
height == x.
Size(),
"incompatible output Vector size!");
3459 Orthogonalize(
b, b_ortho);
3465 solver->
Mult(b_ortho, x);
3468 Orthogonalize(x, x);
3471 void OrthoSolver::Orthogonalize(
const Vector &v,
Vector &v_ortho)
const 3473 if (global_size == -1)
3479 MPI_Allreduce(MPI_IN_PLACE, &global_size, 1, HYPRE_MPI_BIG_INT,
3487 double global_sum = v.
Sum();
3492 MPI_Allreduce(MPI_IN_PLACE, &global_sum, 1, MPI_DOUBLE, MPI_SUM, mycomm);
3496 double ratio = global_sum /
static_cast<double>(global_size);
3500 for (
int i = 0; i < v_ortho.
Size(); ++i)
3502 v_ortho(i) = v(i) - ratio;
3509 bool op_is_symmetric,
3511 :
Solver(op.NumRows()), aux_map_(aux_map, own_aux_map)
3513 aux_system_.
Reset(
RAP(&op, aux_map));
3516 aux_smoother_.
As<
HypreSmoother>()->SetOperatorSymmetry(op_is_symmetric);
3519 void AuxSpaceSmoother::Mult(
const Vector &x,
Vector &y,
bool transpose)
const 3524 Vector aux_sol(aux_rhs.Size());
3531 aux_smoother_->
Mult(aux_rhs, aux_sol);
3535 aux_map_->
Mult(aux_sol, y);
3537 #endif // MFEM_USE_MPI const T * Read(bool on_dev=true) const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), on_dev).
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 ...
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 ...
const double * HostReadData() const
virtual void Mult(const Vector &x, Vector &y) const
Matrix vector multiplication.
Conjugate gradient method.
double Info[UMFPACK_INFO]
Chebyshev accelerated smoothing with given vector, no matrix necessary.
Array< Vector * > ykArray
virtual Operator & GetGradient(const Vector &x) const
Evaluate the gradient operator at the point x. The default behavior in class Operator is to generate ...
void GetDiag(Vector &d) const
Returns the Diagonal of A.
void SetSize(int s)
Resize the vector to size s.
virtual const double * HostRead() const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), false).
void MinimumDiscardedFillOrdering(SparseMatrix &C, Array< int > &p)
int * GetRowColumns(const int row)
Return a pointer to the column indices in a row.
int RowSize(const int i) const
Returns the number of elements in row i.
virtual void UseDevice(bool use_dev) const
Enable execution of Vector operations using the mfem::Device.
bool summary
A summary of the solver process will be reported after the last iteration to mfem::out.
void Mult(const Vector &x, Vector &y) const
Operator application: y=A(x).
virtual void ProcessNewState(const Vector &x) const
This method can be overloaded in derived classes to perform computations that need knowledge of the n...
virtual void Mult(const Vector &b, Vector &x) const
Solve the nonlinear system with right-hand side b.
bool first_and_last
Information about the first and last iteration will be printed to mfem::out.
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
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.
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
virtual void Solve(int m, int n, double *X) const
int Size() const
Returns the size of the vector.
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
Data type dense matrix using column-major storage.
virtual double * HostWrite()
Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), false).
virtual MemoryClass GetMemoryClass() const
Return the MemoryClass preferred by the Operator.
virtual void Mult(const Vector &b, Vector &x) 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).
int * GetI()
Return the array I.
bool errors
If a fatal problem has been detected the failure will be reported to mfem::err.
int NumRows() const
Get the number of rows (size of output) of the Operator. Synonym with Height().
virtual void Mult(const Vector &x, Vector &y) const =0
Operator application: y=A(x).
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
void SetOperator(const Operator &op)
bool iterative_mode
If true, use the second argument of Mult() as an initial guess.
void GetSubVector(const Array< int > &dofs, Vector &elemvect) const
Extract entries listed in dofs to the output Vector elemvect.
Reordering
The reordering method used by the BlockILU factorization.
void GetSubMatrix(const Array< int > &rows, const Array< int > &cols, DenseMatrix &subm) const
void Mult(const Vector &b, Vector &x) const
Solve the system LUx = b, where L and U are the block ILU factors.
int print_level
(DEPRECATED) Legacy print level definition, which is left for compatibility with custom iterative sol...
void SortColumnIndices()
Sort the column indices corresponding to each row.
void add(const Vector &v1, const Vector &v2, Vector &v)
void Monitor(int it, double norm, const Vector &r, const Vector &x, bool final=false) const
double GetFinalNorm() const
Returns the final residual norm after termination of the solver during the last call to Mult()...
virtual void SetOperator(const Operator &op)
Set the Operator that is the OrthoSolver is to invert (approximately).
double * GetData()
Return the element data, i.e. the array A.
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 SetOperator(const Operator &op) override
Also calls SetOperator for the preconditioner if there is one.
double Norm(const Vector &x) const
const class IterativeSolver * iter_solver
The last IterativeSolver to which this monitor was attached.
void Add(const DenseMatrix &A, const DenseMatrix &B, double alpha, DenseMatrix &C)
C = A + alpha*B.
General product operator: x -> (A*B)(x) = A(B(x)).
virtual void SetPreconditioner(Solver &pr)
This should be called before SetOperator.
virtual void SetPrintLevel(int print_lvl)
Legacy method to set the level of verbosity of the solver output.
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 ...
int GetNumConstraints() const
double solve(double l, const Vector &xt, Vector &x, int &nclip) const
Solve QP at fixed lambda.
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.
int GetNumIterations() const
Returns the number of iterations taken during the last call to Mult()
void Update(Vector &x, int k, DenseMatrix &h, Vector &s, Array< Vector *> &v)
const int * HostReadJ() const
void SetMaxIter(int max_it)
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_)
double Sum() const
Return the sum of the vector entries.
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 print_iteration(int it, double r, double l) const
void AddMult_a(double a, const Vector &x, Vector &y) const
y += a * A.x
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)
PrintLevel & Iterations()
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)
void SetSize(int i, int j, int k, MemoryType mt_=MemoryType::PRESERVE)
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.
void GetDiag(Vector &diag) const
Get the local diagonal of the matrix.
Array< Vector * > skArray
PrintLevel & FirstAndLast()
void RAP(const DenseMatrix &A, const DenseMatrix &P, DenseMatrix &RAP)
const T * HostRead() const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), false).
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...
bool Finalized() const
Returns whether or not CSR format has been finalized.
BlockILU(int block_size_, Reordering reordering_=Reordering::MINIMUM_DISCARDED_FILL, int k_fill_=0)
double * GetData() const
Return a pointer to the beginning of the Vector data.
Stationary linear iteration: x <- x + B (b - A x)
void SetInequalityConstraint(const Vector &dl, const Vector &dh)
void SetEqualityConstraint(const Vector &c)
virtual int GetTrueVSize() const
Return the number of vector true (conforming) dofs.
virtual void MultTranspose(const Vector &x, Vector &y) const
Multiply a vector with the transposed matrix. y = At * x.
virtual void Mult(const Vector &b, Vector &x) const
Solve the nonlinear system with right-hand side b.
void Swap(Array< T > &, Array< T > &)
void SetAbsTol(double atol)
PrintLevel print_options
Output behavior for the iterative solver.
double p(const Vector &x, double t)
void SetRelTol(double rtol)
double Control[UMFPACK_CONTROL]
Abstract base class for iterative solver.
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 ...
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
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.
bool GetConverged() const
Returns true if the last call to Mult() converged successfully.
int max_iter
Limit for the number of iterations the solver is allowed to do.
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
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.
static int GuessLegacyPrintLevel(PrintLevel)
Use some heuristics to guess a legacy print level corresponding to the given PrintLevel.
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
int NumCols() const
Get the number of columns (size of input) of the Operator. Synonym with Width().
void SetDataAndSize(double *d, int s)
Set the Vector data and size.
const int * HostReadI() const
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
double rel_tol
Relative tolerance.
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 Mult(const Vector &xt, Vector &x) const
OpType * As() const
Return the Operator pointer statically cast to a specified OpType. Similar to the method Get()...
AuxSpaceSmoother(const HypreParMatrix &op, HypreParMatrix *aux_map, bool op_is_symmetric=true, bool own_aux_map=false)
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.
virtual void AssembleDiagonal(Vector &diag) const
Computes the diagonal entries into diag. Typically, this operation only makes sense for linear Operat...
PrintLevel FromLegacyPrintLevel(int)
Convert a legacy print level integer to a PrintLevel object.
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
double Norml2() const
Returns the l2 norm of the vector.
double Dot(const Vector &x, const Vector &y) const
virtual void SetOperator(const Operator &op)=0
Set/update the solver for the given operator.
int Size() const
Return the logical size of the array.
MPI_Comm GetComm() const
Return the associated MPI communicator, or MPI_COMM_NULL if no communicator is set.
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 SetSolver(Solver &s)
Set the solver used by the OrthoSolver.
void Mult(const Vector &b, Vector &x) const
Perform the action of the OrthoSolver: P * solver * P where P is the projection to the subspace of ve...
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)
bool warnings
If a non-fatal problem has been detected some context-specific information will be reported to mfem::...
bool iterations
Detailed information about each iteration will be reported to mfem::out.
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
const OptimizationProblem * problem
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
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...
virtual double ComputeScalingFactor(const Vector &x, const Vector &b) const
This method can be overloaded in derived classes to implement line search algorithms.
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.
virtual void Mult(const Vector &x, Vector &y) const
Operator application: y=A(x).
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 ...
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 Mult(const Vector &x, Vector &y) const
Operator application: y=A(x).
IterativeSolverMonitor * monitor
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 SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
Settings for the output behavior of the IterativeSolver.
const Operator * C
Not owned, some can remain unused (NULL).
double abs_tol
Absolute tolerance.
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.